diff options
author | GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> | 2024-08-14 17:31:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-14 17:31:06 +0200 |
commit | fa4e319c0b60cd68a3dccaa4322e3c35cfa1e385 (patch) | |
tree | 4a78391c5008a4aa50d81fbca5d9f26bb475cd96 /Northstar.CustomServers/mod/scripts | |
parent | bcec5a5e9edd2a2af3a017ea4b250a9ba1112e6f (diff) | |
parent | 7aa3958ccd8e32970736654dfae0c7a87f0798bb (diff) | |
download | NorthstarMods-fa4e319c0b60cd68a3dccaa4322e3c35cfa1e385.tar.gz NorthstarMods-fa4e319c0b60cd68a3dccaa4322e3c35cfa1e385.zip |
Merge branch 'main' into permanent-amped-weapons-fix-prpermanent-amped-weapons-fix-pr
Diffstat (limited to 'Northstar.CustomServers/mod/scripts')
126 files changed, 13504 insertions, 644 deletions
diff --git a/Northstar.CustomServers/mod/scripts/datatable/battle_chatter.csv b/Northstar.CustomServers/mod/scripts/datatable/battle_chatter.csv new file mode 100644 index 00000000..74d4c1d9 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/battle_chatter.csv @@ -0,0 +1,24 @@ +conversationname,priority,debounce
+"bc_pReload",500,45.000000
+"bc_pHardcover",500,10.000000
+"bc_pPulse",500,10.000000
+"bc_pGrapple",500,10.000000
+"bc_pHolo",500,10.000000
+"bc_pCloak",500,10.000000
+"bc_pAmp",500,10.000000
+"bc_pStim",500,10.000000
+"bc_pPhase",500,10.000000
+"bc_pFrag",500,10.000000
+"bc_pSmoke",500,10.000000
+"bc_pArc",500,10.000000
+"bc_pGrav",500,10.000000
+"bc_pSatchel",500,10.000000
+"bc_pFirestar",500,10.000000
+"bc_pGravStar",500,10.000000
+"bc_pAmpedWall",500,10.000000
+"bc_fKilledEnemy",500,10.000000
+"bc_pPulseBladeSpotEnemy",500,10.000000
+"bc_fNearEnemyDmg",500,10.000000
+"bc_fCongratsKill",500,10.000000
+"bc_pBatteryOffer",500,5.000000
+"bc_pIntroChat",500,5.000000
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/battle_chatter_voices.csv b/Northstar.CustomServers/mod/scripts/datatable/battle_chatter_voices.csv new file mode 100644 index 00000000..32450513 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/battle_chatter_voices.csv @@ -0,0 +1,19 @@ +isMale,isAndroid,ref
+1,0,"M1"
+1,0,"M2"
+1,0,"M3"
+1,0,"M4"
+1,0,"M5"
+1,0,"M6"
+1,0,"M7"
+1,0,"M8"
+1,0,"M9"
+0,0,"F1"
+0,0,"F2"
+0,0,"F3"
+0,0,"F4"
+0,0,"F5"
+1,1,"MA1"
+1,1,"MA2"
+0,1,"FA1"
+0,1,"FA2"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/burn_meter_rewards.csv b/Northstar.CustomServers/mod/scripts/datatable/burn_meter_rewards.csv new file mode 100644 index 00000000..41e8376d --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/burn_meter_rewards.csv @@ -0,0 +1,21 @@ +itemRef,selectable,name,description,image,model,skinIndex,activationCost,rewardAvailableFor,weaponName,extraWeaponMod,activationText,cost
+"burnmeter_maphack",1,"#BURNMETER_MAP_HACK","#BURNMETER_MAP_HACK_DESC","rui/menu/boosts/boost_map_hack","models/weapons_r2/burn_card/burn_card.mdl",9,0.700000,"PILOT_AND_TITAN","mp_ability_burncardweapon","burnmeter_maphack","#BURNMETER_MAP_HACK_DESC",125
+"burnmeter_amped_weapons",1,"#BURNMETER_AMPED_WEAPONS","#BURNMETER_AMPED_WEAPONS_DESC","rui/menu/boosts/boost_amped_weapons","models/weapons_r2/burn_card/burn_card.mdl",0,0.800000,"PILOT_AND_TITAN","mp_ability_burncardweapon","burnmeter_amped_weapons","#BURNMETER_AMPED_WEAPONS_DESC",125
+"burnmeter_ticks",1,"#BURNMETER_TICKS","#BURNMETER_TICKS_DESC","rui/menu/boosts/boost_ticks","models/weapons_r2/burn_card/burn_card.mdl",5,0.650000,"PILOT_ONLY","mp_weapon_frag_drone","","#WPN_FRAG_DRONE_LONGDESC",125
+"burnmeter_random_foil",1,"#BURNMETER_RANDOM_FOIL","#BURNMETER_RANDOM_FOIL_DESC","rui/menu/boosts/boost_random","models/weapons_r2/burn_card/burn_card.mdl",11,0.500000,"PILOT_AND_TITAN","mp_ability_burncardweapon","burnmeter_random_foil","#BURNMETER_RANDOM_FOIL_DESC",125
+"burnmeter_ap_turret_weapon",1,"#BURNMETER_AP_TURRETWEAPON","#BURNMETER_AP_TURRETWEAPON_DESC","rui/menu/boosts/boost_antipersonnel_sentry","models/weapons_r2/burn_card/burn_card.mdl",6,0.720000,"PILOT_ONLY","mp_ability_turretweapon","burnmeter_ap_turret_weapon","#BURNMETER_AP_TURRETWEAPON_DESC_BOOST_ACTIVATION_TEXT",125
+"burnmeter_phase_rewind",1,"#WPN_REWIND","#WPN_REWIND_LONGDESC","rui/menu/boosts/boost_phase_rewind","models/weapons_r2/burn_card/burn_card.mdl",8,0.250000,"PILOT_ONLY","mp_ability_burncardweapon","burnmeter_phase_rewind","#WPN_REWIND_LONGDESC",125
+"burnmeter_at_turret_weapon",1,"#BURNMETER_AT_TURRETWEAPON","#BURNMETER_AT_TURRETWEAPON_DESC","rui/menu/boosts/boost_antititan_sentry","models/weapons_r2/burn_card/burn_card.mdl",7,0.350000,"PILOT_ONLY","mp_ability_turretweapon","burnmeter_at_turret_weapon","#BURNMETER_AT_TURRETWEAPON_DESC_BOOST_ACTIVATION_TEXT",125
+"burnmeter_holopilot_nova",1,"#WPN_HOLOPILOT_NOVA","#WPN_HOLOPILOT_NOVA_DESC_BOOST_ACTIVATION_TEXT","rui/menu/boosts/boost_holo_pilots","models/weapons_r2/burn_card/burn_card.mdl",10,0.400000,"PILOT_ONLY","mp_ability_holopilot_nova","","#WPN_HOLOPILOT_NOVA_DESC",125
+"burnmeter_emergency_battery",1,"#BURNMETER_EMERGENCY_BATTERY","#BURNMETER_EMERGENCY_BATTERY_DESC","rui/menu/boosts/boost_battery","models/weapons_r2/burn_card/burn_card.mdl",1,0.800000,"PILOT_ONLY","mp_ability_burncardweapon","burnmeter_emergency_battery","#BURNMETER_AT_BATTERY_BOOST_ACTIVATION_TEXT",125
+"burnmeter_smart_pistol",1,"#WPN_SMART_PISTOL","#WPN_SMART_PISTOL_LONGDESC","rui/menu/boosts/boost_smart_pistol","models/weapons_r2/burn_card/burn_card.mdl",2,0.600000,"PILOT_ONLY","mp_ability_burncardweapon","burnmeter_smart_pistol","#WPN_SMART_PISTOL_BOOST_ACTIVATION_TEXT",125
+"burnmeter_radar_jammer",1,"#BURNMETER_RADAR_JAMMER","#BURNMETER_RADAR_JAMMER_DESC","rui/menu/boosts/boost_radar_jammer","models/weapons_r2/burn_card/burn_card.mdl",3,0.400000,"PILOT_ONLY","mp_ability_burncardweapon","burnmeter_radar_jammer","#BURNMETER_RADAR_JAMMER_DESC",125
+"burnmeter_hard_cover",1,"#WPN_HARD_COVER","#WPN_HARD_COVER_DESC","rui/menu/boosts/boost_shield","models/weapons_r2/burn_card/burn_card.mdl",4,0.200000,"PILOT_ONLY","mp_weapon_hard_cover","","#WPN_HARD_COVER_DESC",125
+"burnmeter_nuke_titan",0,"#WPN_NUKE_TITAN","#WPN_NUKE_TITAN_DESC","rui/menu/boosts/boost_nuke","models/weapons_r2/burn_card/burn_card.mdl",9,0.200000,"SPECIAL_PLAYERS_ONLY","mp_ability_burncardweapon","burnmeter_nuke_titan","#WPN_NUKE_TITAN_DESC",125
+"burnmeter_harvester_shield",0,"#BURNMETER_HARVESTER_SHIELD","#BURNMETER_HARVESTER_SHIELD_DESC","rui/menu/boosts/boost_harvester","models/weapons_r2/burn_card/burn_card.mdl",9,0.200000,"SPECIAL_PLAYERS_ONLY","mp_ability_burncardweapon","burnmeter_harvester_shield","#BURNMETER_HARVESTER_SHIELD_DESC",125
+"burnmeter_arc_trap",0,"#WPN_ARC_TRAP","#WPN_ARC_TRAP_DESC","rui/menu/boosts/boost_arc_trap","models/weapons_r2/burn_card/burn_card.mdl",9,0.200000,"PILOT_ONLY","mp_weapon_arc_trap","","#WPN_ARC_TRAP_DESC",125
+"burnmeter_ap_turret_weapon_infinite",0,"#BURNMETER_AP_TURRETWEAPON_INF","#BURNMETER_AP_TURRETWEAPON_INF_DESC","rui/menu/boosts/boost_antipersonnel_sentry","models/weapons_r2/burn_card/burn_card.mdl",6,0.720000,"PILOT_ONLY","mp_ability_turretweapon","burnmeter_ap_turret_weapon_inf","#BURNMETER_AP_TURRETWEAPON_INF_DESC",125
+"burnmeter_at_turret_weapon_infinite",0,"#BURNMETER_AT_TURRETWEAPON_INF","#BURNMETER_AT_TURRETWEAPON_INF_DESC","rui/menu/boosts/boost_antititan_sentry","models/weapons_r2/burn_card/burn_card.mdl",7,0.350000,"PILOT_ONLY","mp_ability_turretweapon","burnmeter_at_turret_weapon_inf","#BURNMETER_AT_TURRETWEAPON_INF_DESC",125
+"burnmeter_rodeo_grenade",0,"#BURNMETER_SUPER_RODEO","#BURNMETER_SUPER_RODEO_DESC","rui/menu/boosts/boost_core_grenade","models/weapons_r2/burn_card/burn_card.mdl",9,0.350000,"PILOT_ONLY","mp_ability_burncardweapon","burnmeter_rodeo_grenade","#BURNMETER_SUPER_RODEO_DESC",125
+"burnmeter_instant_battery",0,"#BURNMETER_INSTANT_BATTERY","#BURNMETER_INSTANT_BATTERY_DESC","rui/menu/boosts/boost_battery","models/weapons_r2/burn_card/burn_card.mdl",1,0.800000,"PILOT_ONLY","mp_ability_burncardweapon","burnmeter_emergency_battery","#BURNMETER_INSTANT_BATTERY_DESC",125
+"burnmeter_amped_weapons_permanent",0,"#BURNMETER_AMPED_WEAPONS_PERMANENT","#BURNMETER_AMPED_WEAPONS_PERMANENT_DESC","rui/menu/boosts/boost_amped_weapons","models/weapons_r2/burn_card/burn_card.mdl",0,0.800000,"PILOT_AND_TITAN","mp_ability_burncardweapon","burnmeter_amped_weapons","#BURNMETER_AMPED_WEAPONS_PERMANENT_DESC",125
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/burn_meter_store.csv b/Northstar.CustomServers/mod/scripts/datatable/burn_meter_store.csv new file mode 100644 index 00000000..2f05bfc8 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/burn_meter_store.csv @@ -0,0 +1,21 @@ +itemRef,modes,cost,extraDesc,autoActivate,storeIcon,lockedStoreIcon,extraDescFail
+"burnmeter_maphack","",0,"",0,"rui/menu/boosts/boost_icon_map_hack","rui/menu/boosts/boost_icon_map_hack",""
+"burnmeter_amped_weapons","",100,"#BOOST_STORE_INSTANT",1,"rui/menu/boosts/boost_icon_amped","rui/menu/boosts/boost_icon_amped","#BOOST_STORE_AMPED_FAIL"
+"burnmeter_ticks","",50,"",0,"rui/menu/boosts/boost_icon_tick","rui/menu/boosts/boost_icon_tick",""
+"burnmeter_random_foil","",0,"",0,"rui/menu/boosts/boost_icon_random","rui/menu/boosts/boost_icon_random",""
+"burnmeter_ap_turret_weapon","",0,"",0,"rui/menu/boosts/boost_icon_personel_sentry","rui/menu/boosts/boost_icon_personel_sentry",""
+"burnmeter_phase_rewind","",0,"",0,"rui/menu/boosts/boost_icon_phase_rewind","rui/menu/boosts/boost_icon_phase_rewind",""
+"burnmeter_at_turret_weapon","",0,"",0,"rui/menu/boosts/boost_icon_titan_sentry","rui/menu/boosts/boost_icon_titan_sentry",""
+"burnmeter_holopilot_nova","",0,"",0,"rui/menu/boosts/boost_icon_holopilot","rui/menu/boosts/boost_icon_holopilot",""
+"burnmeter_emergency_battery","",0,"",0,"rui/menu/boosts/boost_icon_battery","rui/menu/boosts/boost_icon_battery",""
+"burnmeter_smart_pistol","",0,"",1,"rui/menu/boosts/boost_icon_smart_pistol","rui/menu/boosts/boost_icon_smart_pistol",""
+"burnmeter_radar_jammer","",0,"",0,"rui/menu/boosts/boost_icon_radar_jam","rui/menu/boosts/boost_icon_radar_jam",""
+"burnmeter_hard_cover","",0,"",0,"rui/menu/boosts/boost_icon_shield","rui/menu/boosts/boost_icon_shield",""
+"burnmeter_nuke_titan","",0,"",0,"rui/menu/boosts/boost_icon_nuke","rui/menu/boosts/boost_icon_nuke",""
+"burnmeter_harvester_shield","fd",1200,"",1,"rui/menu/boosts/boost_icon_harvester_shield","rui/menu/boosts/locked/boost_icon_harvester_shield","#BOOST_STORE_HARVESTER_SHIELD_FAIL"
+"burnmeter_arc_trap","fd",650,"",0,"rui/menu/boosts/boost_icon_arc_trap","rui/menu/boosts/locked/boost_icon_arc_trap","#BOOST_STORE_ARC_TRAP_FAIL"
+"burnmeter_at_turret_weapon_infinite","",1200,"#BOOST_STORE_TURRET_LIMIT",0,"rui/menu/boosts/boost_icon_titan_sentry","rui/menu/boosts/boost_icon_titan_sentry",""
+"burnmeter_ap_turret_weapon_infinite","fd",1200,"#BOOST_STORE_TURRET_LIMIT",0,"rui/menu/boosts/boost_icon_personel_sentry","rui/menu/boosts/locked/boost_icon_personel_sentry","#BOOST_STORE_TURRET_FAIL"
+"burnmeter_rodeo_grenade","fd",500,"",1,"rui/menu/boosts/boost_icon_core_overload","rui/menu/boosts/locked/boost_icon_core_overload","#BOOST_STORE_RODEO_GRENADE_FAIL"
+"burnmeter_instant_battery","fd",400,"#BOOST_STORE_INSTANT",1,"rui/menu/boosts/boost_icon_battery_amped","rui/menu/boosts/locked/boost_icon_battery_amped","#BOOST_STORE_BATTERY_FAIL"
+"burnmeter_amped_weapons_permanent","fd",100,"#BOOST_STORE_INSTANT",1,"rui/menu/boosts/boost_icon_amped","rui/menu/boosts/locked/boost_icon_amped","#BOOST_STORE_AMPED_FAIL"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/caller_ids_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/caller_ids_mp.csv new file mode 100644 index 00000000..dcb3f5ab --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/caller_ids_mp.csv @@ -0,0 +1,2 @@ +title,image
+"#FACTION_LEADER_NAME_MARVIN","rui/hud/caller_ids/caller_id_36"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/calling_cards.csv b/Northstar.CustomServers/mod/scripts/datatable/calling_cards.csv new file mode 100644 index 00000000..998e644e --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/calling_cards.csv @@ -0,0 +1,491 @@ +itemRef,name,layoutType,image,cost
+"callsign_01_col","#BANNER_CALLSIGN1",0,"rui/callsigns/callsign_01_col",0
+"callsign_02_col","#BANNER_CALLSIGN2",0,"rui/callsigns/callsign_02_col",100
+"callsign_03_col","#BANNER_CALLSIGN3",0,"rui/callsigns/callsign_03_col",0
+"callsign_04_col","#BANNER_CALLSIGN4",0,"rui/callsigns/callsign_04_col",0
+"callsign_05_col","#BANNER_CALLSIGN5",0,"rui/callsigns/callsign_05_col",0
+"callsign_06_col","#BANNER_CALLSIGN6",0,"rui/callsigns/callsign_06_col",0
+"callsign_07_col","#BANNER_CALLSIGN7",0,"rui/callsigns/callsign_07_col",0
+"callsign_08_col","#BANNER_CALLSIGN8",0,"rui/callsigns/callsign_08_col",100
+"callsign_09_col","#BANNER_CALLSIGN9",0,"rui/callsigns/callsign_09_col",0
+"callsign_10_col","#BANNER_CALLSIGN10",0,"rui/callsigns/callsign_10_col",100
+"callsign_11_col","#BANNER_CALLSIGN11",0,"rui/callsigns/callsign_11_col",0
+"callsign_12_col","#BANNER_CALLSIGN12",0,"rui/callsigns/callsign_12_col",100
+"callsign_13_col","#BANNER_CALLSIGN13",0,"rui/callsigns/callsign_13_col",0
+"callsign_14_col","#BANNER_CALLSIGN14",0,"rui/callsigns/callsign_14_col",0
+"callsign_15_col","#BANNER_CALLSIGN15",0,"rui/callsigns/callsign_15_col",0
+"callsign_16_col","#BANNER_CALLSIGN16",0,"rui/callsigns/callsign_16_col",0
+"callsign_17_col","#BANNER_CALLSIGN17",0,"rui/callsigns/callsign_17_col",100
+"callsign_18_col","#BANNER_CALLSIGN18",0,"rui/callsigns/callsign_18_col",0
+"callsign_19_col","#BANNER_CALLSIGN19",0,"rui/callsigns/callsign_19_col",0
+"callsign_20_col","#BANNER_CALLSIGN20",0,"rui/callsigns/callsign_20_col",100
+"callsign_21_col","#BANNER_CALLSIGN21",0,"rui/callsigns/callsign_21_col",0
+"callsign_22_col","#BANNER_CALLSIGN22",0,"rui/callsigns/callsign_22_col",0
+"callsign_23_col","#BANNER_CALLSIGN23",0,"rui/callsigns/callsign_23_col",0
+"callsign_24_col","#BANNER_CALLSIGN24",0,"rui/callsigns/callsign_24_col",0
+"callsign_25_col","#BANNER_CALLSIGN25",0,"rui/callsigns/callsign_25_col",100
+"callsign_26_col","#BANNER_CALLSIGN26",0,"rui/callsigns/callsign_26_col",0
+"callsign_27_col","#BANNER_CALLSIGN27",0,"rui/callsigns/callsign_27_col",0
+"callsign_28_col","#BANNER_CALLSIGN28",0,"rui/callsigns/callsign_28_col",100
+"callsign_29_col","#BANNER_CALLSIGN29",0,"rui/callsigns/callsign_29_col",0
+"callsign_30_col","#BANNER_CALLSIGN30",0,"rui/callsigns/callsign_30_col",0
+"callsign_31_col","#BANNER_CALLSIGN31",0,"rui/callsigns/callsign_31_col",0
+"callsign_32_col","#BANNER_CALLSIGN32",0,"rui/callsigns/callsign_32_col",100
+"callsign_34_col","#BANNER_CALLSIGN34",0,"rui/callsigns/callsign_34_col",0
+"callsign_35_col","#BANNER_CALLSIGN35",0,"rui/callsigns/callsign_35_col",0
+"callsign_36_col","#BANNER_CALLSIGN36",0,"rui/callsigns/callsign_36_col",0
+"callsign_37_col","#BANNER_CALLSIGN37",0,"rui/callsigns/callsign_37_col",0
+"callsign_39_col","#BANNER_CALLSIGN39",0,"rui/callsigns/callsign_39_col",0
+"callsign_40_col","#BANNER_CALLSIGN40",0,"rui/callsigns/callsign_40_col",0
+"callsign_41_col","#BANNER_CALLSIGN41",0,"rui/callsigns/callsign_41_col",0
+"callsign_42_col","#BANNER_CALLSIGN42",0,"rui/callsigns/callsign_42_col",0
+"callsign_43_col","#BANNER_CALLSIGN43",0,"rui/callsigns/callsign_43_col",100
+"callsign_44_col","#BANNER_CALLSIGN44",0,"rui/callsigns/callsign_44_col",100
+"callsign_45_col","#BANNER_CALLSIGN45",0,"rui/callsigns/callsign_45_col",0
+"callsign_46_col","#BANNER_CALLSIGN46",0,"rui/callsigns/callsign_46_col",0
+"callsign_47_col","#BANNER_CALLSIGN47",0,"rui/callsigns/callsign_47_col",0
+"callsign_48_col","#BANNER_CALLSIGN48",0,"rui/callsigns/callsign_48_col",0
+"callsign_49_col","#BANNER_CALLSIGN49",0,"rui/callsigns/callsign_49_col",100
+"callsign_50_col","#BANNER_CALLSIGN50",0,"rui/callsigns/callsign_50_col",100
+"callsign_51_col","#BANNER_CALLSIGN51",0,"rui/callsigns/callsign_51_col",0
+"callsign_52_col","#BANNER_CALLSIGN52",0,"rui/callsigns/callsign_52_col",100
+"callsign_53_col","#BANNER_CALLSIGN53",0,"rui/callsigns/callsign_53_col",0
+"callsign_54_col","#BANNER_CALLSIGN54",0,"rui/callsigns/callsign_54_col",100
+"callsign_55_col","#BANNER_CALLSIGN55",0,"rui/callsigns/callsign_55_col",0
+"callsign_56_col","#BANNER_CALLSIGN56",0,"rui/callsigns/callsign_56_col",100
+"callsign_57_col","#BANNER_CALLSIGN57",0,"rui/callsigns/callsign_57_col",0
+"callsign_58_col","#BANNER_CALLSIGN58",0,"rui/callsigns/callsign_58_col",100
+"callsign_59_col","#BANNER_CALLSIGN59",0,"rui/callsigns/callsign_59_col",0
+"callsign_60_col","#BANNER_CALLSIGN60",0,"rui/callsigns/callsign_60_col",100
+"callsign_61_col","#BANNER_CALLSIGN61",0,"rui/callsigns/callsign_61_col",100
+"callsign_62_col","#BANNER_CALLSIGN62",0,"rui/callsigns/callsign_62_col",100
+"callsign_63_col","#BANNER_CALLSIGN63",0,"rui/callsigns/callsign_63_col",100
+"callsign_64_col","#BANNER_CALLSIGN64",0,"rui/callsigns/callsign_64_col",100
+"callsign_66_col","#BANNER_CALLSIGN66",0,"rui/callsigns/callsign_66_col",0
+"callsign_67_col","#BANNER_CALLSIGN67",0,"rui/callsigns/callsign_67_col",0
+"callsign_68_col","#BANNER_CALLSIGN68",0,"rui/callsigns/callsign_68_col",0
+"callsign_69_col","#BANNER_CALLSIGN69",0,"rui/callsigns/callsign_69_col",0
+"callsign_70_col","#BANNER_CALLSIGN70",0,"rui/callsigns/callsign_70_col",0
+"callsign_71_col","#BANNER_CALLSIGN71",0,"rui/callsigns/callsign_71_col",100
+"callsign_72_col","#BANNER_CALLSIGN72",0,"rui/callsigns/callsign_72_col",100
+"callsign_73_col","#BANNER_CALLSIGN73",0,"rui/callsigns/callsign_73_col",100
+"callsign_74_col","#BANNER_CALLSIGN74",0,"rui/callsigns/callsign_74_col",100
+"callsign_75_col","#BANNER_CALLSIGN75",0,"rui/callsigns/callsign_75_col",0
+"callsign_76_col","#BANNER_CALLSIGN76",0,"rui/callsigns/callsign_76_col",0
+"callsign_77_col","#BANNER_CALLSIGN77",0,"rui/callsigns/callsign_77_col",100
+"callsign_78_col","#BANNER_CALLSIGN78",0,"rui/callsigns/callsign_78_col",0
+"callsign_79_col","#BANNER_CALLSIGN79",0,"rui/callsigns/callsign_79_col",0
+"callsign_80_col","#BANNER_CALLSIGN80",0,"rui/callsigns/callsign_80_col",100
+"callsign_81_col","#BANNER_CALLSIGN81",0,"rui/callsigns/callsign_81_col",100
+"callsign_82_col","#BANNER_CALLSIGN82",0,"rui/callsigns/callsign_82_col",100
+"callsign_83_col","#BANNER_CALLSIGN83",0,"rui/callsigns/callsign_83_col",100
+"callsign_84_col","#BANNER_CALLSIGN84",0,"rui/callsigns/callsign_84_col",100
+"callsign_85_col","#BANNER_CALLSIGN85",0,"rui/callsigns/callsign_85_col",100
+"callsign_86_col","#BANNER_CALLSIGN86",0,"rui/callsigns/callsign_86_col",100
+"callsign_87_col","#BANNER_CALLSIGN87",0,"rui/callsigns/callsign_87_col",100
+"callsign_88_col","#BANNER_CALLSIGN88",0,"rui/callsigns/callsign_88_col",100
+"callsign_89_col","#BANNER_CALLSIGN89",0,"rui/callsigns/callsign_89_col",100
+"callsign_90_col","#BANNER_CALLSIGN90",0,"rui/callsigns/callsign_90_col",100
+"callsign_91_col","#BANNER_CALLSIGN91",0,"rui/callsigns/callsign_91_col",100
+"callsign_92_col","#BANNER_CALLSIGN92",0,"rui/callsigns/callsign_92_col",0
+"callsign_93_col","#BANNER_CALLSIGN93",0,"rui/callsigns/callsign_93_col",100
+"callsign_94_col","#BANNER_CALLSIGN94",0,"rui/callsigns/callsign_94_col",0
+"callsign_95_col","#BANNER_CALLSIGN95",0,"rui/callsigns/callsign_95_col",100
+"callsign_96_col","#BANNER_CALLSIGN96",0,"rui/callsigns/callsign_96_col",0
+"callsign_97_col","#BANNER_CALLSIGN97",0,"rui/callsigns/callsign_97_col",0
+"callsign_98_col","#BANNER_CALLSIGN98",0,"rui/callsigns/callsign_98_col",100
+"callsign_99_col","#BANNER_CALLSIGN99",0,"rui/callsigns/callsign_99_col",0
+"callsign_100_col","#BANNER_CALLSIGN100",0,"rui/callsigns/callsign_100_col",0
+"callsign_101_col","#BANNER_CALLSIGN101",0,"rui/callsigns/callsign_101_col",100
+"callsign_102_col","#BANNER_CALLSIGN102",0,"rui/callsigns/callsign_102_col",100
+"callsign_103_col","#BANNER_CALLSIGN103",0,"rui/callsigns/callsign_103_col",0
+"callsign_104_col","#BANNER_CALLSIGN104",0,"rui/callsigns/callsign_104_col",0
+"callsign_02_col_prism","#BANNER_PRISM_CALLSIGN2",1,"rui/callsigns/callsign_02_col",250
+"callsign_08_col_prism","#BANNER_PRISM_CALLSIGN8",1,"rui/callsigns/callsign_08_col",250
+"callsign_10_col_prism","#BANNER_PRISM_CALLSIGN10",1,"rui/callsigns/callsign_10_col",250
+"callsign_12_col_prism","#BANNER_PRISM_CALLSIGN12",1,"rui/callsigns/callsign_12_col",250
+"callsign_17_col_prism","#BANNER_PRISM_CALLSIGN17",1,"rui/callsigns/callsign_17_col",250
+"callsign_20_col_prism","#BANNER_PRISM_CALLSIGN20",1,"rui/callsigns/callsign_20_col",250
+"callsign_25_col_prism","#BANNER_PRISM_CALLSIGN25",1,"rui/callsigns/callsign_25_col",250
+"callsign_28_col_prism","#BANNER_PRISM_CALLSIGN28",1,"rui/callsigns/callsign_28_col",250
+"callsign_32_col_prism","#BANNER_PRISM_CALLSIGN32",1,"rui/callsigns/callsign_32_col",250
+"callsign_43_col_prism","#BANNER_PRISM_CALLSIGN43",1,"rui/callsigns/callsign_43_col",250
+"callsign_44_col_prism","#BANNER_PRISM_CALLSIGN44",1,"rui/callsigns/callsign_44_col",250
+"callsign_49_col_prism","#BANNER_PRISM_CALLSIGN49",1,"rui/callsigns/callsign_49_col",250
+"callsign_50_col_prism","#BANNER_PRISM_CALLSIGN50",1,"rui/callsigns/callsign_50_col",250
+"callsign_52_col_prism","#BANNER_PRISM_CALLSIGN52",1,"rui/callsigns/callsign_52_col",250
+"callsign_54_col_prism","#BANNER_PRISM_CALLSIGN54",1,"rui/callsigns/callsign_54_col",250
+"callsign_56_col_prism","#BANNER_PRISM_CALLSIGN56",1,"rui/callsigns/callsign_56_col",250
+"callsign_58_col_prism","#BANNER_PRISM_CALLSIGN58",1,"rui/callsigns/callsign_58_col",250
+"callsign_60_col_prism","#BANNER_PRISM_CALLSIGN60",1,"rui/callsigns/callsign_60_col",250
+"callsign_61_col_prism","#BANNER_PRISM_CALLSIGN61",1,"rui/callsigns/callsign_61_col",250
+"callsign_62_col_prism","#BANNER_PRISM_CALLSIGN62",1,"rui/callsigns/callsign_62_col",250
+"callsign_63_col_prism","#BANNER_PRISM_CALLSIGN63",1,"rui/callsigns/callsign_63_col",250
+"callsign_64_col_prism","#BANNER_PRISM_CALLSIGN64",1,"rui/callsigns/callsign_64_col",250
+"callsign_71_col_prism","#BANNER_PRISM_CALLSIGN71",1,"rui/callsigns/callsign_71_col",250
+"callsign_72_col_prism","#BANNER_PRISM_CALLSIGN72",1,"rui/callsigns/callsign_72_col",250
+"callsign_73_col_prism","#BANNER_PRISM_CALLSIGN73",1,"rui/callsigns/callsign_73_col",250
+"callsign_74_col_prism","#BANNER_PRISM_CALLSIGN74",1,"rui/callsigns/callsign_74_col",250
+"callsign_77_col_prism","#BANNER_PRISM_CALLSIGN77",1,"rui/callsigns/callsign_77_col",250
+"callsign_80_col_prism","#BANNER_PRISM_CALLSIGN80",1,"rui/callsigns/callsign_80_col",250
+"callsign_81_col_prism","#BANNER_PRISM_CALLSIGN81",1,"rui/callsigns/callsign_81_col",250
+"callsign_82_col_prism","#BANNER_PRISM_CALLSIGN82",1,"rui/callsigns/callsign_82_col",250
+"callsign_83_col_prism","#BANNER_PRISM_CALLSIGN83",1,"rui/callsigns/callsign_83_col",250
+"callsign_84_col_prism","#BANNER_PRISM_CALLSIGN84",1,"rui/callsigns/callsign_84_col",250
+"callsign_85_col_prism","#BANNER_PRISM_CALLSIGN85",1,"rui/callsigns/callsign_85_col",250
+"callsign_86_col_prism","#BANNER_PRISM_CALLSIGN86",1,"rui/callsigns/callsign_86_col",250
+"callsign_87_col_prism","#BANNER_PRISM_CALLSIGN87",1,"rui/callsigns/callsign_87_col",250
+"callsign_88_col_prism","#BANNER_PRISM_CALLSIGN88",1,"rui/callsigns/callsign_88_col",250
+"callsign_89_col_prism","#BANNER_PRISM_CALLSIGN89",1,"rui/callsigns/callsign_89_col",250
+"callsign_90_col_prism","#BANNER_PRISM_CALLSIGN90",1,"rui/callsigns/callsign_90_col",250
+"callsign_91_col_prism","#BANNER_PRISM_CALLSIGN91",1,"rui/callsigns/callsign_91_col",250
+"callsign_93_col_prism","#BANNER_PRISM_CALLSIGN93",1,"rui/callsigns/callsign_93_col",250
+"callsign_95_col_prism","#BANNER_PRISM_CALLSIGN95",1,"rui/callsigns/callsign_95_col",250
+"callsign_98_col_prism","#BANNER_PRISM_CALLSIGN98",1,"rui/callsigns/callsign_98_col",250
+"callsign_101_col_prism","#BANNER_PRISM_CALLSIGN101",1,"rui/callsigns/callsign_101_col",250
+"callsign_102_col_prism","#BANNER_PRISM_CALLSIGN102",1,"rui/callsigns/callsign_102_col",250
+"callsign_16_col_gold","#BANNER_GOLD_CALLSIGN16",2,"rui/callsigns/callsign_16_col",0
+"callsign_01_col_gold","#BANNER_GOLD_CALLSIGN1",2,"rui/callsigns/callsign_01_col",0
+"callsign_03_col_gold","#BANNER_GOLD_CALLSIGN3",2,"rui/callsigns/callsign_03_col",0
+"callsign_04_col_gold","#BANNER_GOLD_CALLSIGN4",2,"rui/callsigns/callsign_04_col",0
+"callsign_05_col_gold","#BANNER_GOLD_CALLSIGN5",2,"rui/callsigns/callsign_05_col",0
+"callsign_06_col_gold","#BANNER_GOLD_CALLSIGN6",2,"rui/callsigns/callsign_06_col",0
+"callsign_07_col_gold","#BANNER_GOLD_CALLSIGN7",2,"rui/callsigns/callsign_07_col",0
+"callsign_09_col_gold","#BANNER_GOLD_CALLSIGN9",2,"rui/callsigns/callsign_09_col",0
+"callsign_11_col_gold","#BANNER_GOLD_CALLSIGN11",2,"rui/callsigns/callsign_11_col",0
+"callsign_13_col_gold","#BANNER_GOLD_CALLSIGN13",2,"rui/callsigns/callsign_13_col",0
+"callsign_14_col_gold","#BANNER_GOLD_CALLSIGN14",2,"rui/callsigns/callsign_14_col",0
+"callsign_15_col_gold","#BANNER_GOLD_CALLSIGN15",2,"rui/callsigns/callsign_15_col",0
+"callsign_18_col_gold","#BANNER_GOLD_CALLSIGN18",2,"rui/callsigns/callsign_18_col",0
+"callsign_19_col_gold","#BANNER_GOLD_CALLSIGN19",2,"rui/callsigns/callsign_19_col",0
+"callsign_21_col_gold","#BANNER_GOLD_CALLSIGN21",2,"rui/callsigns/callsign_21_col",0
+"callsign_22_col_gold","#BANNER_GOLD_CALLSIGN22",2,"rui/callsigns/callsign_22_col",0
+"callsign_23_col_gold","#BANNER_GOLD_CALLSIGN23",2,"rui/callsigns/callsign_23_col",0
+"callsign_24_col_gold","#BANNER_GOLD_CALLSIGN24",2,"rui/callsigns/callsign_24_col",0
+"callsign_26_col_gold","#BANNER_GOLD_CALLSIGN26",2,"rui/callsigns/callsign_26_col",0
+"callsign_27_col_gold","#BANNER_GOLD_CALLSIGN27",2,"rui/callsigns/callsign_27_col",0
+"callsign_29_col_gold","#BANNER_GOLD_CALLSIGN29",2,"rui/callsigns/callsign_29_col",0
+"callsign_30_col_gold","#BANNER_GOLD_CALLSIGN30",2,"rui/callsigns/callsign_30_col",0
+"callsign_31_col_gold","#BANNER_GOLD_CALLSIGN31",2,"rui/callsigns/callsign_31_col",0
+"callsign_33_col_gold","#BANNER_GOLD_CALLSIGN33",2,"rui/callsigns/callsign_33_col",0
+"callsign_34_col_gold","#BANNER_GOLD_CALLSIGN34",2,"rui/callsigns/callsign_34_col",0
+"callsign_35_col_gold","#BANNER_GOLD_CALLSIGN35",2,"rui/callsigns/callsign_35_col",0
+"callsign_36_col_gold","#BANNER_GOLD_CALLSIGN36",2,"rui/callsigns/callsign_36_col",0
+"callsign_37_col_gold","#BANNER_GOLD_CALLSIGN37",2,"rui/callsigns/callsign_37_col",0
+"callsign_38_col_gold","#BANNER_GOLD_CALLSIGN38",2,"rui/callsigns/callsign_38_col",0
+"callsign_39_col_gold","#BANNER_GOLD_CALLSIGN39",2,"rui/callsigns/callsign_39_col",0
+"callsign_40_col_gold","#BANNER_GOLD_CALLSIGN40",2,"rui/callsigns/callsign_40_col",0
+"callsign_41_col_gold","#BANNER_GOLD_CALLSIGN41",2,"rui/callsigns/callsign_41_col",0
+"callsign_42_col_gold","#BANNER_GOLD_CALLSIGN42",2,"rui/callsigns/callsign_42_col",0
+"callsign_45_col_gold","#BANNER_GOLD_CALLSIGN45",2,"rui/callsigns/callsign_45_col",0
+"callsign_46_col_gold","#BANNER_GOLD_CALLSIGN46",2,"rui/callsigns/callsign_46_col",0
+"callsign_47_col_gold","#BANNER_GOLD_CALLSIGN47",2,"rui/callsigns/callsign_47_col",0
+"callsign_48_col_gold","#BANNER_GOLD_CALLSIGN48",2,"rui/callsigns/callsign_48_col",0
+"callsign_51_col_gold","#BANNER_GOLD_CALLSIGN51",2,"rui/callsigns/callsign_51_col",0
+"callsign_53_col_gold","#BANNER_GOLD_CALLSIGN53",2,"rui/callsigns/callsign_53_col",0
+"callsign_55_col_gold","#BANNER_GOLD_CALLSIGN55",2,"rui/callsigns/callsign_55_col",0
+"callsign_57_col_gold","#BANNER_GOLD_CALLSIGN57",2,"rui/callsigns/callsign_57_col",0
+"callsign_59_col_gold","#BANNER_GOLD_CALLSIGN59",2,"rui/callsigns/callsign_59_col",0
+"callsign_65_col_gold","#BANNER_GOLD_CALLSIGN65",2,"rui/callsigns/callsign_65_col",0
+"callsign_66_col_gold","#BANNER_GOLD_CALLSIGN66",2,"rui/callsigns/callsign_66_col",0
+"callsign_67_col_gold","#BANNER_GOLD_CALLSIGN67",2,"rui/callsigns/callsign_67_col",0
+"callsign_68_col_gold","#BANNER_GOLD_CALLSIGN68",2,"rui/callsigns/callsign_68_col",0
+"callsign_69_col_gold","#BANNER_GOLD_CALLSIGN69",2,"rui/callsigns/callsign_69_col",0
+"callsign_70_col_gold","#BANNER_GOLD_CALLSIGN70",2,"rui/callsigns/callsign_70_col",0
+"callsign_71_col_gold","#BANNER_GOLD_CALLSIGN71",2,"rui/callsigns/callsign_71_col",0
+"callsign_75_col_gold","#BANNER_GOLD_CALLSIGN75",2,"rui/callsigns/callsign_75_col",0
+"callsign_76_col_gold","#BANNER_GOLD_CALLSIGN76",2,"rui/callsigns/callsign_76_col",0
+"callsign_78_col_gold","#BANNER_GOLD_CALLSIGN78",2,"rui/callsigns/callsign_78_col",0
+"callsign_79_col_gold","#BANNER_GOLD_CALLSIGN79",2,"rui/callsigns/callsign_79_col",0
+"callsign_92_col_gold","#BANNER_GOLD_CALLSIGN92",2,"rui/callsigns/callsign_92_col",0
+"callsign_94_col_gold","#BANNER_GOLD_CALLSIGN94",2,"rui/callsigns/callsign_94_col",0
+"callsign_96_col_gold","#BANNER_GOLD_CALLSIGN96",2,"rui/callsigns/callsign_96_col",0
+"callsign_97_col_gold","#BANNER_GOLD_CALLSIGN97",2,"rui/callsigns/callsign_97_col",0
+"callsign_99_col_gold","#BANNER_GOLD_CALLSIGN99",2,"rui/callsigns/callsign_99_col",0
+"callsign_100_col_gold","#BANNER_GOLD_CALLSIGN100",2,"rui/callsigns/callsign_100_col",0
+"callsign_103_col_gold","#BANNER_GOLD_CALLSIGN103",2,"rui/callsigns/callsign_103_col",0
+"callsign_104_col_gold","#BANNER_GOLD_CALLSIGN104",2,"rui/callsigns/callsign_104_col",0
+"callsign_105_col_gold","#BANNER_GOLD_CALLSIGN105",2,"rui/callsigns/callsign_105_col",0
+"callsign_16_col_fire","#BANNER_FIRE_CALLSIGN16",3,"rui/callsigns/callsign_16_col",0
+"callsign_01_col_fire","#BANNER_FIRE_CALLSIGN1",3,"rui/callsigns/callsign_01_col",0
+"callsign_03_col_fire","#BANNER_FIRE_CALLSIGN3",3,"rui/callsigns/callsign_03_col",0
+"callsign_04_col_fire","#BANNER_FIRE_CALLSIGN4",3,"rui/callsigns/callsign_04_col",0
+"callsign_05_col_fire","#BANNER_FIRE_CALLSIGN5",3,"rui/callsigns/callsign_05_col",0
+"callsign_06_col_fire","#BANNER_FIRE_CALLSIGN6",3,"rui/callsigns/callsign_06_col",0
+"callsign_07_col_fire","#BANNER_FIRE_CALLSIGN7",3,"rui/callsigns/callsign_07_col",0
+"callsign_09_col_fire","#BANNER_FIRE_CALLSIGN9",3,"rui/callsigns/callsign_09_col",0
+"callsign_11_col_fire","#BANNER_FIRE_CALLSIGN11",3,"rui/callsigns/callsign_11_col",0
+"callsign_13_col_fire","#BANNER_FIRE_CALLSIGN13",3,"rui/callsigns/callsign_13_col",0
+"callsign_14_col_fire","#BANNER_FIRE_CALLSIGN14",3,"rui/callsigns/callsign_14_col",0
+"callsign_15_col_fire","#BANNER_FIRE_CALLSIGN15",3,"rui/callsigns/callsign_15_col",0
+"callsign_18_col_fire","#BANNER_FIRE_CALLSIGN18",3,"rui/callsigns/callsign_18_col",0
+"callsign_19_col_fire","#BANNER_FIRE_CALLSIGN19",3,"rui/callsigns/callsign_19_col",0
+"callsign_21_col_fire","#BANNER_FIRE_CALLSIGN21",3,"rui/callsigns/callsign_21_col",0
+"callsign_22_col_fire","#BANNER_FIRE_CALLSIGN22",3,"rui/callsigns/callsign_22_col",0
+"callsign_23_col_fire","#BANNER_FIRE_CALLSIGN23",3,"rui/callsigns/callsign_23_col",0
+"callsign_24_col_fire","#BANNER_FIRE_CALLSIGN24",3,"rui/callsigns/callsign_24_col",0
+"callsign_26_col_fire","#BANNER_FIRE_CALLSIGN26",3,"rui/callsigns/callsign_26_col",0
+"callsign_27_col_fire","#BANNER_FIRE_CALLSIGN27",3,"rui/callsigns/callsign_27_col",0
+"callsign_29_col_fire","#BANNER_FIRE_CALLSIGN29",3,"rui/callsigns/callsign_29_col",0
+"callsign_30_col_fire","#BANNER_FIRE_CALLSIGN30",3,"rui/callsigns/callsign_30_col",0
+"callsign_31_col_fire","#BANNER_FIRE_CALLSIGN31",3,"rui/callsigns/callsign_31_col",0
+"callsign_34_col_fire","#BANNER_FIRE_CALLSIGN34",3,"rui/callsigns/callsign_34_col",0
+"callsign_35_col_fire","#BANNER_FIRE_CALLSIGN35",3,"rui/callsigns/callsign_35_col",0
+"callsign_36_col_fire","#BANNER_FIRE_CALLSIGN36",3,"rui/callsigns/callsign_36_col",0
+"callsign_37_col_fire","#BANNER_FIRE_CALLSIGN37",3,"rui/callsigns/callsign_37_col",0
+"callsign_39_col_fire","#BANNER_FIRE_CALLSIGN39",3,"rui/callsigns/callsign_39_col",0
+"callsign_40_col_fire","#BANNER_FIRE_CALLSIGN40",3,"rui/callsigns/callsign_40_col",0
+"callsign_41_col_fire","#BANNER_FIRE_CALLSIGN41",3,"rui/callsigns/callsign_41_col",0
+"callsign_42_col_fire","#BANNER_FIRE_CALLSIGN42",3,"rui/callsigns/callsign_42_col",0
+"callsign_45_col_fire","#BANNER_FIRE_CALLSIGN45",3,"rui/callsigns/callsign_45_col",0
+"callsign_46_col_fire","#BANNER_FIRE_CALLSIGN46",3,"rui/callsigns/callsign_46_col",0
+"callsign_47_col_fire","#BANNER_FIRE_CALLSIGN47",3,"rui/callsigns/callsign_47_col",0
+"callsign_48_col_fire","#BANNER_FIRE_CALLSIGN48",3,"rui/callsigns/callsign_48_col",0
+"callsign_51_col_fire","#BANNER_FIRE_CALLSIGN51",3,"rui/callsigns/callsign_51_col",0
+"callsign_53_col_fire","#BANNER_FIRE_CALLSIGN53",3,"rui/callsigns/callsign_53_col",0
+"callsign_55_col_fire","#BANNER_FIRE_CALLSIGN55",3,"rui/callsigns/callsign_55_col",0
+"callsign_57_col_fire","#BANNER_FIRE_CALLSIGN57",3,"rui/callsigns/callsign_57_col",0
+"callsign_59_col_fire","#BANNER_FIRE_CALLSIGN59",3,"rui/callsigns/callsign_59_col",0
+"callsign_66_col_fire","#BANNER_FIRE_CALLSIGN66",3,"rui/callsigns/callsign_66_col",0
+"callsign_67_col_fire","#BANNER_FIRE_CALLSIGN67",3,"rui/callsigns/callsign_67_col",0
+"callsign_68_col_fire","#BANNER_FIRE_CALLSIGN68",3,"rui/callsigns/callsign_68_col",0
+"callsign_69_col_fire","#BANNER_FIRE_CALLSIGN69",3,"rui/callsigns/callsign_69_col",0
+"callsign_70_col_fire","#BANNER_FIRE_CALLSIGN70",3,"rui/callsigns/callsign_70_col",0
+"callsign_75_col_fire","#BANNER_FIRE_CALLSIGN75",3,"rui/callsigns/callsign_75_col",0
+"callsign_76_col_fire","#BANNER_FIRE_CALLSIGN76",3,"rui/callsigns/callsign_76_col",0
+"callsign_78_col_fire","#BANNER_FIRE_CALLSIGN78",3,"rui/callsigns/callsign_78_col",0
+"callsign_79_col_fire","#BANNER_FIRE_CALLSIGN79",3,"rui/callsigns/callsign_79_col",0
+"callsign_92_col_fire","#BANNER_FIRE_CALLSIGN92",3,"rui/callsigns/callsign_92_col",0
+"callsign_94_col_fire","#BANNER_FIRE_CALLSIGN94",3,"rui/callsigns/callsign_94_col",0
+"callsign_96_col_fire","#BANNER_FIRE_CALLSIGN96",3,"rui/callsigns/callsign_96_col",0
+"callsign_97_col_fire","#BANNER_FIRE_CALLSIGN97",3,"rui/callsigns/callsign_97_col",0
+"callsign_99_col_fire","#BANNER_FIRE_CALLSIGN99",3,"rui/callsigns/callsign_99_col",0
+"callsign_100_col_fire","#BANNER_FIRE_CALLSIGN100",3,"rui/callsigns/callsign_100_col",0
+"callsign_103_col_fire","#BANNER_FIRE_CALLSIGN103",3,"rui/callsigns/callsign_103_col",0
+"callsign_104_col_fire","#BANNER_FIRE_CALLSIGN104",3,"rui/callsigns/callsign_104_col",0
+"callsign_106_col","#BANNER_CALLSIGN106",0,"rui/callsigns/callsign_106_col",0
+"callsign_107_col","#BANNER_CALLSIGN107",0,"rui/callsigns/callsign_107_col",0
+"callsign_108_col","#BANNER_CALLSIGN108",0,"rui/callsigns/callsign_108_col",0
+"callsign_109_col","#BANNER_CALLSIGN109",0,"rui/callsigns/callsign_109_col",0
+"callsign_110_col","#BANNER_CALLSIGN110",0,"rui/callsigns/callsign_110_col",0
+"callsign_111_col","#BANNER_CALLSIGN111",0,"rui/callsigns/callsign_111_col",0
+"callsign_112_col","#BANNER_CALLSIGN112",0,"rui/callsigns/callsign_112_col",0
+"callsign_113_col","#BANNER_CALLSIGN113",0,"rui/callsigns/callsign_113_col",0
+"callsign_114_col","#BANNER_CALLSIGN114",0,"rui/callsigns/callsign_114_col",0
+"callsign_115_col","#BANNER_CALLSIGN115",0,"rui/callsigns/callsign_115_col",0
+"callsign_116_col","#BANNER_CALLSIGN116",0,"rui/callsigns/callsign_116_col",0
+"callsign_117_col","#BANNER_CALLSIGN117",0,"rui/callsigns/callsign_117_col",0
+"callsign_118_col","#BANNER_CALLSIGN118",0,"rui/callsigns/callsign_118_col",0
+"callsign_119_col","#BANNER_CALLSIGN119",0,"rui/callsigns/callsign_119_col",0
+"callsign_120_col","#BANNER_CALLSIGN120",0,"rui/callsigns/callsign_120_col",0
+"callsign_121_col","#BANNER_CALLSIGN121",0,"rui/callsigns/callsign_121_col",0
+"callsign_122_col","#BANNER_CALLSIGN122",0,"rui/callsigns/callsign_122_col",0
+"callsign_123_col","#BANNER_CALLSIGN123",0,"rui/callsigns/callsign_123_col",0
+"callsign_124_col","#BANNER_CALLSIGN124",0,"rui/callsigns/callsign_124_col",0
+"callsign_125_col","#BANNER_CALLSIGN125",0,"rui/callsigns/callsign_125_col",0
+"callsign_139_col","#BANNER_CALLSIGN139",0,"rui/callsigns/callsign_139_col",0
+"callsign_139_col_fire","#BANNER_FIRE_CALLSIGN139",3,"rui/callsigns/callsign_139_col",0
+"callsign_139_col_gold","#BANNER_GOLD_CALLSIGN139",2,"rui/callsigns/callsign_139_col",0
+"callsign_126_col","#BANNER_CALLSIGN126",0,"rui/callsigns/callsign_126_col",0
+"callsign_127_col","#BANNER_CALLSIGN127",0,"rui/callsigns/callsign_127_col",0
+"callsign_128_col","#BANNER_CALLSIGN128",0,"rui/callsigns/callsign_128_col",0
+"callsign_129_col","#BANNER_CALLSIGN129",0,"rui/callsigns/callsign_129_col",0
+"callsign_130_col","#BANNER_CALLSIGN130",0,"rui/callsigns/callsign_130_col",0
+"callsign_131_col","#BANNER_CALLSIGN131",0,"rui/callsigns/callsign_131_col",0
+"callsign_132_col","#BANNER_CALLSIGN132",0,"rui/callsigns/callsign_132_col",0
+"callsign_133_col","#BANNER_CALLSIGN133",0,"rui/callsigns/callsign_133_col",0
+"callsign_134_col","#BANNER_CALLSIGN134",0,"rui/callsigns/callsign_134_col",0
+"callsign_135_col","#BANNER_CALLSIGN135",0,"rui/callsigns/callsign_135_col",0
+"callsign_136_col","#BANNER_CALLSIGN136",0,"rui/callsigns/callsign_136_col",0
+"callsign_137_col","#BANNER_CALLSIGN137",0,"rui/callsigns/callsign_137_col",0
+"callsign_138_col","#BANNER_CALLSIGN138",0,"rui/callsigns/callsign_138_col",0
+"callsign_125_col_fire","#BANNER_FIRE_CALLSIGN125",3,"rui/callsigns/callsign_125_col",0
+"callsign_126_col_fire","#BANNER_FIRE_CALLSIGN126",3,"rui/callsigns/callsign_126_col",0
+"callsign_127_col_fire","#BANNER_FIRE_CALLSIGN127",3,"rui/callsigns/callsign_127_col",0
+"callsign_128_col_fire","#BANNER_FIRE_CALLSIGN128",3,"rui/callsigns/callsign_128_col",0
+"callsign_129_col_fire","#BANNER_FIRE_CALLSIGN129",3,"rui/callsigns/callsign_129_col",0
+"callsign_130_col_fire","#BANNER_FIRE_CALLSIGN130",3,"rui/callsigns/callsign_130_col",0
+"callsign_131_col_fire","#BANNER_FIRE_CALLSIGN131",3,"rui/callsigns/callsign_131_col",0
+"callsign_132_col_fire","#BANNER_FIRE_CALLSIGN132",3,"rui/callsigns/callsign_132_col",0
+"callsign_133_col_fire","#BANNER_FIRE_CALLSIGN133",3,"rui/callsigns/callsign_133_col",0
+"callsign_134_col_fire","#BANNER_FIRE_CALLSIGN134",3,"rui/callsigns/callsign_134_col",0
+"callsign_135_col_fire","#BANNER_FIRE_CALLSIGN135",3,"rui/callsigns/callsign_135_col",0
+"callsign_136_col_fire","#BANNER_FIRE_CALLSIGN136",3,"rui/callsigns/callsign_136_col",0
+"callsign_137_col_fire","#BANNER_FIRE_CALLSIGN137",3,"rui/callsigns/callsign_137_col",0
+"callsign_138_col_fire","#BANNER_FIRE_CALLSIGN138",3,"rui/callsigns/callsign_138_col",0
+"callsign_125_col_gold","#BANNER_GOLD_CALLSIGN125",2,"rui/callsigns/callsign_125_col",0
+"callsign_126_col_gold","#BANNER_GOLD_CALLSIGN126",2,"rui/callsigns/callsign_126_col",0
+"callsign_127_col_gold","#BANNER_GOLD_CALLSIGN127",2,"rui/callsigns/callsign_127_col",0
+"callsign_128_col_gold","#BANNER_GOLD_CALLSIGN128",2,"rui/callsigns/callsign_128_col",0
+"callsign_129_col_gold","#BANNER_GOLD_CALLSIGN129",2,"rui/callsigns/callsign_129_col",0
+"callsign_130_col_gold","#BANNER_GOLD_CALLSIGN130",2,"rui/callsigns/callsign_130_col",0
+"callsign_131_col_gold","#BANNER_GOLD_CALLSIGN131",2,"rui/callsigns/callsign_131_col",0
+"callsign_132_col_gold","#BANNER_GOLD_CALLSIGN132",2,"rui/callsigns/callsign_132_col",0
+"callsign_133_col_gold","#BANNER_GOLD_CALLSIGN133",2,"rui/callsigns/callsign_133_col",0
+"callsign_134_col_gold","#BANNER_GOLD_CALLSIGN134",2,"rui/callsigns/callsign_134_col",0
+"callsign_135_col_gold","#BANNER_GOLD_CALLSIGN135",2,"rui/callsigns/callsign_135_col",0
+"callsign_136_col_gold","#BANNER_GOLD_CALLSIGN136",2,"rui/callsigns/callsign_136_col",0
+"callsign_137_col_gold","#BANNER_GOLD_CALLSIGN137",2,"rui/callsigns/callsign_137_col",0
+"callsign_138_col_gold","#BANNER_GOLD_CALLSIGN138",2,"rui/callsigns/callsign_138_col",0
+"callsign_125_col_prism","#BANNER_PRISM_CALLSIGN125",1,"rui/callsigns/callsign_125_col",0
+"callsign_126_col_prism","#BANNER_PRISM_CALLSIGN126",1,"rui/callsigns/callsign_126_col",1500
+"callsign_127_col_prism","#BANNER_PRISM_CALLSIGN127",1,"rui/callsigns/callsign_127_col",1500
+"callsign_128_col_prism","#BANNER_PRISM_CALLSIGN128",1,"rui/callsigns/callsign_128_col",0
+"callsign_129_col_prism","#BANNER_PRISM_CALLSIGN129",1,"rui/callsigns/callsign_129_col",0
+"callsign_130_col_prism","#BANNER_PRISM_CALLSIGN130",1,"rui/callsigns/callsign_130_col",1500
+"callsign_131_col_prism","#BANNER_PRISM_CALLSIGN131",1,"rui/callsigns/callsign_131_col",1500
+"callsign_132_col_prism","#BANNER_PRISM_CALLSIGN132",1,"rui/callsigns/callsign_132_col",0
+"callsign_133_col_prism","#BANNER_PRISM_CALLSIGN133",1,"rui/callsigns/callsign_133_col",0
+"callsign_134_col_prism","#BANNER_PRISM_CALLSIGN134",1,"rui/callsigns/callsign_134_col",0
+"callsign_135_col_prism","#BANNER_PRISM_CALLSIGN135",1,"rui/callsigns/callsign_135_col",0
+"callsign_136_col_prism","#BANNER_PRISM_CALLSIGN136",1,"rui/callsigns/callsign_136_col",0
+"callsign_137_col_prism","#BANNER_PRISM_CALLSIGN137",1,"rui/callsigns/callsign_137_col",0
+"callsign_138_col_prism","#BANNER_PRISM_CALLSIGN138",1,"rui/callsigns/callsign_138_col",0
+"callsign_140_col","#BANNER_CALLSIGN140",0,"rui/callsigns/callsign_140_col",0
+"callsign_141_col","#BANNER_CALLSIGN141",0,"rui/callsigns/callsign_141_col",0
+"callsign_142_col","#BANNER_CALLSIGN142",0,"rui/callsigns/callsign_142_col",0
+"callsign_140_col_fire","#BANNER_FIRE_CALLSIGN140",3,"rui/callsigns/callsign_140_col",0
+"callsign_141_col_fire","#BANNER_FIRE_CALLSIGN141",3,"rui/callsigns/callsign_141_col",0
+"callsign_142_col_fire","#BANNER_FIRE_CALLSIGN142",3,"rui/callsigns/callsign_142_col",0
+"callsign_140_col_gold","#BANNER_GOLD_CALLSIGN140",2,"rui/callsigns/callsign_140_col",0
+"callsign_141_col_gold","#BANNER_GOLD_CALLSIGN141",2,"rui/callsigns/callsign_141_col",0
+"callsign_142_col_gold","#BANNER_GOLD_CALLSIGN142",2,"rui/callsigns/callsign_142_col",0
+"callsign_143_col","#BANNER_CALLSIGN143",0,"rui/callsigns/callsign_143_col",0
+"callsign_144_col","#BANNER_CALLSIGN144",0,"rui/callsigns/callsign_144_col",0
+"callsign_145_col","#BANNER_CALLSIGN145",0,"rui/callsigns/callsign_145_col",0
+"callsign_146_col","#BANNER_CALLSIGN146",0,"rui/callsigns/callsign_146_col",0
+"callsign_147_col","#BANNER_CALLSIGN147",0,"rui/callsigns/callsign_147_col",0
+"callsign_148_col","#BANNER_CALLSIGN148",0,"rui/callsigns/callsign_148_col",0
+"callsign_149_col","#BANNER_CALLSIGN149",0,"rui/callsigns/callsign_149_col",0
+"callsign_150_col","#BANNER_CALLSIGN150",0,"rui/callsigns/callsign_150_col",0
+"callsign_151_col","#BANNER_CALLSIGN151",0,"rui/callsigns/callsign_151_col",0
+"callsign_152_col","#BANNER_CALLSIGN152",0,"rui/callsigns/callsign_152_col",0
+"callsign_153_col","#BANNER_CALLSIGN153",0,"rui/callsigns/callsign_153_col",0
+"callsign_154_col","#BANNER_CALLSIGN154",0,"rui/callsigns/callsign_154_col",0
+"callsign_155_col","#BANNER_CALLSIGN155",0,"rui/callsigns/callsign_155_col",0
+"callsign_156_col","#BANNER_CALLSIGN156",0,"rui/callsigns/callsign_156_col",0
+"callsign_157_col","#BANNER_CALLSIGN157",0,"rui/callsigns/callsign_157_col",0
+"callsign_158_col","#BANNER_CALLSIGN158",0,"rui/callsigns/callsign_158_col",0
+"callsign_159_col","#BANNER_CALLSIGN159",0,"rui/callsigns/callsign_159_col",0
+"callsign_160_col","#BANNER_CALLSIGN160",0,"rui/callsigns/callsign_160_col",0
+"callsign_161_col","#BANNER_CALLSIGN161",0,"rui/callsigns/callsign_161_col",0
+"callsign_162_col","#BANNER_CALLSIGN162",0,"rui/callsigns/callsign_162_col",0
+"callsign_163_col","#BANNER_CALLSIGN163",0,"rui/callsigns/callsign_163_col",0
+"callsign_164_col","#BANNER_CALLSIGN164",0,"rui/callsigns/callsign_164_col",0
+"callsign_163_col_prism","#BANNER_PRISM_CALLSIGN163",1,"rui/callsigns/callsign_163_col",0
+"callsign_164_col_prism","#BANNER_PRISM_CALLSIGN164",1,"rui/callsigns/callsign_164_col",0
+"callsign_163_col_gold","#BANNER_GOLD_CALLSIGN163",2,"rui/callsigns/callsign_163_col",0
+"callsign_164_col_gold","#BANNER_GOLD_CALLSIGN164",2,"rui/callsigns/callsign_164_col",0
+"callsign_163_col_fire","#BANNER_FIRE_CALLSIGN163",3,"rui/callsigns/callsign_163_col",0
+"callsign_164_col_fire","#BANNER_FIRE_CALLSIGN164",3,"rui/callsigns/callsign_164_col",0
+"callsign_regen_10_col","#BANNER_REGEN_10",0,"rui/callsigns/callsign_regen_10_col",0
+"callsign_regen_20_col","#BANNER_REGEN_20",0,"rui/callsigns/callsign_regen_20_col",0
+"callsign_regen_30_col","#BANNER_REGEN_30",0,"rui/callsigns/callsign_regen_30_col",0
+"callsign_regen_40_col","#BANNER_REGEN_40",0,"rui/callsigns/callsign_regen_40_col",0
+"callsign_regen_50_col","#BANNER_REGEN_50",0,"rui/callsigns/callsign_regen_50_col",0
+"callsign_regen_60_col","#BANNER_REGEN_60",0,"rui/callsigns/callsign_regen_60_col",0
+"callsign_regen_70_col","#BANNER_REGEN_70",0,"rui/callsigns/callsign_regen_70_col",0
+"callsign_regen_80_col","#BANNER_REGEN_80",0,"rui/callsigns/callsign_regen_80_col",0
+"callsign_regen_90_col","#BANNER_REGEN_90",0,"rui/callsigns/callsign_regen_90_col",0
+"callsign_regen_100_col","#BANNER_REGEN_100",0,"rui/callsigns/callsign_regen_100_col",0
+"callsign_regen_10_col_prism","#BANNER_PRISM_REGEN_10",1,"rui/callsigns/callsign_regen_10_col",0
+"callsign_regen_20_col_prism","#BANNER_PRISM_REGEN_20",1,"rui/callsigns/callsign_regen_20_col",0
+"callsign_regen_30_col_prism","#BANNER_PRISM_REGEN_30",1,"rui/callsigns/callsign_regen_30_col",0
+"callsign_regen_40_col_prism","#BANNER_PRISM_REGEN_40",1,"rui/callsigns/callsign_regen_40_col",0
+"callsign_regen_50_col_prism","#BANNER_PRISM_REGEN_50",1,"rui/callsigns/callsign_regen_50_col",0
+"callsign_regen_60_col_prism","#BANNER_PRISM_REGEN_60",1,"rui/callsigns/callsign_regen_60_col",0
+"callsign_regen_70_col_prism","#BANNER_PRISM_REGEN_70",1,"rui/callsigns/callsign_regen_70_col",0
+"callsign_regen_80_col_prism","#BANNER_PRISM_REGEN_80",1,"rui/callsigns/callsign_regen_80_col",0
+"callsign_regen_90_col_prism","#BANNER_PRISM_REGEN_90",1,"rui/callsigns/callsign_regen_90_col",0
+"callsign_regen_100_col_prism","#BANNER_PRISM_REGEN_100",1,"rui/callsigns/callsign_regen_100_col",0
+"callsign_165_col","#BANNER_CALLSIGN165",0,"rui/callsigns/callsign_165_col",0
+"callsign_166_col","#BANNER_CALLSIGN166",0,"rui/callsigns/callsign_166_col",0
+"callsign_167_col","#BANNER_CALLSIGN167",0,"rui/callsigns/callsign_167_col",0
+"callsign_168_col","#BANNER_CALLSIGN168",0,"rui/callsigns/callsign_168_col",0
+"callsign_169_col","#BANNER_CALLSIGN169",0,"rui/callsigns/callsign_169_col",0
+"callsign_170_col","#BANNER_CALLSIGN170",0,"rui/callsigns/callsign_170_col",0
+"callsign_171_col","#BANNER_CALLSIGN171",0,"rui/callsigns/callsign_171_col",0
+"callsign_172_col","#BANNER_CALLSIGN172",0,"rui/callsigns/callsign_172_col",0
+"callsign_173_col","#BANNER_CALLSIGN173",0,"rui/callsigns/callsign_173_col",0
+"callsign_174_col","#BANNER_CALLSIGN174",0,"rui/callsigns/callsign_174_col",0
+"callsign_175_col","#BANNER_CALLSIGN175",0,"rui/callsigns/callsign_175_col",0
+"callsign_176_col","#BANNER_CALLSIGN176",0,"rui/callsigns/callsign_176_col",0
+"callsign_177_col","#BANNER_CALLSIGN177",0,"rui/callsigns/callsign_177_col",0
+"callsign_178_col","#BANNER_CALLSIGN178",0,"rui/callsigns/callsign_178_col",0
+"callsign_179_col","#BANNER_CALLSIGN179",0,"rui/callsigns/callsign_179_col",0
+"callsign_180_col","#BANNER_CALLSIGN180",0,"rui/callsigns/callsign_180_col",0
+"callsign_181_col","#BANNER_CALLSIGN181",0,"rui/callsigns/callsign_181_col",0
+"callsign_182_col","#BANNER_CALLSIGN182",0,"rui/callsigns/callsign_182_col",0
+"callsign_183_col","#BANNER_CALLSIGN183",0,"rui/callsigns/callsign_183_col",0
+"callsign_184_col","#BANNER_CALLSIGN184",0,"rui/callsigns/callsign_184_col",0
+"callsign_185_col","#BANNER_CALLSIGN185",0,"rui/callsigns/callsign_185_col",0
+"callsign_165_col_fire","#BANNER_FIRE_CALLSIGN165",3,"rui/callsigns/callsign_165_col",0
+"callsign_165_col_gold","#BANNER_GOLD_CALLSIGN165",2,"rui/callsigns/callsign_165_col",0
+"callsign_24_col_prism","#BANNER_PRISM_CALLSIGN24",1,"rui/callsigns/callsign_24_col",0
+"callsign_47_col_prism","#BANNER_PRISM_CALLSIGN47",1,"rui/callsigns/callsign_47_col",0
+"callsign_36_col_prism","#BANNER_PRISM_CALLSIGN36",1,"rui/callsigns/callsign_36_col",0
+"callsign_45_col_prism","#BANNER_PRISM_CALLSIGN45",1,"rui/callsigns/callsign_45_col",0
+"callsign_68_col_prism","#BANNER_PRISM_CALLSIGN68",1,"rui/callsigns/callsign_68_col",0
+"callsign_26_col_prism","#BANNER_PRISM_CALLSIGN26",1,"rui/callsigns/callsign_26_col",0
+"callsign_165_col_prism","#BANNER_PRISM_CALLSIGN165",1,"rui/callsigns/callsign_165_col",0
+"callsign_fd_ion_dynamic","#BANNER_CALLSIGN_FD_ION",0,"rui/callsigns/callsign_fd_ion_dynamic",0
+"callsign_fd_tone_dynamic","#BANNER_CALLSIGN_FD_TONE",0,"rui/callsigns/callsign_fd_tone_dynamic",0
+"callsign_fd_scorch_dynamic","#BANNER_CALLSIGN_FD_SCORCH",0,"rui/callsigns/callsign_fd_scorch_dynamic",0
+"callsign_fd_legion_dynamic","#BANNER_CALLSIGN_FD_LEGION",0,"rui/callsigns/callsign_fd_legion_dynamic",0
+"callsign_fd_ronin_dynamic","#BANNER_CALLSIGN_FD_RONIN",0,"rui/callsigns/callsign_fd_ronin_dynamic",0
+"callsign_fd_northstar_dynamic","#BANNER_CALLSIGN_FD_NORTHSTAR",0,"rui/callsigns/callsign_fd_northstar_dynamic",0
+"callsign_fd_monarch_dynamic","#BANNER_CALLSIGN_FD_MONARCH",0,"rui/callsigns/callsign_fd_monarch_dynamic",0
+"callsign_fd_ion_hard","#BANNER_CALLSIGN_FD_ION",1,"rui/callsigns/callsign_fd_ion_hard",0
+"callsign_fd_ion_master","#BANNER_CALLSIGN_FD_ION",1,"rui/callsigns/callsign_fd_ion_master",0
+"callsign_fd_ion_insane","#BANNER_CALLSIGN_FD_ION",2,"rui/callsigns/callsign_fd_ion_insane",0
+"callsign_fd_tone_hard","#BANNER_CALLSIGN_FD_TONE",1,"rui/callsigns/callsign_fd_tone_hard",0
+"callsign_fd_tone_master","#BANNER_CALLSIGN_FD_TONE",1,"rui/callsigns/callsign_fd_tone_master",0
+"callsign_fd_tone_insane","#BANNER_CALLSIGN_FD_TONE",2,"rui/callsigns/callsign_fd_tone_insane",0
+"callsign_fd_scorch_hard","#BANNER_CALLSIGN_FD_SCORCH",1,"rui/callsigns/callsign_fd_scorch_hard",0
+"callsign_fd_scorch_master","#BANNER_CALLSIGN_FD_SCORCH",1,"rui/callsigns/callsign_fd_scorch_master",0
+"callsign_fd_scorch_insane","#BANNER_CALLSIGN_FD_SCORCH",2,"rui/callsigns/callsign_fd_scorch_insane",0
+"callsign_fd_legion_hard","#BANNER_CALLSIGN_FD_LEGION",1,"rui/callsigns/callsign_fd_legion_hard",0
+"callsign_fd_legion_master","#BANNER_CALLSIGN_FD_LEGION",1,"rui/callsigns/callsign_fd_legion_master",0
+"callsign_fd_legion_insane","#BANNER_CALLSIGN_FD_LEGION",2,"rui/callsigns/callsign_fd_legion_insane",0
+"callsign_fd_ronin_hard","#BANNER_CALLSIGN_FD_RONIN",1,"rui/callsigns/callsign_fd_ronin_hard",0
+"callsign_fd_ronin_master","#BANNER_CALLSIGN_FD_RONIN",1,"rui/callsigns/callsign_fd_ronin_master",0
+"callsign_fd_ronin_insane","#BANNER_CALLSIGN_FD_RONIN",2,"rui/callsigns/callsign_fd_ronin_insane",0
+"callsign_fd_northstar_hard","#BANNER_CALLSIGN_FD_NORTHSTAR",1,"rui/callsigns/callsign_fd_northstar_hard",0
+"callsign_fd_northstar_master","#BANNER_CALLSIGN_FD_NORTHSTAR",1,"rui/callsigns/callsign_fd_northstar_master",0
+"callsign_fd_northstar_insane","#BANNER_CALLSIGN_FD_NORTHSTAR",2,"rui/callsigns/callsign_fd_northstar_insane",0
+"callsign_fd_monarch_hard","#BANNER_CALLSIGN_FD_MONARCH",1,"rui/callsigns/callsign_fd_monarch_hard",0
+"callsign_fd_monarch_master","#BANNER_CALLSIGN_FD_MONARCH",1,"rui/callsigns/callsign_fd_monarch_master",0
+"callsign_fd_monarch_insane","#BANNER_CALLSIGN_FD_MONARCH",2,"rui/callsigns/callsign_fd_monarch_insane",0
+"callsign_tt_gameover","#BANNER_CALLSIGN_TT_GAMEOVER",0,"rui/callsigns/callsign_tt_gameover",1500
+"callsign_tt_gameover_prism","#BANNER_PRISM_TT_GAMEOVER",1,"rui/callsigns/callsign_tt_gameover",3000
+"callsign_tt_guardtheflag","#BANNER_CALLSIGN_TT_GUARDTHEFLAG",0,"rui/callsigns/callsign_tt_guardtheflag",1500
+"callsign_tt_guardtheflag_prism","#BANNER_PRISM_TT_GUARDTHEFLAG",1,"rui/callsigns/callsign_tt_guardtheflag",3000
+"callsign_tt_megamarvin","#BANNER_CALLSIGN_TT_MEGAMARVIN",0,"rui/callsigns/callsign_tt_megamarvin",1500
+"callsign_tt_megamarvin_prism","#BANNER_PRISM_TT_MEGAMARVIN",1,"rui/callsigns/callsign_tt_megamarvin",3000
+"callsign_tt_nessievault","#BANNER_CALLSIGN_TT_NESSIEVAULT",0,"rui/callsigns/callsign_tt_nessievault",1500
+"callsign_tt_nessievault_prism","#BANNER_PRISM_TT_NESSIEVAULT",1,"rui/callsigns/callsign_tt_nessievault",3000
+"callsign_tt_nsbt","#BANNER_CALLSIGN_TT_NSBT",0,"rui/callsigns/callsign_tt_nsbt",1500
+"callsign_tt_nsbt_prism","#BANNER_PRISM_TT_NSBT",1,"rui/callsigns/callsign_tt_nsbt",3000
+"callsign_tt_protocol2","#BANNER_CALLSIGN_TT_PROTOCOL2",0,"rui/callsigns/callsign_tt_protocol2",1500
+"callsign_tt_protocol2_prism","#BANNER_PRISM_TT_PROTOCOL2",1,"rui/callsigns/callsign_tt_protocol2",3000
+"callsign_tt_rekt","#BANNER_CALLSIGN_TT_REKT",0,"rui/callsigns/callsign_tt_rekt",1500
+"callsign_tt_rekt_prism","#BANNER_PRISM_TT_REKT",1,"rui/callsigns/callsign_tt_rekt",3000
+"callsign_tt_titantoons","#BANNER_CALLSIGN_TT_TITANTOONS",0,"rui/callsigns/callsign_tt_titantoons",1500
+"callsign_tt_titantoons_prism","#BANNER_PRISM_TT_TITANTOONS",1,"rui/callsigns/callsign_tt_titantoons",3000
+"callsign_eat_ion","#BANNER_EAT_ION",0,"rui/callsigns/callsign_eat_ion",1500
+"callsign_eat_legion","#BANNER_EAT_LEGION",0,"rui/callsigns/callsign_eat_legion",1500
+"callsign_eat_northstar","#BANNER_EAT_NORTHSTAR",0,"rui/callsigns/callsign_eat_northstar",1500
+"callsign_eat_ronin","#BANNER_EAT_RONIN",0,"rui/callsigns/callsign_eat_ronin",1500
+"callsign_eat_scorch","#BANNER_EAT_SCORCH",0,"rui/callsigns/callsign_eat_scorch",1500
+"callsign_eat_tone","#BANNER_EAT_TONE",0,"rui/callsigns/callsign_eat_tone",1500
+"callsign_goodboy","#BANNER_GOODBOY",0,"rui/callsigns/callsign_goodboy",0
+"callsign_contest_01","#BANNER_CONTEST_01",0,"rui/callsigns/callsign_contest_01",0
+"callsign_contest_02","#BANNER_CONTEST_02",0,"rui/callsigns/callsign_contest_02",0
+"callsign_contest_03","#BANNER_CONTEST_03",0,"rui/callsigns/callsign_contest_03",0
+"callsign_contest_04","#BANNER_CONTEST_04",0,"rui/callsigns/callsign_contest_04",0
+"callsign_contest_05","#BANNER_CONTEST_05",0,"rui/callsigns/callsign_contest_05",0
+"callsign_contest_06","#BANNER_CONTEST_06",0,"rui/callsigns/callsign_contest_06",0
+"callsign_contest_07","#BANNER_CONTEST_07",0,"rui/callsigns/callsign_contest_07",0
+"callsign_contest_08","#BANNER_CONTEST_08",0,"rui/callsigns/callsign_contest_08",0
+"callsign_contest_09","#BANNER_CONTEST_09",0,"rui/callsigns/callsign_contest_09",0
+"callsign_contest_10","#BANNER_CONTEST_10",0,"rui/callsigns/callsign_contest_10",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/callsign_icons.csv b/Northstar.CustomServers/mod/scripts/datatable/callsign_icons.csv new file mode 100644 index 00000000..61840c68 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/callsign_icons.csv @@ -0,0 +1,193 @@ +itemRef,name,image,smallImage,cost
+"gc_icon_5star","#PATCH_GC_ICON_5STAR","rui/gencard_icons/gc_icon_5star","rui/gencard_icons/gc_icon_5star_small",50
+"gc_icon_8ball","#PATCH_8BALL","rui/gencard_icons/gc_icon_8ball","rui/gencard_icons/gc_icon_8ball_small",0
+"gc_icon_ace","#PATCH_ACE","rui/gencard_icons/gc_icon_ace","rui/gencard_icons/gc_icon_ace_small",0
+"gc_icon_angryface","#PATCH_ANGRYFACE","rui/gencard_icons/gc_icon_angryface","rui/gencard_icons/gc_icon_angryface_small",50
+"gc_icon_apostrophe","#PATCH_APOSTROPHE","rui/gencard_icons/gc_icon_apostrophe","rui/gencard_icons/gc_icon_apostrophe_small",0
+"gc_icon_atom","#PATCH_ATOM","rui/gencard_icons/gc_icon_atom","rui/gencard_icons/gc_icon_atom_small",0
+"gc_icon_balloon","#PATCH_BALLOON","rui/gencard_icons/gc_icon_balloon","rui/gencard_icons/gc_icon_balloon_small",0
+"gc_icon_bear","#PATCH_BEAR","rui/gencard_icons/gc_icon_bear","rui/gencard_icons/gc_icon_bear_small",50
+"gc_icon_bird","#PATCH_BIRD","rui/gencard_icons/gc_icon_bird","rui/gencard_icons/gc_icon_bird_small",50
+"gc_icon_bomb_01","#PATCH_BOMB_01","rui/gencard_icons/gc_icon_bomb_01","rui/gencard_icons/gc_icon_bomb_01_small",0
+"gc_icon_bomb_02","#PATCH_BOMB_02","rui/gencard_icons/gc_icon_bomb_02","rui/gencard_icons/gc_icon_bomb_02_small",0
+"gc_icon_bullet","#PATCH_BULLET","rui/gencard_icons/gc_icon_bullet","rui/gencard_icons/gc_icon_bullet_small",0
+"gc_icon_bullseye","#PATCH_BULLSEYE","rui/gencard_icons/gc_icon_bullseye","rui/gencard_icons/gc_icon_bullseye_small",0
+"gc_icon_cateye","#PATCH_CATEYE","rui/gencard_icons/gc_icon_cateye","rui/gencard_icons/gc_icon_cateye_small",0
+"gc_icon_chicken","#PATCH_CHICKEN","rui/gencard_icons/gc_icon_chicken","rui/gencard_icons/gc_icon_chicken_small",50
+"gc_icon_clawmark","#PATCH_CLAWMARK","rui/gencard_icons/gc_icon_clawmark","rui/gencard_icons/gc_icon_clawmark_small",0
+"gc_icon_club","#PATCH_CLUB","rui/gencard_icons/gc_icon_club","rui/gencard_icons/gc_icon_club_small",50
+"gc_icon_comet","#PATCH_COMET","rui/gencard_icons/gc_icon_comet","rui/gencard_icons/gc_icon_comet_small",0
+"gc_icon_cow","#PATCH_COW","rui/gencard_icons/gc_icon_cow","rui/gencard_icons/gc_icon_cow_small",50
+"gc_icon_cowboy_hat","#PATCH_COWBOY_HAT","rui/gencard_icons/gc_icon_cowboy_hat","rui/gencard_icons/gc_icon_cowboy_hat_small",0
+"gc_icon_crosshair","#PATCH_CROSSHAIR","rui/gencard_icons/gc_icon_crosshair","rui/gencard_icons/gc_icon_crosshair_small",0
+"gc_icon_cupcake","#PATCH_CUPCAKE","rui/gencard_icons/gc_icon_cupcake","rui/gencard_icons/gc_icon_cupcake_small",50
+"gc_icon_diamond","#PATCH_DIAMOND","rui/gencard_icons/gc_icon_diamond","rui/gencard_icons/gc_icon_diamond_small",0
+"gc_icon_dice","#PATCH_DICE","rui/gencard_icons/gc_icon_dice","rui/gencard_icons/gc_icon_dice_small",0
+"gc_icon_dollarsign","#PATCH_DOLLARSIGN","rui/gencard_icons/gc_icon_dollarsign","rui/gencard_icons/gc_icon_dollarsign_small",0
+"gc_icon_doublerainbow","#PATCH_DOUBLERAINBOW","rui/gencard_icons/gc_icon_doublerainbow","rui/gencard_icons/gc_icon_doublerainbow_small",50
+"gc_icon_fingerprint","#PATCH_FINGERPRINT","rui/gencard_icons/gc_icon_fingerprint","rui/gencard_icons/gc_icon_fingerprint_small",50
+"gc_icon_fireball","#PATCH_FIREBALL","rui/gencard_icons/gc_icon_fireball","rui/gencard_icons/gc_icon_fireball_small",0
+"gc_icon_frag","#PATCH_FRAG","rui/gencard_icons/gc_icon_frag","rui/gencard_icons/gc_icon_frag_small",0
+"gc_icon_gear","#PATCH_GEAR","rui/gencard_icons/gc_icon_gear","rui/gencard_icons/gc_icon_gear_small",0
+"gc_icon_ghostface","#PATCH_GHOSTFACE","rui/gencard_icons/gc_icon_ghostface","rui/gencard_icons/gc_icon_ghostface_small",50
+"gc_icon_hamburger","#PATCH_HAMBURGER","rui/gencard_icons/gc_icon_hamburger","rui/gencard_icons/gc_icon_hamburger_small",50
+"gc_icon_handprint","#PATCH_HANDPRINT","rui/gencard_icons/gc_icon_handprint","rui/gencard_icons/gc_icon_handprint_small",50
+"gc_icon_happyface","#PATCH_HAPPYFACE","rui/gencard_icons/gc_icon_happyface","rui/gencard_icons/gc_icon_happyface_small",0
+"gc_icon_heart","#PATCH_HEART","rui/gencard_icons/gc_icon_heart","rui/gencard_icons/gc_icon_heart_small",0
+"gc_icon_hvt","#PATCH_HVT","rui/gencard_icons/gc_icon_hvt","rui/gencard_icons/gc_icon_hvt_small",50
+"gc_icon_jollyrgr","#PATCH_JOLLYRGR","rui/gencard_icons/gc_icon_jollyrgr","rui/gencard_icons/gc_icon_jollyrgr_small",50
+"gc_icon_lightning","#PATCH_LIGHTNING","rui/gencard_icons/gc_icon_lightning","rui/gencard_icons/gc_icon_lightning_small",0
+"gc_icon_lol","#PATCH_LOL","rui/gencard_icons/gc_icon_lol","rui/gencard_icons/gc_icon_lol_small",50
+"gc_icon_mad_hat","#PATCH_MAD_HAT","rui/gencard_icons/gc_icon_mad_hat","rui/gencard_icons/gc_icon_mad_hat_small",50
+"gc_icon_medic","#PATCH_MEDIC","rui/gencard_icons/gc_icon_medic","rui/gencard_icons/gc_icon_medic_small",0
+"gc_icon_moon","#PATCH_MOON","rui/gencard_icons/gc_icon_moon","rui/gencard_icons/gc_icon_moon_small",0
+"gc_icon_omg","#PATCH_OMG","rui/gencard_icons/gc_icon_omg","rui/gencard_icons/gc_icon_omg_small",50
+"gc_icon_paw","#PATCH_PAW","rui/gencard_icons/gc_icon_paw","rui/gencard_icons/gc_icon_paw_small",0
+"gc_icon_pizza","#PATCH_PIZZA","rui/gencard_icons/gc_icon_pizza","rui/gencard_icons/gc_icon_pizza_small",50
+"gc_icon_pro","#PATCH_PRO","rui/gencard_icons/gc_icon_pro","rui/gencard_icons/gc_icon_pro_small",0
+"gc_icon_question","#PATCH_QUESTION","rui/gencard_icons/gc_icon_question","rui/gencard_icons/gc_icon_question_small",50
+"gc_icon_rainbow","#PATCH_RAINBOW","rui/gencard_icons/gc_icon_rainbow","rui/gencard_icons/gc_icon_rainbow_small",50
+"gc_icon_raincloud","#PATCH_RAINCLOUD","rui/gencard_icons/gc_icon_raincloud","rui/gencard_icons/gc_icon_raincloud_small",0
+"gc_icon_rocket","#PATCH_ROCKET","rui/gencard_icons/gc_icon_rocket","rui/gencard_icons/gc_icon_rocket_small",0
+"gc_icon_saturn","#PATCH_SATURN","rui/gencard_icons/gc_icon_saturn","rui/gencard_icons/gc_icon_saturn_small",50
+"gc_icon_skull","#PATCH_SKULL","rui/gencard_icons/gc_icon_skull","rui/gencard_icons/gc_icon_skull_small",50
+"gc_icon_spade","#PATCH_SPADE","rui/gencard_icons/gc_icon_spade","rui/gencard_icons/gc_icon_spade_small",0
+"gc_icon_star","#PATCH_STAR","rui/gencard_icons/gc_icon_star","rui/gencard_icons/gc_icon_star_small",0
+"gc_icon_sword","#PATCH_SWORD","rui/gencard_icons/gc_icon_sword","rui/gencard_icons/gc_icon_sword_small",0
+"gc_icon_teabage","#PATCH_TEABAGE","rui/gencard_icons/gc_icon_teabage","rui/gencard_icons/gc_icon_teabage_small",50
+"gc_icon_titanfall","#PATCH_TITANFALL","rui/gencard_icons/gc_icon_titanfall","rui/gencard_icons/gc_icon_titanfall_small",0
+"gc_icon_vip","#PATCH_VIP","rui/gencard_icons/gc_icon_vip","rui/gencard_icons/gc_icon_vip_small",0
+"gc_icon_witch_hat","#PATCH_WITCH_HAT","rui/gencard_icons/gc_icon_witch_hat","rui/gencard_icons/gc_icon_witch_hat_small",50
+"gc_icon_wizard_hat","#PATCH_WIZARD_HAT","rui/gencard_icons/gc_icon_wizard_hat","rui/gencard_icons/gc_icon_wizard_hat_small",50
+"gc_icon_wtf","#PATCH_WTF","rui/gencard_icons/gc_icon_wtf","rui/gencard_icons/gc_icon_wtf_small",50
+"gc_icon_yuckface","#PATCH_YUCKFACE","rui/gencard_icons/gc_icon_yuckface","rui/gencard_icons/gc_icon_yuckface_small",0
+"gc_icon_respawn","#PATCH_RESPAWN","rui/gencard_icons/gc_icon_respawn","rui/gencard_icons/gc_icon_respawn_small",50
+"gc_icon_fair_warning","#PATCH_FAIR_WARNING","rui/gencard_icons/gc_icon_fair_warning","rui/gencard_icons/gc_icon_fair_warning_small",50
+"gc_icon_hawk","#PATCH_HAWK","rui/gencard_icons/gc_icon_hawk","rui/gencard_icons/gc_icon_hawk_small",0
+"gc_icon_ram","#PATCH_RAM","rui/gencard_icons/gc_icon_ram","rui/gencard_icons/gc_icon_ram_small",50
+"gc_icon_stab","#PATCH_STAB","rui/gencard_icons/gc_icon_stab","rui/gencard_icons/gc_icon_stab_small",50
+"gc_icon_bigcat","#PATCH_BIGCAT","rui/gencard_icons/gc_icon_bigcat","rui/gencard_icons/gc_icon_bigcat_small",50
+"gc_icon_wraith","#PATCH_WRAITH","rui/gencard_icons/gc_icon_wraith","rui/gencard_icons/gc_icon_wraith_small",50
+"gc_icon_stinger","#PATCH_STINGER","rui/gencard_icons/gc_icon_stinger","rui/gencard_icons/gc_icon_stinger_small",0
+"gc_icon_heartless","#PATCH_HEARTLESS","rui/gencard_icons/gc_icon_heartless","rui/gencard_icons/gc_icon_heartless_small",50
+"gc_icon_earthworm","#PATCH_EARTHWORM","rui/gencard_icons/gc_icon_earthworm","rui/gencard_icons/gc_icon_earthworm_small",50
+"gc_icon_prowler","#PATCH_PROWLER","rui/gencard_icons/gc_icon_prowler","rui/gencard_icons/gc_icon_prowler_small",0
+"gc_icon_ordnance","#PATCH_ORDNANCE","rui/gencard_icons/gc_icon_ordnance","rui/gencard_icons/gc_icon_ordnance_small",50
+"gc_icon_radar","#PATCH_RADAR","rui/gencard_icons/gc_icon_radar","rui/gencard_icons/gc_icon_radar_small",0
+"gc_icon_ramskull","#PATCH_RAMSKULL","rui/gencard_icons/gc_icon_ramskull","rui/gencard_icons/gc_icon_ramskull_small",0
+"gc_icon_hawkmoth","#PATCH_HAWKMOTH","rui/gencard_icons/gc_icon_hawkmoth","rui/gencard_icons/gc_icon_hawkmoth_small",50
+"gc_icon_fox","#PATCH_FOX","rui/gencard_icons/gc_icon_fox","rui/gencard_icons/gc_icon_fox_small",0
+"gc_icon_marksman","#PATCH_MARKSMAN","rui/gencard_icons/gc_icon_marksman","rui/gencard_icons/gc_icon_marksman_small",50
+"gc_icon_bunnyskull","#PATCH_BUNNYSKULL","rui/gencard_icons/gc_icon_bunnyskull","rui/gencard_icons/gc_icon_bunnyskull_small",50
+"gc_icon_falcon","#PATCH_FALCON","rui/gencard_icons/gc_icon_falcon","rui/gencard_icons/gc_icon_falcon_small",50
+"gc_icon_assault","#PATCH_ASSAULT","rui/gencard_icons/gc_icon_assault","rui/gencard_icons/gc_icon_assault_small",0
+"gc_icon_flying_skull","#PATCH_FLYING_SKULL","rui/gencard_icons/gc_icon_flying_skull","rui/gencard_icons/gc_icon_flying_skull_small",50
+"gc_icon_hammer","#PATCH_HAMMER","rui/gencard_icons/gc_icon_hammer","rui/gencard_icons/gc_icon_hammer_small",50
+"gc_icon_dragonfly","#PATCH_DRAGONFLY","rui/gencard_icons/gc_icon_dragonfly","rui/gencard_icons/gc_icon_dragonfly_small",0
+"gc_icon_striketwice","#PATCH_STRIKETWICE","rui/gencard_icons/gc_icon_striketwice","rui/gencard_icons/gc_icon_striketwice_small",0
+"gc_icon_waves","#PATCH_WAVES","rui/gencard_icons/gc_icon_waves","rui/gencard_icons/gc_icon_waves_small",0
+"gc_icon_fin","#PATCH_FIN","rui/gencard_icons/gc_icon_fin","rui/gencard_icons/gc_icon_fin_small",0
+"gc_icon_bee","#PATCH_BEE","rui/gencard_icons/gc_icon_bee","rui/gencard_icons/gc_icon_bee_small",50
+"gc_icon_wasp","#PATCH_WASP","rui/gencard_icons/gc_icon_wasp","rui/gencard_icons/gc_icon_wasp_small",0
+"gc_icon_bat","#PATCH_BAT","rui/gencard_icons/gc_icon_bat","rui/gencard_icons/gc_icon_bat_small",0
+"gc_icon_dataknife","#PATCH_DATAKNIFE","rui/gencard_icons/gc_icon_dataknife","rui/gencard_icons/gc_icon_dataknife_small",50
+"gc_icon_knife","#PATCH_KNIFE","rui/gencard_icons/gc_icon_knife","rui/gencard_icons/gc_icon_knife_small",50
+"gc_icon_widow","#PATCH_WIDOW","rui/gencard_icons/gc_icon_widow","rui/gencard_icons/gc_icon_widow_small",50
+"gc_icon_snake","#PATCH_SNAKE","rui/gencard_icons/gc_icon_snake","rui/gencard_icons/gc_icon_snake_small",50
+"gc_icon_scorpion","#PATCH_SCORPION","rui/gencard_icons/gc_icon_scorpion","rui/gencard_icons/gc_icon_scorpion_small",50
+"gc_icon_dragon","#PATCH_DRAGON","rui/gencard_icons/gc_icon_dragon","rui/gencard_icons/gc_icon_dragon_small",50
+"gc_icon_sgt_major","#PATCH_SGT_MAJOR","rui/gencard_icons/gc_icon_sgt_major","rui/gencard_icons/gc_icon_sgt_major_small",0
+"gc_icon_senior_sgt_e6","#PATCH_SENIOR_SGT_E6","rui/gencard_icons/gc_icon_senior_sgt_e6","rui/gencard_icons/gc_icon_senior_sgt_e6_small",50
+"gc_icon_senior_sgt","#PATCH_SENIOR_SGT","rui/gencard_icons/gc_icon_senior_sgt","rui/gencard_icons/gc_icon_senior_sgt_small",50
+"gc_icon_sgt","#PATCH_SGT","rui/gencard_icons/gc_icon_sgt","rui/gencard_icons/gc_icon_sgt_small",50
+"gc_icon_corporal","#PATCH_CORPORAL","rui/gencard_icons/gc_icon_corporal","rui/gencard_icons/gc_icon_corporal_small",50
+"gc_icon_pvt","#PATCH_PVT","rui/gencard_icons/gc_icon_private","rui/gencard_icons/gc_icon_private_small",50
+"gc_icon_gen0","#PATCH_GEN0","rui/gencard_icons/gc_icon_gen0","rui/gencard_icons/gc_icon_gen0_small",0
+"gc_icon_gen1","#PATCH_GEN1","rui/gencard_icons/gc_icon_gen1","rui/gencard_icons/gc_icon_gen1_small",0
+"gc_icon_gen2","#PATCH_GEN2","rui/gencard_icons/gc_icon_gen2","rui/gencard_icons/gc_icon_gen2_small",0
+"gc_icon_gen3","#PATCH_GEN3","rui/gencard_icons/gc_icon_gen3","rui/gencard_icons/gc_icon_gen3_small",0
+"gc_icon_gen4","#PATCH_GEN4","rui/gencard_icons/gc_icon_gen4","rui/gencard_icons/gc_icon_gen4_small",0
+"gc_icon_gen5","#PATCH_GEN5","rui/gencard_icons/gc_icon_gen5","rui/gencard_icons/gc_icon_gen5_small",0
+"gc_icon_gen6","#PATCH_GEN6","rui/gencard_icons/gc_icon_gen6","rui/gencard_icons/gc_icon_gen6_small",0
+"gc_icon_gen7","#PATCH_GEN7","rui/gencard_icons/gc_icon_gen7","rui/gencard_icons/gc_icon_gen7_small",0
+"gc_icon_gen8","#PATCH_GEN8","rui/gencard_icons/gc_icon_gen8","rui/gencard_icons/gc_icon_gen8_small",0
+"gc_icon_gen9","#PATCH_GEN9","rui/gencard_icons/gc_icon_gen9","rui/gencard_icons/gc_icon_gen9_small",0
+"gc_icon_respawn_dev","#PATCH_DEV","rui/gencard_icons/gc_icon_respawn_dev","rui/gencard_icons/gc_icon_respawn_dev_small",0
+"gc_icon_64","#PATCH_64","rui/gencard_icons/dlc1/gc_icon_64","rui/gencard_icons/dlc1/gc_icon_64_small",0
+"gc_icon_aces","#PATCH_ACES","rui/gencard_icons/dlc1/gc_icon_aces","rui/gencard_icons/dlc1/gc_icon_aces_small",0
+"gc_icon_alien","#PATCH_ALIEN","rui/gencard_icons/dlc1/gc_icon_alien","rui/gencard_icons/dlc1/gc_icon_alien_small",0
+"gc_icon_apex","#PATCH_APEX","rui/gencard_icons/dlc1/gc_icon_apex","rui/gencard_icons/dlc1/gc_icon_apex_small",0
+"gc_icon_ares","#PATCH_ARES","rui/gencard_icons/dlc1/gc_icon_ares","rui/gencard_icons/dlc1/gc_icon_ares_small",0
+"gc_icon_controller","#PATCH_CONTROLLER","rui/gencard_icons/dlc1/gc_icon_controller","rui/gencard_icons/dlc1/gc_icon_controller_small",0
+"gc_icon_drone","#PATCH_DRONE","rui/gencard_icons/dlc1/gc_icon_drone","rui/gencard_icons/dlc1/gc_icon_drone_small",0
+"gc_icon_heartbreaker","#PATCH_HEARTBREAKER","rui/gencard_icons/dlc1/gc_icon_heartbreaker","rui/gencard_icons/dlc1/gc_icon_heartbreaker_small",0
+"gc_icon_hexes","#PATCH_HEXES","rui/gencard_icons/dlc1/gc_icon_hexes","rui/gencard_icons/dlc1/gc_icon_hexes_small",0
+"gc_icon_kodai","#PATCH_KODAI","rui/gencard_icons/dlc1/gc_icon_kodai","rui/gencard_icons/dlc1/gc_icon_kodai_small",0
+"gc_icon_lastimosa","#PATCH_LASTIMOSA","rui/gencard_icons/dlc1/gc_icon_lastimosa","rui/gencard_icons/dlc1/gc_icon_lastimosa_small",0
+"gc_icon_lawai","#PATCH_LAWAI","rui/gencard_icons/dlc1/gc_icon_lawai","rui/gencard_icons/dlc1/gc_icon_lawai_small",0
+"gc_icon_mcor","#PATCH_MCOR","rui/gencard_icons/dlc1/gc_icon_mcor","rui/gencard_icons/dlc1/gc_icon_mcor_small",0
+"gc_icon_phoenix","#PATCH_PHOENIX","rui/gencard_icons/dlc1/gc_icon_phoenix","rui/gencard_icons/dlc1/gc_icon_phoenix_small",0
+"gc_icon_pilot","#PATCH_PILOT","rui/gencard_icons/dlc1/gc_icon_pilot","rui/gencard_icons/dlc1/gc_icon_pilot_small",0
+"gc_icon_robot","#PATCH_ROBOT","rui/gencard_icons/dlc1/gc_icon_robot","rui/gencard_icons/dlc1/gc_icon_robot_small",0
+"gc_icon_sentry","#PATCH_SENTRY","rui/gencard_icons/dlc1/gc_icon_sentry","rui/gencard_icons/dlc1/gc_icon_sentry_small",0
+"gc_icon_super_spectre","#PATCH_SUPER_SPECTRE","rui/gencard_icons/dlc1/gc_icon_super_spectre","rui/gencard_icons/dlc1/gc_icon_super_spectre_small",0
+"gc_icon_vinson","#PATCH_VINSON","rui/gencard_icons/dlc1/gc_icon_vinson","rui/gencard_icons/dlc1/gc_icon_vinson_small",0
+"gc_icon_wonyeon","#PATCH_WONYEON","rui/gencard_icons/dlc1/gc_icon_wonyeon","rui/gencard_icons/dlc1/gc_icon_wonyeon_small",0
+"gc_icon_b3_wing","#PATCH_B3_WING","rui/gencard_icons/gc_icon_b3_wing","rui/gencard_icons/gc_icon_b3_wing_small",0
+"gc_icon_balance","#PATCH_BALANCE","rui/gencard_icons/dlc3/gc_icon_balance","rui/gencard_icons/dlc3/gc_icon_balance_small",0
+"gc_icon_boot","#PATCH_BOOT","rui/gencard_icons/dlc3/gc_icon_boot","rui/gencard_icons/dlc3/gc_icon_boot_small",0
+"gc_icon_bt_eye","#PATCH_BT_EYE","rui/gencard_icons/dlc3/gc_icon_bt_eye","rui/gencard_icons/dlc3/gc_icon_bt_eye_small",0
+"gc_icon_peace","#PATCH_PEACE","rui/gencard_icons/dlc3/gc_icon_peace","rui/gencard_icons/dlc3/gc_icon_peace_small",0
+"gc_icon_pilot2","#PATCH_PILOT2","rui/gencard_icons/dlc3/gc_icon_pilot","rui/gencard_icons/dlc3/gc_icon_pilot_small",0
+"gc_icon_srs","#PATCH_SRS","rui/gencard_icons/dlc3/gc_icon_srs","rui/gencard_icons/dlc3/gc_icon_srs_small",0
+"gc_icon_starline","#PATCH_STARLINE","rui/gencard_icons/dlc3/gc_icon_starline","rui/gencard_icons/dlc3/gc_icon_starline_small",0
+"gc_icon_thumbdown","#PATCH_THUMBDOWN","rui/gencard_icons/dlc3/gc_icon_thumbdown","rui/gencard_icons/dlc3/gc_icon_thumbdown_small",0
+"gc_icon_thumbup","#PATCH_THUMBUP","rui/gencard_icons/dlc3/gc_icon_thumbup","rui/gencard_icons/dlc3/gc_icon_thumbup_small",0
+"gc_icon_vanguard","#PATCH_VANGUARD","rui/gencard_icons/dlc3/gc_icon_vanguard","rui/gencard_icons/dlc3/gc_icon_vanguard_small",0
+"gc_icon_deuce","#PATCH_DEUCE","rui/gencard_icons/dlc2/gc_icon_deuce","rui/gencard_icons/dlc2/gc_icon_deuce_small",0
+"gc_icon_down","#PATCH_DOWN","rui/gencard_icons/dlc2/gc_icon_down","rui/gencard_icons/dlc2/gc_icon_down_small",50
+"gc_icon_joy","#PATCH_JOY","rui/gencard_icons/dlc2/gc_icon_joy","rui/gencard_icons/dlc2/gc_icon_joy_small",50
+"gc_icon_mushroom","#PATCH_MUSHROOM","rui/gencard_icons/dlc2/gc_icon_mushroom","rui/gencard_icons/dlc2/gc_icon_mushroom_small",0
+"gc_icon_prowlerhead","#PATCH_PROWLERHEAD","rui/gencard_icons/dlc2/gc_icon_prowlerhead","rui/gencard_icons/dlc2/gc_icon_prowlerhead_small",0
+"gc_icon_scythe","#PATCH_SCYTHE","rui/gencard_icons/dlc2/gc_icon_scythe","rui/gencard_icons/dlc2/gc_icon_scythe_small",0
+"gc_icon_shuriken","#PATCH_SHURIKEN","rui/gencard_icons/dlc2/gc_icon_shuriken","rui/gencard_icons/dlc2/gc_icon_shuriken_small",0
+"gc_icon_squid","#PATCH_SQUID","rui/gencard_icons/dlc2/gc_icon_squid","rui/gencard_icons/dlc2/gc_icon_squid_small",0
+"gc_icon_threebullets","#PATCH_THREEBULLETS","rui/gencard_icons/dlc2/gc_icon_threebullets","rui/gencard_icons/dlc2/gc_icon_threebullets_small",0
+"gc_icon_tick","#PATCH_TICK","rui/gencard_icons/dlc2/gc_icon_tick","rui/gencard_icons/dlc2/gc_icon_tick_small",0
+"gc_icon_buzzsaw","#PATCH_BUZZSAW","rui/gencard_icons/dlc3/gc_icon_buzzsaw","rui/gencard_icons/dlc3/gc_icon_buzzsaw_small",0
+"gc_icon_crossed_lighting","#PATCH_CROSSED_LIGHTING","rui/gencard_icons/dlc3/gc_icon_crossed_lighting","rui/gencard_icons/dlc3/gc_icon_crossed_lighting_small",0
+"gc_icon_flying_bullet","#PATCH_FLYING_BULLET","rui/gencard_icons/dlc3/gc_icon_flying_bullet","rui/gencard_icons/dlc3/gc_icon_flying_bullet_small",0
+"gc_icon_hammer2","#PATCH_HAMMER2","rui/gencard_icons/dlc3/gc_icon_hammer","rui/gencard_icons/dlc3/gc_icon_hammer_small",0
+"gc_icon_keyboard","#PATCH_KEYBOARD","rui/gencard_icons/dlc3/gc_icon_keyboard","rui/gencard_icons/dlc3/gc_icon_keyboard_small",0
+"gc_icon_lightbulb","#PATCH_LIGHTBULB","rui/gencard_icons/dlc3/gc_icon_lightbulb","rui/gencard_icons/dlc3/gc_icon_lightbulb_small",0
+"gc_icon_narwhal","#PATCH_NARWHAL","rui/gencard_icons/dlc3/gc_icon_narwhal","rui/gencard_icons/dlc3/gc_icon_narwhal_small",0
+"gc_icon_robot_eye","#PATCH_ROBOT_EYE","rui/gencard_icons/dlc3/gc_icon_robot_eye","rui/gencard_icons/dlc3/gc_icon_robot_eye_small",0
+"gc_icon_taco","#PATCH_TACO","rui/gencard_icons/dlc3/gc_icon_taco","rui/gencard_icons/dlc3/gc_icon_taco_small",0
+"gc_icon_treble","#PATCH_TREBLE","rui/gencard_icons/dlc3/gc_icon_treble","rui/gencard_icons/dlc3/gc_icon_treble_small",0
+"gc_icon_monarch","#PATCH_MONARCH","rui/gencard_icons/dlc4/gc_icon_monarch","rui/gencard_icons/dlc4/gc_icon_monarch_small",0
+"gc_icon_mrvn","#PATCH_MRVN","rui/gencard_icons/dlc4/gc_icon_mrvn","rui/gencard_icons/dlc4/gc_icon_mrvn_small",0
+"gc_icon_blank","#PATCH_BLANK","rui/gencard_icons/gc_icon_blank","rui/gencard_icons/gc_icon_blank_small",0
+"gc_icon_monarch_dlc5","#PATCH_MONARCH_DLC5","rui/gencard_icons/dlc5/gc_icon_monarch","rui/gencard_icons/dlc5/gc_icon_monarch_small",0
+"gc_icon_militia","#PATCH_MILITIA","rui/gencard_icons/dlc5/gc_icon_militia","rui/gencard_icons/dlc5/gc_icon_militia_small",0
+"gc_icon_militia_alt","#PATCH_MILITIA_ALT","rui/gencard_icons/dlc5/gc_icon_militia_alt","rui/gencard_icons/dlc5/gc_icon_militia_alt_small",0
+"gc_icon_imc","#PATCH_IMC","rui/gencard_icons/dlc5/gc_icon_imc","rui/gencard_icons/dlc5/gc_icon_imc_small",0
+"gc_icon_hammond","#PATCH_HAMMOND","rui/gencard_icons/dlc5/gc_icon_hammond","rui/gencard_icons/dlc5/gc_icon_hammond_small",0
+"gc_icon_tri_chevron","#PATCH_TRI_CHEVRON","rui/gencard_icons/dlc5/gc_icon_tri_chevron","rui/gencard_icons/dlc5/gc_icon_tri_chevron_small",0
+"gc_icon_pilot_circle","#PATCH_PILOT_CIRCLE","rui/gencard_icons/dlc5/gc_icon_pilot_circle","rui/gencard_icons/dlc5/gc_icon_pilot_circle_small",0
+"gc_icon_x","#PATCH_X","rui/gencard_icons/dlc5/gc_icon_x","rui/gencard_icons/dlc5/gc_icon_x_small",0
+"gc_icon_nessie","#PATCH_NESSIE","rui/gencard_icons/dlc5/gc_icon_nessie","rui/gencard_icons/dlc5/gc_icon_nessie_small",0
+"gc_icon_spicy","#PATCH_SPICY","rui/gencard_icons/dlc5/gc_icon_spicy","rui/gencard_icons/dlc5/gc_icon_spicy_small",0
+"gc_icon_crown","#PATCH_CROWN","rui/gencard_icons/dlc5/gc_icon_crown","rui/gencard_icons/dlc5/gc_icon_crown_small",0
+"gc_icon_pawn","#PATCH_PAWN","rui/gencard_icons/dlc5/gc_icon_pawn","rui/gencard_icons/dlc5/gc_icon_pawn_small",0
+"gc_icon_excite","#PATCH_EXCITE","rui/gencard_icons/dlc5/gc_icon_excite","rui/gencard_icons/dlc5/gc_icon_excite_small",0
+"gc_icon_duck","#PATCH_DUCK","rui/gencard_icons/dlc5/gc_icon_duck","rui/gencard_icons/dlc5/gc_icon_duck_small",0
+"gc_icon_sock","#PATCH_SOCK","rui/gencard_icons/dlc5/gc_icon_sock","rui/gencard_icons/dlc5/gc_icon_sock_small",0
+"gc_icon_rabbit","#PATCH_RABBIT","rui/gencard_icons/dlc5/gc_icon_rabbit","rui/gencard_icons/dlc5/gc_icon_rabbit_small",0
+"gc_icon_peanut","#PATCH_PEANUT","rui/gencard_icons/dlc5/gc_icon_peanut","rui/gencard_icons/dlc5/gc_icon_peanut_small",0
+"gc_icon_clock","#PATCH_CLOCK","rui/gencard_icons/dlc5/gc_icon_clock","rui/gencard_icons/dlc5/gc_icon_clock_small",0
+"gc_icon_shamrock","#PATCH_SHAMROCK","rui/gencard_icons/dlc5/gc_icon_shamrock","rui/gencard_icons/dlc5/gc_icon_shamrock_small",0
+"gc_icon_trident","#PATCH_TRIDENT","rui/gencard_icons/dlc5/gc_icon_trident","rui/gencard_icons/dlc5/gc_icon_trident_small",0
+"gc_icon_fd_normal","#PATCH_FD_NORMAL","rui/gencard_icons/fd/gc_icon_fd_normal","rui/gencard_icons/fd/gc_icon_fd_normal_small",0
+"gc_icon_fd_hard","#PATCH_FD_HARD","rui/gencard_icons/fd/gc_icon_fd_hard","rui/gencard_icons/fd/gc_icon_fd_hard_small",0
+"gc_icon_fd_master","#PATCH_FD_MASTER","rui/gencard_icons/fd/gc_icon_fd_master","rui/gencard_icons/fd/gc_icon_fd_master_small",0
+"gc_icon_fd_insane","#PATCH_FD_INSANE","rui/gencard_icons/fd/gc_icon_fd_insane","rui/gencard_icons/fd/gc_icon_fd_insane_small",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/camo_skins.csv b/Northstar.CustomServers/mod/scripts/datatable/camo_skins.csv new file mode 100644 index 00000000..2773f4b6 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/camo_skins.csv @@ -0,0 +1,161 @@ +itemRef,pilotRef,titanRef,type,image,name,description,pilotCost,titanCost,pilotWeaponCost,titanWeaponCost,category
+"camo_skin00","pilot_camo_skin00","titan_camo_skin00","CAMO","rui/menu/common/no_art","#CAMO_DEFAULT","#DEFAULT_DESC",0,0,0,0,1
+"camo_skin01","pilot_camo_skin01","titan_camo_skin01","CAMO","models/camo_skins/camo_skin01_col","#CAMO_SKIN_01","#CAMO_SKIN_01_DESC",0,0,0,0,1
+"camo_skin02","pilot_camo_skin02","titan_camo_skin02","CAMO","models/camo_skins/camo_skin02_col","#CAMO_SKIN_02","#CAMO_SKIN_02_DESC",0,0,0,0,1
+"camo_skin03","pilot_camo_skin03","titan_camo_skin03","CAMO","models/camo_skins/camo_skin03_col","#CAMO_SKIN_03","#CAMO_SKIN_03_DESC",0,0,0,0,1
+"camo_skin04","pilot_camo_skin04","titan_camo_skin04","CAMO","models/camo_skins/camo_skin04_col","#CAMO_SKIN_04","#CAMO_SKIN_04_DESC",150,100,75,50,3
+"camo_skin05","pilot_camo_skin05","titan_camo_skin05","CAMO","models/camo_skins/camo_skin05_col","#CAMO_SKIN_05","#CAMO_SKIN_05_DESC",150,100,75,50,3
+"camo_skin06","pilot_camo_skin06","titan_camo_skin06","CAMO","models/camo_skins/camo_skin06_col","#CAMO_SKIN_06","#CAMO_SKIN_06_DESC",150,100,75,50,4
+"camo_skin07","pilot_camo_skin07","titan_camo_skin07","CAMO","models/camo_skins/camo_skin07_col","#CAMO_SKIN_07","#CAMO_SKIN_07_DESC",0,0,0,0,2
+"camo_skin08","pilot_camo_skin08","titan_camo_skin08","CAMO","models/camo_skins/camo_skin08_col","#CAMO_SKIN_08","#CAMO_SKIN_08_DESC",150,100,75,50,4
+"camo_skin09","pilot_camo_skin09","titan_camo_skin09","CAMO","models/camo_skins/camo_skin09_col","#CAMO_SKIN_09","#CAMO_SKIN_09_DESC",0,0,0,0,1
+"camo_skin10","pilot_camo_skin10","titan_camo_skin10","CAMO","models/camo_skins/camo_skin10_col","#CAMO_SKIN_10","#CAMO_SKIN_10_DESC",0,0,0,0,1
+"camo_skin11","pilot_camo_skin11","titan_camo_skin11","CAMO","models/camo_skins/camo_skin11_col","#CAMO_SKIN_11","#CAMO_SKIN_11_DESC",150,100,75,50,4
+"camo_skin12","pilot_camo_skin12","titan_camo_skin12","CAMO","models/camo_skins/camo_skin12_col","#CAMO_SKIN_12","#CAMO_SKIN_12_DESC",150,100,75,50,4
+"camo_skin13","pilot_camo_skin13","titan_camo_skin13","CAMO","models/camo_skins/camo_skin13_col","#CAMO_SKIN_13","#CAMO_SKIN_13_DESC",0,0,0,0,2
+"camo_skin14","pilot_camo_skin14","titan_camo_skin14","CAMO","models/camo_skins/camo_skin14_col","#CAMO_SKIN_14","#CAMO_SKIN_14_DESC",0,0,0,0,1
+"camo_skin15","pilot_camo_skin15","titan_camo_skin15","CAMO","models/camo_skins/camo_skin15_col","#CAMO_SKIN_15","#CAMO_SKIN_15_DESC",0,0,0,0,1
+"camo_skin16","pilot_camo_skin16","titan_camo_skin16","CAMO","models/camo_skins/camo_skin16_col","#CAMO_SKIN_16","#CAMO_SKIN_16_DESC",0,0,0,0,1
+"camo_skin17","pilot_camo_skin17","titan_camo_skin17","CAMO","models/camo_skins/camo_skin17_col","#CAMO_SKIN_17","#CAMO_SKIN_17_DESC",0,0,0,0,1
+"camo_skin18","pilot_camo_skin18","titan_camo_skin18","CAMO","models/camo_skins/camo_skin18_col","#CAMO_SKIN_18","#CAMO_SKIN_18_DESC",0,0,0,0,1
+"camo_skin19","pilot_camo_skin19","titan_camo_skin19","CAMO","models/camo_skins/camo_skin19_col","#CAMO_SKIN_19","#CAMO_SKIN_19_DESC",0,0,0,0,1
+"camo_skin20","pilot_camo_skin20","titan_camo_skin20","CAMO","models/camo_skins/camo_skin20_col","#CAMO_SKIN_20","#CAMO_SKIN_20_DESC",150,100,75,50,3
+"camo_skin21","pilot_camo_skin21","titan_camo_skin21","CAMO","models/camo_skins/camo_skin21_col","#CAMO_SKIN_21","#CAMO_SKIN_21_DESC",150,100,75,50,3
+"camo_skin22","pilot_camo_skin22","titan_camo_skin22","CAMO","models/camo_skins/camo_skin22_col","#CAMO_SKIN_22","#CAMO_SKIN_22_DESC",150,100,75,50,3
+"camo_skin23","pilot_camo_skin23","titan_camo_skin23","CAMO","models/camo_skins/camo_skin23_col","#CAMO_SKIN_23","#CAMO_SKIN_23_DESC",150,100,75,50,3
+"camo_skin24","pilot_camo_skin24","titan_camo_skin24","CAMO","models/camo_skins/camo_skin24_col","#CAMO_SKIN_24","#CAMO_SKIN_24_DESC",0,0,0,0,1
+"camo_skin25","pilot_camo_skin25","titan_camo_skin25","CAMO","models/camo_skins/camo_skin25_col","#CAMO_SKIN_25","#CAMO_SKIN_25_DESC",0,0,0,0,1
+"camo_skin26","pilot_camo_skin26","titan_camo_skin26","CAMO","models/camo_skins/camo_skin26_col","#CAMO_SKIN_26","#CAMO_SKIN_26_DESC",0,0,0,0,1
+"camo_skin27","pilot_camo_skin27","titan_camo_skin27","CAMO","models/camo_skins/camo_skin27_col","#CAMO_SKIN_27","#CAMO_SKIN_27_DESC",0,0,0,0,1
+"camo_skin28","pilot_camo_skin28","titan_camo_skin28","CAMO","models/camo_skins/camo_skin28_col","#CAMO_SKIN_28","#CAMO_SKIN_28_DESC",150,100,75,50,4
+"camo_skin29","pilot_camo_skin29","titan_camo_skin29","CAMO","models/camo_skins/camo_skin29_col","#CAMO_SKIN_29","#CAMO_SKIN_29_DESC",150,100,75,50,4
+"camo_skin30","pilot_camo_skin30","titan_camo_skin30","CAMO","models/camo_skins/camo_skin30_col","#CAMO_SKIN_30","#CAMO_SKIN_30_DESC",0,0,0,0,1
+"camo_skin31","pilot_camo_skin31","titan_camo_skin31","CAMO","models/camo_skins/camo_skin31_col","#CAMO_SKIN_31","#CAMO_SKIN_31_DESC",0,0,0,0,1
+"camo_skin32","pilot_camo_skin32","titan_camo_skin32","CAMO","models/camo_skins/camo_skin32_col","#CAMO_SKIN_32","#CAMO_SKIN_32_DESC",150,100,75,50,4
+"camo_skin33","pilot_camo_skin33","titan_camo_skin33","CAMO","models/camo_skins/camo_skin33_col","#CAMO_SKIN_33","#CAMO_SKIN_33_DESC",150,100,75,50,4
+"camo_skin34","pilot_camo_skin34","titan_camo_skin34","CAMO","models/camo_skins/camo_skin34_col","#CAMO_SKIN_34","#CAMO_SKIN_34_DESC",150,100,75,50,4
+"camo_skin35","pilot_camo_skin35","titan_camo_skin35","CAMO","models/camo_skins/camo_skin35_col","#CAMO_SKIN_35","#CAMO_SKIN_35_DESC",150,100,75,50,3
+"camo_skin36","pilot_camo_skin36","titan_camo_skin36","CAMO","models/camo_skins/camo_skin36_col","#CAMO_SKIN_36","#CAMO_SKIN_36_DESC",150,100,75,50,3
+"camo_skin37","pilot_camo_skin37","titan_camo_skin37","CAMO","models/camo_skins/camo_skin37_col","#CAMO_SKIN_37","#CAMO_SKIN_37_DESC",150,100,75,50,4
+"camo_skin38","pilot_camo_skin38","titan_camo_skin38","CAMO","models/camo_skins/camo_skin38_col","#CAMO_SKIN_38","#CAMO_SKIN_38_DESC",150,100,75,50,4
+"camo_skin39","pilot_camo_skin39","titan_camo_skin39","CAMO","models/camo_skins/camo_skin39_col","#CAMO_SKIN_39","#CAMO_SKIN_39_DESC",150,100,75,50,4
+"camo_skin40","pilot_camo_skin40","titan_camo_skin40","CAMO","models/camo_skins/camo_skin40_col","#CAMO_SKIN_40","#CAMO_SKIN_40_DESC",150,100,75,50,3
+"camo_skin41","pilot_camo_skin41","titan_camo_skin41","CAMO","models/camo_skins/camo_skin41_col","#CAMO_SKIN_41","#CAMO_SKIN_41_DESC",150,100,75,50,3
+"camo_skin42","pilot_camo_skin42","titan_camo_skin42","CAMO","models/camo_skins/camo_skin42_col","#CAMO_SKIN_42","#CAMO_SKIN_42_DESC",150,100,75,50,3
+"camo_skin43","pilot_camo_skin43","titan_camo_skin43","CAMO","models/camo_skins/camo_skin43_col","#CAMO_SKIN_43","#CAMO_SKIN_43_DESC",150,100,75,50,3
+"camo_skin44","pilot_camo_skin44","titan_camo_skin44","CAMO","models/camo_skins/camo_skin44_col","#CAMO_SKIN_44","#CAMO_SKIN_44_DESC",150,100,75,50,3
+"camo_skin45","pilot_camo_skin45","titan_camo_skin45","CAMO","models/camo_skins/camo_skin45_col","#CAMO_SKIN_45","#CAMO_SKIN_45_DESC",150,100,75,50,3
+"camo_skin46","pilot_camo_skin46","titan_camo_skin46","CAMO","models/camo_skins/camo_skin46_col","#CAMO_SKIN_46","#CAMO_SKIN_46_DESC",150,100,75,50,3
+"camo_skin47","pilot_camo_skin47","titan_camo_skin47","CAMO","models/camo_skins/camo_skin47_col","#CAMO_SKIN_47","#CAMO_SKIN_47_DESC",150,100,75,50,4
+"camo_skin48","pilot_camo_skin48","titan_camo_skin48","CAMO","models/camo_skins/camo_skin48_col","#CAMO_SKIN_48","#CAMO_SKIN_48_DESC",150,100,75,50,4
+"camo_skin49","pilot_camo_skin49","titan_camo_skin49","CAMO","models/camo_skins/camo_skin49_col","#CAMO_SKIN_49","#CAMO_SKIN_49_DESC",150,100,75,50,4
+"camo_skin50","pilot_camo_skin50","titan_camo_skin50","CAMO","models/camo_skins/camo_skin50_col","#CAMO_SKIN_50","#CAMO_SKIN_50_DESC",150,100,75,50,4
+"camo_skin51","pilot_camo_skin51","titan_camo_skin51","CAMO","models/camo_skins/camo_skin51_col","#CAMO_SKIN_51","#CAMO_SKIN_51_DESC",150,100,75,50,4
+"camo_skin52","pilot_camo_skin52","titan_camo_skin52","CAMO","models/camo_skins/camo_skin52_col","#CAMO_SKIN_52","#CAMO_SKIN_52_DESC",150,100,75,50,4
+"camo_skin53","pilot_camo_skin53","titan_camo_skin53","CAMO","models/camo_skins/camo_skin53_col","#CAMO_SKIN_53","#CAMO_SKIN_53_DESC",150,100,75,50,4
+"camo_skin54","pilot_camo_skin54","titan_camo_skin54","CAMO","models/camo_skins/camo_skin54_col","#CAMO_SKIN_54","#CAMO_SKIN_54_DESC",150,100,75,50,4
+"camo_skin55","pilot_camo_skin55","titan_camo_skin55","CAMO","models/camo_skins/camo_skin55_col","#CAMO_SKIN_55","#CAMO_SKIN_55_DESC",0,0,0,0,2
+"camo_skin56","pilot_camo_skin56","titan_camo_skin56","CAMO","models/camo_skins/camo_skin56_col","#CAMO_SKIN_56","#CAMO_SKIN_56_DESC",0,0,0,0,2
+"camo_skin57","pilot_camo_skin57","titan_camo_skin57","CAMO","models/camo_skins/camo_skin57_col","#CAMO_SKIN_57","#CAMO_SKIN_57_DESC",0,0,0,0,2
+"camo_skin58","pilot_camo_skin58","titan_camo_skin58","CAMO","models/camo_skins/camo_skin58_col","#CAMO_SKIN_58","#CAMO_SKIN_58_DESC",0,0,0,0,2
+"camo_skin59","pilot_camo_skin59","titan_camo_skin59","CAMO","models/camo_skins/camo_skin59_col","#CAMO_SKIN_59","#CAMO_SKIN_59_DESC",0,0,0,0,2
+"camo_skin60","pilot_camo_skin60","titan_camo_skin60","CAMO","models/camo_skins/camo_skin60_col","#CAMO_SKIN_60","#CAMO_SKIN_60_DESC",0,0,0,0,2
+"camo_skin61","pilot_camo_skin61","titan_camo_skin61","CAMO","models/camo_skins/camo_skin61_col","#CAMO_SKIN_61","#CAMO_SKIN_61_DESC",0,0,0,0,2
+"camo_skin62","pilot_camo_skin62","titan_camo_skin62","CAMO","models/camo_skins/camo_skin62_col","#CAMO_SKIN_62","#CAMO_SKIN_62_DESC",0,0,0,0,2
+"camo_skin63","pilot_camo_skin63","titan_camo_skin63","CAMO","models/camo_skins/camo_skin63_col","#CAMO_SKIN_63","#CAMO_SKIN_63_DESC",0,0,0,0,2
+"camo_skin64","pilot_camo_skin64","titan_camo_skin64","CAMO","models/camo_skins/camo_skin64_col","#CAMO_SKIN_64","#CAMO_SKIN_64_DESC",0,0,0,0,2
+"camo_skin65","pilot_camo_skin65","titan_camo_skin65","CAMO","models/camo_skins/camo_skin65_col","#CAMO_SKIN_65","#CAMO_SKIN_65_DESC",0,0,0,0,2
+"camo_skin66","pilot_camo_skin66","titan_camo_skin66","CAMO","models/camo_skins/camo_skin66_col","#CAMO_SKIN_66","#CAMO_SKIN_66_DESC",0,0,0,0,2
+"camo_skin67","pilot_camo_skin67","titan_camo_skin67","CAMO","models/camo_skins/camo_skin67_col","#CAMO_SKIN_67","#CAMO_SKIN_67_DESC",0,0,0,0,2
+"camo_skin68","pilot_camo_skin68","titan_camo_skin68","CAMO","models/camo_skins/camo_skin68_col","#CAMO_SKIN_68","#CAMO_SKIN_68_DESC",150,100,75,50,4
+"camo_skin69","pilot_camo_skin69","titan_camo_skin69","CAMO","models/camo_skins/camo_skin69_col","#CAMO_SKIN_69","#CAMO_SKIN_69_DESC",150,100,75,50,4
+"camo_skin70","pilot_camo_skin70","titan_camo_skin70","CAMO","models/camo_skins/camo_skin70_col","#CAMO_SKIN_70","#CAMO_SKIN_70_DESC",150,100,75,50,4
+"camo_skin71","pilot_camo_skin71","titan_camo_skin71","CAMO","models/camo_skins/camo_skin71_col","#CAMO_SKIN_71","#CAMO_SKIN_71_DESC",150,100,75,50,4
+"camo_skin72","pilot_camo_skin72","titan_camo_skin72","CAMO","models/camo_skins/camo_skin72_col","#CAMO_SKIN_72","#CAMO_SKIN_72_DESC",150,100,75,50,4
+"camo_skin73","pilot_camo_skin73","titan_camo_skin73","CAMO","models/camo_skins/camo_skin73_col","#CAMO_SKIN_73","#CAMO_SKIN_73_DESC",150,100,75,50,4
+"camo_skin74","pilot_camo_skin74","titan_camo_skin74","CAMO","models/camo_skins/camo_skin74_col","#CAMO_SKIN_74","#CAMO_SKIN_74_DESC",150,100,75,50,4
+"camo_skin75","pilot_camo_skin75","titan_camo_skin75","CAMO","models/camo_skins/camo_skin75_col","#CAMO_SKIN_75","#CAMO_SKIN_75_DESC",150,100,75,50,4
+"camo_skin76","pilot_camo_skin76","titan_camo_skin76","CAMO","models/camo_skins/camo_skin76_col","#CAMO_SKIN_76","#CAMO_SKIN_76_DESC",150,100,75,50,3
+"camo_skin77","pilot_camo_skin77","titan_camo_skin77","CAMO","models/camo_skins/camo_skin77_col","#CAMO_SKIN_77","#CAMO_SKIN_77_DESC",150,100,75,50,3
+"camo_skin78","pilot_camo_skin78","titan_camo_skin78","CAMO","models/camo_skins/camo_skin78_col","#CAMO_SKIN_78","#CAMO_SKIN_78_DESC",150,100,75,50,3
+"camo_skin79","pilot_camo_skin79","titan_camo_skin79","CAMO","models/camo_skins/camo_skin79_col","#CAMO_SKIN_79","#CAMO_SKIN_79_DESC",150,100,75,50,3
+"camo_skin80","pilot_camo_skin80","titan_camo_skin80","CAMO","models/camo_skins/camo_skin80_col","#CAMO_SKIN_80","#CAMO_SKIN_80_DESC",150,100,75,50,3
+"camo_skin81","pilot_camo_skin81","titan_camo_skin81","CAMO","models/camo_skins/camo_skin81_col","#CAMO_SKIN_81","#CAMO_SKIN_81_DESC",0,0,0,0,1
+"camo_skin82","pilot_camo_skin82","titan_camo_skin82","CAMO","models/camo_skins/camo_skin82_col","#CAMO_SKIN_82","#CAMO_SKIN_82_DESC",0,0,0,0,1
+"camo_skin83","pilot_camo_skin83","titan_camo_skin83","CAMO","models/camo_skins/camo_skin83_col","#CAMO_SKIN_83","#CAMO_SKIN_83_DESC",0,0,0,0,1
+"camo_skin84","pilot_camo_skin84","titan_camo_skin84","CAMO","models/camo_skins/camo_skin84_col","#CAMO_SKIN_84","#CAMO_SKIN_84_DESC",150,100,75,50,4
+"camo_skin85","pilot_camo_skin85","titan_camo_skin85","CAMO","models/camo_skins/camo_skin85_col","#CAMO_SKIN_85","#CAMO_SKIN_85_DESC",0,0,0,0,2
+"camo_skin86","pilot_camo_skin86","titan_camo_skin86","CAMO","models/camo_skins/camo_skin86_col","#CAMO_SKIN_86","#CAMO_SKIN_86_DESC",150,100,75,50,4
+"camo_skin87","pilot_camo_skin87","titan_camo_skin87","CAMO","models/camo_skins/camo_skin87_col","#CAMO_SKIN_87","#CAMO_SKIN_87_DESC",0,0,0,0,2
+"camo_skin88","pilot_camo_skin88","titan_camo_skin88","CAMO","models/camo_skins/camo_skin88_col","#CAMO_SKIN_88","#CAMO_SKIN_88_DESC",150,100,75,50,4
+"camo_skin89","pilot_camo_skin89","titan_camo_skin89","CAMO","models/camo_skins/camo_skin89_col","#CAMO_SKIN_89","#CAMO_SKIN_89_DESC",150,100,75,50,4
+"camo_skin90","pilot_camo_skin90","titan_camo_skin90","CAMO","models/camo_skins/camo_skin90_col","#CAMO_SKIN_90","#CAMO_SKIN_90_DESC",150,100,75,50,4
+"camo_skin91","pilot_camo_skin91","titan_camo_skin91","CAMO","models/camo_skins/camo_skin91_col","#CAMO_SKIN_91","#CAMO_SKIN_91_DESC",0,0,0,0,2
+"camo_skin92","pilot_camo_skin92","titan_camo_skin92","CAMO","models/camo_skins/camo_skin92_col","#CAMO_SKIN_92","#CAMO_SKIN_92_DESC",0,0,0,0,1
+"camo_skin93","pilot_camo_skin93","titan_camo_skin93","CAMO","models/camo_skins/camo_skin93_col","#CAMO_SKIN_93","#CAMO_SKIN_93_DESC",0,0,0,0,2
+"camo_skin94","pilot_camo_skin94","titan_camo_skin94","CAMO","models/camo_skins/camo_skin94_col","#CAMO_SKIN_94","#CAMO_SKIN_94_DESC",0,0,0,0,2
+"camo_skin95","pilot_camo_skin95","titan_camo_skin95","CAMO","models/camo_skins/camo_skin95_col","#CAMO_SKIN_95","#CAMO_SKIN_95_DESC",150,100,75,50,4
+"camo_skin96","pilot_camo_skin96","titan_camo_skin96","CAMO","models/camo_skins/camo_skin96_col","#CAMO_SKIN_96","#CAMO_SKIN_96_DESC",150,100,75,50,4
+"camo_skin97","pilot_camo_skin97","titan_camo_skin97","CAMO","models/camo_skins/camo_skin97_col","#CAMO_SKIN_97","#CAMO_SKIN_97_DESC",0,0,0,0,1
+"camo_skin98","pilot_camo_skin98","titan_camo_skin98","CAMO","models/camo_skins/camo_skin98_col","#CAMO_SKIN_98","#CAMO_SKIN_98_DESC",150,100,75,50,4
+"camo_skin99","pilot_camo_skin99","titan_camo_skin99","CAMO","models/camo_skins/camo_skin99_col","#CAMO_SKIN_99","#CAMO_SKIN_99_DESC",150,100,75,50,4
+"camo_skin101","pilot_camo_skin101","titan_camo_skin101","CAMO","models/camo_skins/camo_skin101_col","#CAMO_SKIN_101","#CAMO_SKIN_101_DESC",0,0,0,0,5
+"camo_skin102","pilot_camo_skin102","titan_camo_skin102","CAMO","models/camo_skins/camo_skin102_col","#CAMO_SKIN_102","#CAMO_SKIN_102_DESC",0,0,0,0,5
+"camo_skin103","pilot_camo_skin103","titan_camo_skin103","CAMO","models/camo_skins/camo_skin103_col","#CAMO_SKIN_103","#CAMO_SKIN_103_DESC",0,0,0,0,5
+"camo_skin104","pilot_camo_skin104","titan_camo_skin104","CAMO","models/camo_skins/camo_skin104_col","#CAMO_SKIN_104","#CAMO_SKIN_104_DESC",0,0,0,0,5
+"camo_skin105","pilot_camo_skin105","titan_camo_skin105","CAMO","models/camo_skins/camo_skin105_col","#CAMO_SKIN_105","#CAMO_SKIN_105_DESC",0,0,0,0,5
+"camo_skin106","pilot_camo_skin106","titan_camo_skin106","CAMO","models/camo_skins/camo_skin106_col","#CAMO_SKIN_106","#CAMO_SKIN_106_DESC",0,0,0,0,5
+"camo_skin107","pilot_camo_skin107","titan_camo_skin107","CAMO","models/camo_skins/camo_skin107_col","#CAMO_SKIN_107","#CAMO_SKIN_107_DESC",0,0,0,0,5
+"camo_skin108","pilot_camo_skin108","titan_camo_skin108","CAMO","models/camo_skins/camo_skin108_col","#CAMO_SKIN_108","#CAMO_SKIN_108_DESC",0,0,0,0,5
+"camo_skin109","pilot_camo_skin109","titan_camo_skin109","CAMO","models/camo_skins/camo_skin109_col","#CAMO_SKIN_109","#CAMO_SKIN_109_DESC",0,0,0,0,5
+"camo_skin110","pilot_camo_skin110","titan_camo_skin110","CAMO","models/camo_skins/camo_skin110_col","#CAMO_SKIN_110","#CAMO_SKIN_110_DESC",0,0,0,0,5
+"camo_skin111","pilot_camo_skin111","titan_camo_skin111","CAMO","models/camo_skins/camo_skin111_col","#CAMO_SKIN_111","#CAMO_SKIN_111_DESC",0,0,0,0,5
+"camo_skin112","pilot_camo_skin112","titan_camo_skin112","CAMO","models/camo_skins/camo_skin112_col","#CAMO_SKIN_112","#CAMO_SKIN_112_DESC",0,0,0,0,5
+"camo_skin113","pilot_camo_skin113","titan_camo_skin113","CAMO","models/camo_skins/camo_skin113_col","#CAMO_SKIN_113","#CAMO_SKIN_113_DESC",0,0,0,0,5
+"camo_skin114","pilot_camo_skin114","titan_camo_skin114","CAMO","models/camo_skins/camo_skin114_col","#CAMO_SKIN_114","#CAMO_SKIN_114_DESC",0,0,0,0,5
+"camo_skin115","pilot_camo_skin115","titan_camo_skin115","CAMO","models/camo_skins/camo_skin115_col","#CAMO_SKIN_115","#CAMO_SKIN_115_DESC",0,0,0,0,5
+"camo_skin116","pilot_camo_skin116","titan_camo_skin116","CAMO","models/camo_skins/camo_skin116_col","#CAMO_SKIN_116","#CAMO_SKIN_116_DESC",0,0,0,0,5
+"camo_skin117","pilot_camo_skin117","titan_camo_skin117","CAMO","models/camo_skins/camo_skin117_col","#CAMO_SKIN_117","#CAMO_SKIN_117_DESC",0,0,0,0,5
+"camo_skin118","pilot_camo_skin118","titan_camo_skin118","CAMO","models/camo_skins/camo_skin118_col","#CAMO_SKIN_118","#CAMO_SKIN_118_DESC",0,0,0,0,5
+"camo_skin119","pilot_camo_skin119","titan_camo_skin119","CAMO","models/camo_skins/camo_skin119_col","#CAMO_SKIN_119","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin120","pilot_camo_skin120","titan_camo_skin120","CAMO","models/camo_skins/camo_skin120_col","#CAMO_SKIN_120","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin121","pilot_camo_skin121","titan_camo_skin121","CAMO","models/camo_skins/camo_skin121_col","#CAMO_SKIN_121","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin122","pilot_camo_skin122","titan_camo_skin122","CAMO","models/camo_skins/camo_skin122_col","#CAMO_SKIN_122","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin123","pilot_camo_skin123","titan_camo_skin123","CAMO","models/camo_skins/camo_skin123_col","#CAMO_SKIN_123","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin124","pilot_camo_skin124","titan_camo_skin124","CAMO","models/camo_skins/camo_skin124_col","#CAMO_SKIN_124","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin125","pilot_camo_skin125","titan_camo_skin125","CAMO","models/camo_skins/camo_skin125_col","#CAMO_SKIN_125","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin126","pilot_camo_skin126","titan_camo_skin126","CAMO","models/camo_skins/camo_skin126_col","#CAMO_SKIN_126","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin127","pilot_camo_skin127","titan_camo_skin127","CAMO","models/camo_skins/camo_skin127_col","#CAMO_SKIN_127","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin128","pilot_camo_skin128","titan_camo_skin128","CAMO","models/camo_skins/camo_skin128_col","#CAMO_SKIN_128","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin129","pilot_camo_skin129","titan_camo_skin129","CAMO","models/camo_skins/camo_skin129_col","#CAMO_SKIN_129","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin130","pilot_camo_skin130","titan_camo_skin130","CAMO","models/camo_skins/camo_skin130_col","#CAMO_SKIN_130","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin131","pilot_camo_skin131","titan_camo_skin131","CAMO","models/camo_skins/camo_skin131_col","#CAMO_SKIN_131","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin132","pilot_camo_skin132","titan_camo_skin132","CAMO","models/camo_skins/camo_skin132_col","#CAMO_SKIN_132","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin133","pilot_camo_skin133","titan_camo_skin133","CAMO","models/camo_skins/camo_skin133_col","#CAMO_SKIN_133","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin134","pilot_camo_skin134","titan_camo_skin134","CAMO","models/camo_skins/camo_skin134_col","#CAMO_SKIN_134","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin135","pilot_camo_skin135","titan_camo_skin135","CAMO","models/camo_skins/camo_skin135_col","#CAMO_SKIN_135","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin136","pilot_camo_skin136","titan_camo_skin136","CAMO","models/camo_skins/camo_skin136_col","#CAMO_SKIN_136","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin137","pilot_camo_skin137","titan_camo_skin137","CAMO","models/camo_skins/camo_skin137_col","#CAMO_SKIN_137","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin138","pilot_camo_skin138","titan_camo_skin138","CAMO","models/camo_skins/camo_skin138_col","#CAMO_SKIN_138","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin139","pilot_camo_skin139","titan_camo_skin139","CAMO","models/camo_skins/camo_skin139_col","#CAMO_SKIN_139","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin140","pilot_camo_skin140","titan_camo_skin140","CAMO","models/camo_skins/camo_skin140_col","#CAMO_SKIN_140","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin141","pilot_camo_skin141","titan_camo_skin141","CAMO","models/camo_skins/camo_skin141_col","#CAMO_SKIN_141","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin142","pilot_camo_skin142","titan_camo_skin142","CAMO","models/camo_skins/camo_skin142_col","#CAMO_SKIN_142","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin143","pilot_camo_skin143","titan_camo_skin143","CAMO","models/camo_skins/camo_skin143_col","#CAMO_SKIN_143","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin144","pilot_camo_skin144","titan_camo_skin144","CAMO","models/camo_skins/camo_skin144_col","#CAMO_SKIN_144","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin145","pilot_camo_skin145","titan_camo_skin145","CAMO","models/camo_skins/camo_skin145_col","#CAMO_SKIN_145","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin146","pilot_camo_skin146","titan_camo_skin146","CAMO","models/camo_skins/camo_skin146_col","#CAMO_SKIN_146","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin147","pilot_camo_skin147","titan_camo_skin147","CAMO","models/camo_skins/camo_skin147_col","#CAMO_SKIN_147","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin148","pilot_camo_skin148","titan_camo_skin148","CAMO","models/camo_skins/camo_skin148_col","#CAMO_SKIN_148","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin149","pilot_camo_skin149","titan_camo_skin149","CAMO","models/camo_skins/camo_skin149_col","#CAMO_SKIN_149","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin150","pilot_camo_skin150","titan_camo_skin150","CAMO","models/camo_skins/camo_skin150_col","#CAMO_SKIN_150","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin151","pilot_camo_skin151","titan_camo_skin151","CAMO","models/camo_skins/camo_skin151_col","#CAMO_SKIN_151","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin152","pilot_camo_skin152","titan_camo_skin152","CAMO","models/camo_skins/camo_skin152_col","#CAMO_SKIN_152","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin153","pilot_camo_skin153","titan_camo_skin153","CAMO","models/camo_skins/camo_skin153_col","#CAMO_SKIN_153","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin154","pilot_camo_skin154","titan_camo_skin154","CAMO","models/camo_skins/camo_skin154_col","#CAMO_SKIN_154","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin155","pilot_camo_skin155","titan_camo_skin155","CAMO","models/camo_skins/camo_skin155_col","#CAMO_SKIN_155","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin156","pilot_camo_skin156","titan_camo_skin156","CAMO","models/camo_skins/camo_skin156_col","#CAMO_SKIN_156","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin157","pilot_camo_skin157","titan_camo_skin157","CAMO","models/camo_skins/camo_skin157_col","#CAMO_SKIN_157","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin158","pilot_camo_skin158","titan_camo_skin158","CAMO","models/camo_skins/camo_skin158_col","#CAMO_SKIN_158","#CAMO_SKIN_120_DESC",0,0,0,0,5
+"camo_skin159","pilot_camo_skin159","titan_camo_skin159","CAMO","models/camo_skins/camo_skin159_col","#CAMO_SKIN_159","#CAMO_SKIN_119_DESC",0,0,0,0,5
+"camo_skin160","pilot_camo_skin160","titan_camo_skin160","CAMO","models/camo_skins/camo_skin160_col","#CAMO_SKIN_160","#CAMO_SKIN_120_DESC",0,0,0,0,5
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/community_entries.csv b/Northstar.CustomServers/mod/scripts/datatable/community_entries.csv new file mode 100644 index 00000000..0616f131 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/community_entries.csv @@ -0,0 +1,22 @@ +category,key,locString
+"categories","gaming","#COMMUNITY_CATEGORY_GAMING"
+"categories","lifestyle","#COMMUNITY_CATEGORY_LIFESTYLE"
+"categories","geography","#COMMUNITY_CATEGORY_GEOGRAPHY"
+"categories","tech","#COMMUNITY_CATEGORY_TECH"
+"categories","other","#COMMUNITY_CATEGORY_OTHER"
+"regions","North America","#COMMUNITY_REGION_NORTHAMERICA"
+"regions","Europe","#COMMUNITY_REGION_EUROPE"
+"regions","South America","#COMMUNITY_REGION_SOUTHAMERICA"
+"regions","Asia","#COMMUNITY_REGION_ASIA"
+"regions","Oceania","#COMMUNITY_REGION_AUSTRALIA"
+"languages","English","#COMMUNITY_LANGUAGE_ENGLISH"
+"languages","French","#COMMUNITY_LANGUAGE_FRENCH"
+"languages","Italian","#COMMUNITY_LANGUAGE_ITALIAN"
+"languages","German","#COMMUNITY_LANGUAGE_GERMAN"
+"languages","Spanish","#COMMUNITY_LANGUAGE_SPANISH"
+"languages","MSpanish","#COMMUNITY_LANGUAGE_MSPANISH"
+"languages","Japanese","#COMMUNITY_LANGUAGE_JAPANESE"
+"languages","TChinese","#COMMUNITY_LANGUAGE_TCHINESE"
+"languages","Russian","#COMMUNITY_LANGUAGE_RUSSIAN"
+"languages","Portuguese","#COMMUNITY_LANGUAGE_PORTUGUESE"
+"languages","Polish","#COMMUNITY_LANGUAGE_POLISH"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/death_hints_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/death_hints_mp.csv new file mode 100644 index 00000000..4388ab0f --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/death_hints_mp.csv @@ -0,0 +1,381 @@ +source,className,locString,mapName,gameMode
+"titan_class","ion","#DEATH_HINT_ION_001","",""
+"titan_class","ion","#DEATH_HINT_ION_002","",""
+"titan_class","ion","#DEATH_HINT_ION_003","",""
+"titan_class","ion","#DEATH_HINT_ION_004","",""
+"titan_class","ion","#DEATH_HINT_ION_005","",""
+"titan_class","ion","#DEATH_HINT_ION_006","",""
+"titan_class","legion","#DEATH_HINT_LEGION_001","",""
+"titan_class","legion","#DEATH_HINT_LEGION_002","",""
+"titan_class","legion","#DEATH_HINT_LEGION_003","",""
+"titan_class","legion","#DEATH_HINT_LEGION_004","",""
+"titan_class","legion","#DEATH_HINT_LEGION_005","",""
+"titan_class","legion","#DEATH_HINT_LEGION_006","",""
+"titan_class","northstar","#DEATH_HINT_NORTHSTAR_001","",""
+"titan_class","northstar","#DEATH_HINT_NORTHSTAR_002","",""
+"titan_class","northstar","#DEATH_HINT_NORTHSTAR_003","",""
+"titan_class","northstar","#DEATH_HINT_NORTHSTAR_004","",""
+"titan_class","northstar","#DEATH_HINT_NORTHSTAR_005","",""
+"titan_class","northstar","#DEATH_HINT_NORTHSTAR_006","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_001","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_002","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_003","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_004","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_005","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_006","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_007","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_008","",""
+"titan_class","ronin","#DEATH_HINT_RONIN_009","",""
+"titan_class","scorch","#DEATH_HINT_SCORCH_001","",""
+"titan_class","scorch","#DEATH_HINT_SCORCH_002","",""
+"titan_class","scorch","#DEATH_HINT_SCORCH_003","",""
+"titan_class","scorch","#DEATH_HINT_SCORCH_004","",""
+"titan_class","scorch","#DEATH_HINT_SCORCH_005","",""
+"titan_class","scorch","#DEATH_HINT_SCORCH_006","",""
+"titan_class","tone","#DEATH_HINT_TONE_001","",""
+"titan_class","tone","#DEATH_HINT_TONE_002","",""
+"titan_class","tone","#DEATH_HINT_TONE_003","",""
+"titan_class","tone","#DEATH_HINT_TONE_004","",""
+"titan_class","tone","#DEATH_HINT_TONE_005","",""
+"titan_class","tone","#DEATH_HINT_TONE_006","",""
+"weapon","mp_ability_cloak","#DEATH_HINT_CLOAK_001","",""
+"weapon","mp_ability_cloak","#DEATH_HINT_CLOAK_002","",""
+"weapon","mp_ability_cloak","#DEATH_HINT_CLOAK_003","",""
+"weapon","mp_ability_grapple","#DEATH_HINT_GRAPPLE_001","",""
+"weapon","mp_ability_heal","#DEATH_HINT_STIM_001","",""
+"weapon","mp_ability_heal","#DEATH_HINT_STIM_002","",""
+"weapon","mp_ability_heal","#DEATH_HINT_STIM_003","",""
+"weapon","mp_ability_holopilot","#DEATH_HINT_HOLOPILOT_001","",""
+"weapon","mp_ability_holopilot","#DEATH_HINT_HOLOPILOT_002","",""
+"weapon","mp_ability_holopilot","#DEATH_HINT_HOLOPILOT_003","",""
+"weapon","mp_ability_holopilot","#DEATH_HINT_HOLOPILOT_004","",""
+"weapon","mp_ability_holopilot","#DEATH_HINT_HOLOPILOT_005","",""
+"weapon","mp_ability_holopilot","#DEATH_HINT_HOLOPILOT_006","",""
+"weapon","mp_ability_phase_rewind","#DEATH_HINT_PHASE_REWIND_001","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_001","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_002","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_003","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_004","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_005","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_006","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_007","",""
+"weapon","mp_ability_shifter","#DEATH_HINT_PHASESHIFT_008","",""
+"weapon","mp_ability_sonar","#DEATH_HINT_SONAR_001","",""
+"weapon","mp_titanability_ammo_swap","#DEATH_HINT_AMMO_SWAP_001_MP","",""
+"weapon","mp_titanability_basic_block","#DEATH_HINT_SWORD_BLOCK_001_MP","",""
+"weapon","mp_titanability_gun_shield","#DEATH_HINT_GUN_SHIELD_001_MP","",""
+"weapon","mp_titanability_hover","#DEATH_HINT_TITAN_HOVER_001","",""
+"weapon","mp_titanability_laser_trip","#DEATH_HINT_LASER_TRIPWIRE_001","",""
+"weapon","mp_titanability_particle_wall","#DEATH_HINT_PARTICLE_WALL_001_MP","",""
+"weapon","mp_titanability_particle_wall","#DEATH_HINT_PARTICLE_WALL_002_MP","",""
+"weapon","mp_titanability_particle_wall","#DEATH_HINT_PARTICLE_WALL_003_MP","",""
+"weapon","mp_titanability_phase_dash","#DEATH_HINT_PHASE_DASH_001_MP","",""
+"weapon","mp_titanability_phase_dash","#DEATH_HINT_PHASE_DASH_002_MP","",""
+"weapon","mp_titanability_power_shot","#DEATH_HINT_POWER_SHOT_001_MP","",""
+"weapon","mp_titanability_power_shot","#DEATH_HINT_POWER_SHOT_002_MP","",""
+"weapon","mp_titanability_slow_trap","#DEATH_HINT_INCENDIARY_TRAP_001","",""
+"weapon","mp_titanability_tether_trap","#DEATH_HINT_TETHER_TRAP_001_MP","",""
+"weapon","mp_titancore_flame_wave","#DEATH_HINT_FLAME_CORE_001_MP","",""
+"weapon","mp_titancore_flight_core","#DEATH_HINT_FLIGHT_CORE_001_MP","",""
+"weapon","mp_titancore_laser_cannon","#DEATH_HINT_LASER_CANNON_001_MP","",""
+"weapon","mp_titancore_salvo_core","#DEATH_HINT_SALVO_CORE_001_MP","",""
+"weapon","mp_titancore_shift_core","#DEATH_HINT_SHIFT_CORE_001","",""
+"weapon","mp_titancore_siege_mode","#DEATH_HINT_SMART_CORE_001_MP","",""
+"weapon","mp_titanweapon_arc_wave","#DEATH_HINT_ARC_WAVE_001","",""
+"weapon","mp_titanweapon_flame_wall","#DEATH_HINT_FIREWALL_001_MP","",""
+"weapon","mp_titanweapon_heat_shield","#DEATH_HINT_HEAT_SHIELD_001_MP","",""
+"weapon","mp_titanweapon_laser_lite","#DEATH_HINT_LASER_SHOT_001_MP","",""
+"weapon","mp_titanweapon_leadwall","#DEATH_HINT_LEADWALL_001","",""
+"weapon","mp_titanweapon_leadwall","#DEATH_HINT_LEADWALL_002","",""
+"weapon","mp_titanweapon_leadwall","#DEATH_HINT_LEADWALL_003","",""
+"weapon","mp_titanweapon_leadwall","#DEATH_HINT_LEADWALL_004","",""
+"weapon","mp_titanweapon_meteor","#DEATH_HINT_THERMITE_LAUNCHER_001","",""
+"weapon","mp_titanweapon_meteor","#DEATH_HINT_THERMITE_LAUNCHER_002","",""
+"weapon","mp_titanweapon_meteor","#DEATH_HINT_THERMITE_LAUNCHER_003","",""
+"weapon","mp_titanweapon_meteor","#DEATH_HINT_THERMITE_LAUNCHER_004","",""
+"weapon","mp_titanweapon_meteor","#DEATH_HINT_THERMITE_LAUNCHER_005","",""
+"weapon","mp_titanweapon_particle_accelerator","#DEATH_HINT_SPLITTER_RIFLE_001","",""
+"weapon","mp_titanweapon_particle_accelerator","#DEATH_HINT_SPLITTER_RIFLE_002","",""
+"weapon","mp_titanweapon_particle_accelerator","#DEATH_HINT_SPLITTER_RIFLE_003","",""
+"weapon","mp_titanweapon_particle_accelerator","#DEATH_HINT_SPLITTER_RIFLE_004","",""
+"weapon","mp_titanweapon_predator_cannon","#DEATH_HINT_PREDATOR_CANNON_001","",""
+"weapon","mp_titanweapon_predator_cannon","#DEATH_HINT_PREDATOR_CANNON_002","",""
+"weapon","mp_titanweapon_predator_cannon","#DEATH_HINT_PREDATOR_CANNON_003","",""
+"weapon","mp_titanweapon_predator_cannon","#DEATH_HINT_PREDATOR_CANNON_004","",""
+"weapon","mp_titanweapon_predator_cannon","#DEATH_HINT_PREDATOR_CANNON_005","",""
+"weapon","mp_titanweapon_sniper","#DEATH_HINT_PLASMA_RAILGUN_001","",""
+"weapon","mp_titanweapon_sniper","#DEATH_HINT_PLASMA_RAILGUN_002","",""
+"weapon","mp_titanweapon_sniper","#DEATH_HINT_PLASMA_RAILGUN_003","",""
+"weapon","mp_titanweapon_sniper","#DEATH_HINT_PLASMA_RAILGUN_004","",""
+"weapon","mp_titanweapon_sniper","#DEATH_HINT_PLASMA_RAILGUN_005","",""
+"weapon","mp_titanweapon_sticky_40mm","#DEATH_HINT_40MM_TRACKER_001","",""
+"weapon","mp_titanweapon_sticky_40mm","#DEATH_HINT_40MM_TRACKER_002","",""
+"weapon","mp_titanweapon_sticky_40mm","#DEATH_HINT_40MM_TRACKER_003","",""
+"weapon","mp_titanweapon_sticky_40mm","#DEATH_HINT_40MM_TRACKER_004","",""
+"weapon","mp_titanweapon_sticky_40mm","#DEATH_HINT_40MM_TRACKER_005","",""
+"weapon","mp_titanweapon_sticky_40mm","#DEATH_HINT_40MM_TRACKER_006","",""
+"weapon","mp_titanweapon_tracker_rockets","#DEATH_HINT_TRACKING_ROCKETS_001_MP","",""
+"weapon","mp_titanweapon_tracker_rockets","#DEATH_HINT_TRACKING_ROCKETS_002_MP","",""
+"weapon","mp_titanweapon_tracker_rockets","#DEATH_HINT_TRACKING_ROCKETS_003","",""
+"weapon","mp_titanweapon_vortex_shield","#DEATH_HINT_VORTEX_SHIELD_001","",""
+"weapon","mp_titanweapon_vortex_shield","#DEATH_HINT_VORTEX_SHIELD_002_MP","",""
+"weapon","mp_weapon_alternator_smg","#DEATH_HINT_ALTERNATOR_001","",""
+"weapon","mp_weapon_alternator_smg","#DEATH_HINT_ALTERNATOR_002","",""
+"weapon","mp_weapon_arc_launcher","#DEATH_HINT_ARCLAUNCHER_001","",""
+"weapon","mp_weapon_arc_launcher","#DEATH_HINT_ARCLAUNCHER_002","",""
+"weapon","mp_weapon_arc_launcher","#DEATH_HINT_ARCLAUNCHER_003","",""
+"weapon","mp_weapon_arc_launcher","#DEATH_HINT_ARCLAUNCHER_004","",""
+"weapon","mp_weapon_autopistol","#DEATH_HINT_RE45_001","",""
+"weapon","mp_weapon_autopistol","#DEATH_HINT_RE45_002","",""
+"weapon","mp_weapon_autopistol","#DEATH_HINT_RE45_003","",""
+"weapon","mp_weapon_car","#DEATH_HINT_CAR_001","",""
+"weapon","mp_weapon_car","#DEATH_HINT_CAR_002","",""
+"weapon","mp_weapon_defender","#DEATH_HINT_CHARGERIFLE_001","",""
+"weapon","mp_weapon_defender","#DEATH_HINT_CHARGERIFLE_002","",""
+"weapon","mp_weapon_defender","#DEATH_HINT_CHARGERIFLE_003","",""
+"weapon","mp_weapon_defender","#DEATH_HINT_CHARGERIFLE_004","",""
+"weapon","mp_weapon_defender","#DEATH_HINT_CHARGERIFLE_005","",""
+"weapon","mp_weapon_defender","#DEATH_HINT_CHARGERIFLE_006","",""
+"weapon","mp_weapon_deployable_cover","#DEATH_HINT_AWALL_001","",""
+"weapon","mp_weapon_deployable_cover","#DEATH_HINT_AWALL_002","",""
+"weapon","mp_weapon_deployable_cover","#DEATH_HINT_AWALL_003","",""
+"weapon","mp_weapon_deployable_cover","#DEATH_HINT_AWALL_004","",""
+"weapon","mp_weapon_deployable_cover","#DEATH_HINT_AWALL_005","",""
+"weapon","mp_weapon_deployable_cover","#DEATH_HINT_AWALL_006","",""
+"weapon","mp_weapon_dmr","#DEATH_HINT_DMR_001","",""
+"weapon","mp_weapon_dmr","#DEATH_HINT_DMR_002","",""
+"weapon","mp_weapon_dmr","#DEATH_HINT_DMR_003","",""
+"weapon","mp_weapon_dmr","#DEATH_HINT_DMR_004","",""
+"weapon","mp_weapon_dmr","#DEATH_HINT_DMR_005","",""
+"weapon","mp_weapon_dmr","#DEATH_HINT_DMR_006","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_001","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_002","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_003","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_004","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_005","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_006","",""
+"weapon","mp_weapon_doubletake","#DEATH_HINT_DOUBLETAKE_007","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_001","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_002","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_003","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_004","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_005","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_006","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_007","",""
+"weapon","mp_weapon_epg","#DEATH_HINT_EPG1_008","",""
+"weapon","mp_weapon_esaw","#DEATH_HINT_DEVOTION_001","",""
+"weapon","mp_weapon_esaw","#DEATH_HINT_DEVOTION_002","",""
+"weapon","mp_weapon_esaw","#DEATH_HINT_DEVOTION_003","",""
+"weapon","mp_weapon_esaw","#DEATH_HINT_DEVOTION_004","",""
+"weapon","mp_weapon_frag_drone","#DEATH_HINT_FRAG_DRONE_001","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_001","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_002","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_003","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_004","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_005","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_006","",""
+"weapon","mp_weapon_frag_grenade","#DEATH_HINT_GRENADE_FRAG_007","",""
+"weapon","mp_weapon_g2","#DEATH_HINT_G2_001","",""
+"weapon","mp_weapon_g3","#DEATH_HINT_G2_002","",""
+"weapon","mp_weapon_g4","#DEATH_HINT_G2_003","",""
+"weapon","mp_weapon_g5","#DEATH_HINT_G2_004","",""
+"weapon","mp_weapon_grenade_electric_smoke","#DEATH_HINT_GRENADE_ELECTRIC_SMOKE_001","",""
+"weapon","mp_weapon_grenade_electric_smoke","#DEATH_HINT_GRENADE_ELECTRIC_SMOKE_002","",""
+"weapon","mp_weapon_grenade_electric_smoke","#DEATH_HINT_GRENADE_ELECTRIC_SMOKE_003","",""
+"weapon","mp_weapon_grenade_electric_smoke","#DEATH_HINT_GRENADE_ELECTRIC_SMOKE_004","",""
+"weapon","mp_weapon_grenade_emp","#DEATH_HINT_GRENADE_EMP_001","",""
+"weapon","mp_weapon_grenade_emp","#DEATH_HINT_GRENADE_EMP_002","",""
+"weapon","mp_weapon_grenade_emp","#DEATH_HINT_GRENADE_EMP_003","",""
+"weapon","mp_weapon_grenade_emp","#DEATH_HINT_GRENADE_EMP_004","",""
+"weapon","mp_weapon_grenade_emp","#DEATH_HINT_GRENADE_EMP_005","",""
+"weapon","mp_weapon_grenade_gravity","#DEATH_HINT_GRENADE_GRAVITY_001","",""
+"weapon","mp_weapon_grenade_gravity","#DEATH_HINT_GRENADE_GRAVITY_002","",""
+"weapon","mp_weapon_grenade_gravity","#DEATH_HINT_GRENADE_GRAVITY_003","",""
+"weapon","mp_weapon_grenade_gravity","#DEATH_HINT_GRENADE_GRAVITY_004","",""
+"weapon","mp_weapon_grenade_gravity","#DEATH_HINT_GRENADE_GRAVITY_005","",""
+"weapon","mp_weapon_grenade_sonar","#DEATH_HINT_GRENADE_SONAR_001","",""
+"weapon","mp_weapon_grenade_sonar","#DEATH_HINT_GRENADE_SONAR_002","",""
+"weapon","mp_weapon_grenade_sonar","#DEATH_HINT_GRENADE_SONAR_003","",""
+"weapon","mp_weapon_grenade_sonar","#DEATH_HINT_GRENADE_SONAR_004","",""
+"weapon","mp_weapon_hemlok","#DEATH_HINT_HEMLOK_001","",""
+"weapon","mp_weapon_hemlok","#DEATH_HINT_HEMLOK_002","",""
+"weapon","mp_weapon_hemlok_smg","#DEATH_HINT_VOLT_001","",""
+"weapon","mp_weapon_hemlok_smg","#DEATH_HINT_VOLT_002","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_001","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_002","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_003","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_004","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_005","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_006","",""
+"weapon","mp_weapon_lmg","#DEATH_HINT_SPITFIRE_007","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_001","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_002","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_003","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_004","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_005","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_006","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_007","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_008","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_009","",""
+"weapon","mp_weapon_lstar","#DEATH_HINT_LSTAR_010","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_001","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_002","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_003","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_004","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_005","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_006","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_007","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_008","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_009","",""
+"weapon","mp_weapon_mastiff","#DEATH_HINT_MASTIFF_010","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_001","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_002","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_003","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_004","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_005","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_006","",""
+"weapon","mp_weapon_mgl","#DEATH_HINT_MGL_007","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_001","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_002","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_003","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_004","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_005","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_006","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_007","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_008","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_009","",""
+"weapon","mp_weapon_pulse_lmg","#DEATH_HINT_COLDWAR_010","",""
+"weapon","mp_weapon_r97","#DEATH_HINT_97_001","",""
+"weapon","mp_weapon_r97","#DEATH_HINT_97_002","",""
+"weapon","mp_weapon_r97","#DEATH_HINT_97_003","",""
+"weapon","mp_weapon_r97","#DEATH_HINT_97_004","",""
+"weapon","mp_weapon_rocket_launcher","#DEATH_HINT_ARCHER_001","",""
+"weapon","mp_weapon_rocket_launcher","#DEATH_HINT_ARCHER_002","",""
+"weapon","mp_weapon_rocket_launcher","#DEATH_HINT_ARCHER_003","",""
+"weapon","mp_weapon_rocket_launcher","#DEATH_HINT_ARCHER_004","",""
+"weapon","mp_weapon_rocket_launcher","#DEATH_HINT_ARCHER_005","",""
+"weapon","mp_weapon_rspn101","#DEATH_HINT_102_001","",""
+"weapon","mp_weapon_rspn102","#DEATH_HINT_102_002","",""
+"weapon","mp_weapon_satchel","#DEATH_HINT_SATCHEL_001","",""
+"weapon","mp_weapon_satchel","#DEATH_HINT_SATCHEL_002","",""
+"weapon","mp_weapon_satchel","#DEATH_HINT_SATCHEL_003","",""
+"weapon","mp_weapon_semipistol","#DEATH_HINT_P2011_001","",""
+"weapon","mp_weapon_semipistol","#DEATH_HINT_P2011_002","",""
+"weapon","mp_weapon_semipistol","#DEATH_HINT_P2011_003","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_001","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_002","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_003","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_004","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_005","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_006","",""
+"weapon","mp_weapon_shotgun","#DEATH_HINT_EVA8_007","",""
+"weapon","mp_weapon_shotgun_pistol","#DEATH_HINT_MOZAMBIQUE_001","",""
+"weapon","mp_weapon_shotgun_pistol","#DEATH_HINT_MOZAMBIQUE_002","",""
+"weapon","mp_weapon_shotgun_pistol","#DEATH_HINT_MOZAMBIQUE_003","",""
+"weapon","mp_weapon_smart_pistol","#DEATH_HINT_SMARTPISTOL_001","",""
+"weapon","mp_weapon_smart_pistol","#DEATH_HINT_SMARTPISTOL_002","",""
+"weapon","mp_weapon_smart_pistol","#DEATH_HINT_SMARTPISTOL_003","",""
+"weapon","mp_weapon_smart_pistol","#DEATH_HINT_SMARTPISTOL_004","",""
+"weapon","mp_weapon_smart_pistol","#DEATH_HINT_SMARTPISTOL_005","",""
+"weapon","mp_weapon_smart_pistol","#DEATH_HINT_SMARTPISTOL_006","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_001","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_002","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_003","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_004","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_005","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_006","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_007","",""
+"weapon","mp_weapon_smr","#DEATH_HINT_SMR_008","",""
+"weapon","mp_weapon_sniper","#DEATH_HINT_KRABER_001","",""
+"weapon","mp_weapon_sniper","#DEATH_HINT_KRABER_002","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_001","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_002","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_003","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_004","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_005","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_006","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_007","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_008","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_009","",""
+"weapon","mp_weapon_softball","#DEATH_HINT_SOFTBALL_010","",""
+"weapon","mp_weapon_thermite_grenade","#DEATH_HINT_GRENADE_THERMITE_001","",""
+"weapon","mp_weapon_thermite_grenade","#DEATH_HINT_GRENADE_THERMITE_002","",""
+"weapon","mp_weapon_thermite_grenade","#DEATH_HINT_GRENADE_THERMITE_003","",""
+"weapon","mp_weapon_thermite_grenade","#DEATH_HINT_GRENADE_THERMITE_004","",""
+"weapon","mp_weapon_vinson","#DEATH_HINT_VINSON_001","",""
+"weapon","mp_weapon_vinson","#DEATH_HINT_VINSON_002","",""
+"weapon","mp_weapon_vinson","#DEATH_HINT_VINSON_003","",""
+"weapon","mp_weapon_wingman","#DEATH_HINT_WINGMAN_001","",""
+"weapon","mp_weapon_wingman","#DEATH_HINT_WINGMAN_002","",""
+"weapon","mp_weapon_wingman","#DEATH_HINT_WINGMAN_003","",""
+"weapon","mp_weapon_wingman","#DEATH_HINT_WINGMAN_004","",""
+"weapon","mp_weapon_wingman_n","#DEATH_HINT_WINGMAN_N_001","",""
+"weapon","pas_power_cell","#DEATH_HINT_POWER_CELL_001","",""
+"weapon","pas_fast_health_regen","#DEATH_HINT_FAST_REGEN_001","",""
+"weapon","pas_ordnance_pack","#DEATH_HINT_ORDNANCE_EXPERT_001","",""
+"weapon","pas_ordnance_pack","#DEATH_HINT_ORDNANCE_EXPERT_002","",""
+"weapon","pas_ordnance_pack","#DEATH_HINT_ORDNANCE_EXPERT_003","",""
+"weapon","pas_ordnance_pack","#DEATH_HINT_ORDNANCE_EXPERT_004","",""
+"weapon","pas_fast_embark","#DEATH_HINT_PHASE_EMBARK_001","",""
+"weapon","pas_fast_embark","#DEATH_HINT_PHASE_EMBARK_002","",""
+"weapon","pas_fast_embark","#DEATH_HINT_PHASE_EMBARK_003","",""
+"weapon","pas_enemy_death_icons","#DEATH_HINT_KILL_REPORT_001","",""
+"weapon","pas_enemy_death_icons","#DEATH_HINT_KILL_REPORT_002","",""
+"weapon","pas_enemy_death_icons","#DEATH_HINT_KILL_REPORT_003","",""
+"weapon","pas_wallhang","#DEATH_HINT_WALLHANG_001","",""
+"weapon","pas_wallhang","#DEATH_HINT_WALLHANG_002","",""
+"weapon","pas_ads_hover","#DEATH_HINT_HOVER_001","",""
+"weapon","pas_ads_hover","#DEATH_HINT_HOVER_002","",""
+"weapon","pas_ads_hover","#DEATH_HINT_HOVER_003","",""
+"weapon","pas_ads_hover","#DEATH_HINT_HOVER_004","",""
+"weapon","pas_ads_hover","#DEATH_HINT_HOVER_005","",""
+"weapon","pas_stealth_movement","#DEATH_HINT_LOW_PROFILE_001","",""
+"weapon","pas_enhanced_titan_ai","#DEATH_HINT_ASSAULT_CHIP_001","",""
+"weapon","pas_enhanced_titan_ai","#DEATH_HINT_ASSAULT_CHIP_002","",""
+"weapon","pas_auto_eject","#DEATH_HINT_AUTO_EJECT_001","",""
+"weapon","pas_auto_eject","#DEATH_HINT_AUTO_EJECT_002","",""
+"weapon","pas_auto_eject","#DEATH_HINT_AUTO_EJECT_003","",""
+"weapon","pas_auto_eject","#DEATH_HINT_AUTO_EJECT_004","",""
+"weapon","pas_mobility_dash_capacity","#DEATH_HINT_TURBO_ENGINE_001","",""
+"weapon","pas_mobility_dash_capacity","#DEATH_HINT_TURBO_ENGINE_002","",""
+"weapon","pas_mobility_dash_capacity","#DEATH_HINT_TURBO_ENGINE_003","",""
+"weapon","pas_hyper_core","#DEATH_HINT_OVERCORE_001","",""
+"weapon","pas_build_up_nuclear_core","#DEATH_HINT_NUKE_EJECT_001","",""
+"weapon","pas_build_up_nuclear_core","#DEATH_HINT_NUKE_EJECT_002","",""
+"weapon","pas_anti_rodeo","#DEATH_HINT_COUNTER_READY_001","",""
+"weapon","pas_anti_rodeo","#DEATH_HINT_COUNTER_READY_002","",""
+"weapon","pas_warpfall","#DEATH_HINT_WARPFALL_001","",""
+"weapon","pas_bubbleshield","#DEATH_HINT_DOME_SHIELD_001","",""
+"weapon","pas_bubbleshield","#DEATH_HINT_DOME_SHIELD_002","",""
+"npc_title","#NPC_TITAN_AUTO_NUKE","#HINT_FD_TITAN_AUTO_NUKE","","fd"
+"npc_title","#NPC_TITAN_AUTO_NUKE","#HINT_FD_TITAN_AUTO_NUKE2","","fd"
+"npc_title","#NPC_TITAN_ARC","#HINT_FD_TITAN_ARC","","fd"
+"npc_title","#NPC_TITAN_ARC","#HINT_FD_TITAN_ARC2","","fd"
+"npc_title","#NPC_TITAN_MORTAR","#HINT_FD_TITAN_MORTAR","","fd"
+"npc_title","#NPC_TITAN_MORTAR","#HINT_FD_TITAN_MORTAR2","","fd"
+"npc_title","#NPC_SOLDIER","#HINT_FD_SOLDIER","","fd"
+"npc_title","#NPC_SPECTRE","#HINT_FD_SPECTRE","","fd"
+"npc_title","#NPC_SPECTRE_MORTAR","#HINT_FD_SPECTRE_MORTAR","","fd"
+"npc_title","#NPC_SPECTRE_MORTAR","#HINT_FD_SPECTRE_MORTAR2","","fd"
+"npc_title","#NPC_STALKER","#HINT_FD_STALKER","","fd"
+"npc_title","#NPC_SUPER_SPECTRE","#HINT_FD_SUPER_SPECTRE","","fd"
+"npc_title","#NPC_SUPER_SPECTRE","#HINT_FD_SUPER_SPECTRE2","","fd"
+"npc_title","#NPC_SPECTRE_SUICIDE","#HINT_FD_SPECTRE_SUICIDE","","fd"
+"npc_title","#NPC_DRONE_PLASMA","#HINT_FD_DRONE_PLASMA","","fd"
+"npc_title","#NPC_DRONE_CLOAKED","#HINT_FD_DRONE_CLOAKED","","fd"
+"npc_title","#NPC_TITAN_STRYDER_LEADWALL","#HINT_FD_TITAN_STRYDER_LEADWALL","","fd"
+"npc_title","#NPC_TITAN_STRYDER_SNIPER","#HINT_FD_TITAN_STRYDER_SNIPER","","fd"
+"npc_title","#NPC_TITAN_OGRE_METEOR","#HINT_FD_TITAN_OGRE_METEOR","","fd"
+"npc_title","#NPC_TITAN_OGRE_MINIGUN","#HINT_FD_TITAN_OGRE_MINIGUN","","fd"
+"npc_title","#NPC_TITAN_ATLAS_TRACKER","#HINT_FD_TITAN_ATLAS_TRACKER","","fd"
+"npc_title","#NPC_TITAN_ATLAS_STICKYBOMB","#HINT_FD_TITAN_ATLAS_STICKYBOMB","","fd"
+"npc_title","#NPC_TITAN_ATLAS_VANGUARD","#HINT_FD_TITAN_ATLAS_VANGUARD","","fd"
+"npc_title","#NPC_TITAN_SNIPER_FD","#HINT_FD_TITAN_STRYDER_SNIPER","","fd"
+"npc_title","#NPC_TITAN_SNIPER_FD","#HINT_FD_TITAN_STRYDER_SNIPER2","","fd"
+"npc_title","#NPC_TITAN_SNIPER_FD","#HINT_FD_TITAN_STRYDER_SNIPER3","","fd"
+"titan_class","vanguard","#DEATH_HINT_VANGUARD_001","",""
+"titan_class","vanguard","#DEATH_HINT_VANGUARD_002","",""
+"titan_class","vanguard","#DEATH_HINT_VANGUARD_003","",""
+"titan_class","vanguard","#DEATH_HINT_VANGUARD_004","",""
+"titan_class","vanguard","#DEATH_HINT_VANGUARD_005","",""
+"titan_class","vanguard","#DEATH_HINT_VANGUARD_006","",""
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/default_pilot_loadouts.csv b/Northstar.CustomServers/mod/scripts/datatable/default_pilot_loadouts.csv new file mode 100644 index 00000000..e0fbbcd9 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/default_pilot_loadouts.csv @@ -0,0 +1,11 @@ +name,suit,race,primary,primaryAttachment,primaryMod1,primaryMod2,primaryMod3,secondary,secondaryMod1,secondaryMod2,secondaryMod3,weapon3,weapon3Mod1,weapon3Mod2,weapon3Mod3,ordnance,passive1,passive2
+"#DEFAULT_PILOT_1","grapple","race_human_male","mp_weapon_rspn101","","","","","mp_weapon_defender","","","","mp_weapon_autopistol","","","","mp_weapon_frag_grenade","pas_power_cell","pas_enemy_death_icons"
+"#DEFAULT_PILOT_2","medium","race_human_female","mp_weapon_car","","","","","mp_weapon_mgl","","","","mp_weapon_autopistol","","","","mp_weapon_grenade_emp","pas_fast_health_regen","pas_wallhang"
+"#DEFAULT_PILOT_3","grapple","race_human_female","mp_weapon_lmg","","","","","mp_weapon_defender","","","","mp_weapon_autopistol","","","","mp_weapon_thermite_grenade","pas_fast_health_regen","pas_enemy_death_icons"
+"#DEFAULT_PILOT_4","medium","race_human_male","mp_weapon_shotgun","","","","","mp_weapon_defender","","","","mp_weapon_autopistol","","","","mp_weapon_frag_grenade","pas_power_cell","pas_wallhang"
+"#DEFAULT_PILOT_5","geist","race_human_female","mp_weapon_sniper","","","","","mp_weapon_defender","","","","mp_weapon_autopistol","","","","mp_weapon_grenade_emp","pas_power_cell","pas_enemy_death_icons"
+"#DEFAULT_PILOT_6","grapple","race_human_female","mp_weapon_smr","","","","","mp_weapon_defender","","","","mp_weapon_semipistol","","","","mp_weapon_thermite_grenade","pas_fast_health_regen","pas_wallhang"
+"#DEFAULT_PILOT_7","medium","race_human_female","mp_weapon_rspn101","","","","","mp_weapon_mgl","","","","mp_weapon_autopistol","","","","mp_weapon_grenade_emp","pas_power_cell","pas_enemy_death_icons"
+"#DEFAULT_PILOT_8","grapple","race_human_male","mp_weapon_car","","","","","mp_weapon_defender","","","","mp_weapon_autopistol","","","","mp_weapon_thermite_grenade","pas_fast_health_regen","pas_wallhang"
+"#DEFAULT_PILOT_9","grapple","race_human_male","mp_weapon_sniper","","","","","mp_weapon_defender","","","","mp_weapon_semipistol","","","","mp_weapon_frag_grenade","pas_power_cell","pas_enemy_death_icons"
+"#DEFAULT_PILOT_10","geist","race_human_male","mp_weapon_smr","","","","","mp_weapon_defender","","","","mp_weapon_autopistol","","","","mp_weapon_grenade_emp","pas_fast_health_regen","pas_wallhang"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/default_titan_loadouts.csv b/Northstar.CustomServers/mod/scripts/datatable/default_titan_loadouts.csv new file mode 100644 index 00000000..b19ef636 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/default_titan_loadouts.csv @@ -0,0 +1,8 @@ +name,primeName,setFile,titanRef,primaryMod,special,antirodeo,passive1,passive2,passive3,passive4,passive5,passive6,voice
+"#DEFAULT_TITAN_5","#DEFAULT_TITAN_5_PRIME","titan_atlas_stickybomb","ion","","mp_titanweapon_vortex_shield_ion","mp_titanability_laser_trip","pas_enhanced_titan_ai","pas_ion_weapon","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_ion"
+"#DEFAULT_TITAN_7","#DEFAULT_TITAN_7_PRIME","titan_ogre_meteor","scorch","","mp_titanweapon_heat_shield","mp_titanability_slow_trap","pas_enhanced_titan_ai","pas_scorch_weapon","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_scorch"
+"#DEFAULT_TITAN_3","#DEFAULT_TITAN_3_PRIME","titan_stryder_sniper","northstar","","mp_titanability_tether_trap","mp_titanability_hover","pas_enhanced_titan_ai","pas_northstar_weapon","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_northstar"
+"#DEFAULT_TITAN_2","#DEFAULT_TITAN_2_PRIME","titan_stryder_leadwall","ronin","","mp_titanability_basic_block","mp_titanability_phase_dash","pas_enhanced_titan_ai","pas_ronin_weapon","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_ronin"
+"#DEFAULT_TITAN_4","#DEFAULT_TITAN_4_PRIME","titan_atlas_tracker","tone","","mp_titanability_particle_wall","mp_titanability_sonar_pulse","pas_enhanced_titan_ai","pas_tone_weapon","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_tone"
+"#DEFAULT_TITAN_8","#DEFAULT_TITAN_8_PRIME","titan_ogre_minigun","legion","","mp_titanability_gun_shield","mp_titanability_ammo_swap","pas_enhanced_titan_ai","pas_legion_weapon","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_legion"
+"#DEFAULT_TITAN_10","#DEFAULT_TITAN_10_PRIME","titan_atlas_vanguard","vanguard","","mp_titanweapon_stun_laser","mp_titanability_rearm","pas_enhanced_titan_ai","pas_vanguard_shield","pas_bubbleshield","pas_vanguard_core1","pas_vanguard_core4","pas_vanguard_core7","titanos_vanguard"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/earn_meter_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/earn_meter_mp.csv new file mode 100644 index 00000000..1c766181 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/earn_meter_mp.csv @@ -0,0 +1,31 @@ +itemRef,earnType,buildingImage,readyImage,nameText
+"titan_ronin","GOAL","rui/hud/earn_meter/ajax_building","rui/hud/earn_meter/titan_ready","#RONIN"
+"titan","GOAL","rui/hud/earn_meter/ajax_building","rui/hud/earn_meter/titan_ready","#TITAN"
+"ion","GOAL","rui/hud/earn_meter/ajax_building","rui/hud/earn_meter/titan_ready","#ION"
+"tone","GOAL","rui/hud/earn_meter/ajax_building","rui/hud/earn_meter/titan_ready","#TONE"
+"scorch","GOAL","rui/hud/earn_meter/ogre_building","rui/hud/earn_meter/titan_ready","#SCORCH"
+"legion","GOAL","rui/hud/earn_meter/ogre_building","rui/hud/earn_meter/titan_ready","#LEGION"
+"ronin","GOAL","rui/hud/earn_meter/stryder_building","rui/hud/earn_meter/titan_ready","#RONIN"
+"northstar","GOAL","rui/hud/earn_meter/stryder_building","rui/hud/earn_meter/titan_ready","#NORTHSTAR"
+"vanguard","GOAL","rui/hud/earn_meter/ajax_building","rui/hud/earn_meter/titan_ready","#VANGUARD"
+"core_electric_smoke","REWARD","rui/menu/boosts/boost_icon_electric_smoke","rui/menu/boosts/boost_icon_electric_smoke","#WPN_TITAN_ELECTRIC_SMOKE"
+"burnmeter_maphack","REWARD","rui/menu/boosts/boost_icon_map_hack","rui/menu/boosts/boost_icon_map_hack","#BURNMETER_MAP_HACK"
+"burnmeter_amped_weapons","REWARD","rui/menu/boosts/boost_icon_amped","rui/menu/boosts/boost_icon_amped","#BURNMETER_AMPED_WEAPONS"
+"burnmeter_ticks","REWARD","rui/menu/boosts/boost_icon_tick","rui/menu/boosts/boost_icon_tick","#BURNMETER_TICKS"
+"burnmeter_emergency_titan","REWARD","ui/temp","ui/temp","#BURNMETER_EMERGENCY_TITAN"
+"burnmeter_random_foil","REWARD","rui/menu/boosts/boost_icon_random","rui/menu/boosts/boost_icon_random","#BURNMETER_RANDOM_FOIL"
+"burnmeter_double_agent","REWARD","rui/menu/boosts/burncard_icon","rui/menu/boosts/burncard_icon","#BURNMETER_DOUBLE_AGENT"
+"burnmeter_phase_rewind","REWARD","rui/menu/boosts/boost_icon_phase_rewind","rui/menu/boosts/boost_icon_phase_rewind","#WPN_REWIND"
+"burnmeter_at_turret_weapon","REWARD","rui/menu/boosts/boost_icon_titan_sentry","rui/menu/boosts/boost_icon_titan_sentry","#BURNMETER_AT_TURRETWEAPON"
+"burnmeter_ap_turret_weapon","REWARD","rui/menu/boosts/boost_icon_personel_sentry","rui/menu/boosts/boost_icon_personel_sentry","#BURNMETER_AP_TURRETWEAPON"
+"burnmeter_holopilot_nova","REWARD","rui/menu/boosts/boost_icon_holopilot","rui/menu/boosts/boost_icon_holopilot","#WPN_HOLOPILOT_NOVA"
+"burnmeter_emergency_battery","REWARD","rui/menu/boosts/boost_icon_battery","rui/menu/boosts/boost_icon_battery","#BURNMETER_EMERGENCY_BATTERY"
+"burnmeter_smart_pistol","REWARD","rui/menu/boosts/boost_icon_smart_pistol","rui/menu/boosts/boost_icon_smart_pistol","#WPN_SMART_PISTOL"
+"burnmeter_radar_jammer","REWARD","rui/menu/boosts/boost_icon_radar_jam","rui/menu/boosts/boost_icon_radar_jam","#BURNMETER_RADAR_JAMMER"
+"burnmeter_hard_cover","REWARD","rui/menu/boosts/boost_icon_shield","rui/menu/boosts/boost_icon_shield","#WPN_HARD_COVER"
+"burnmeter_nuke_titan","REWARD","rui/menu/boosts/boost_icon_nuke","rui/menu/boosts/boost_icon_nuke","#WPN_NUKE_TITAN"
+"burnmeter_harvester_shield","REWARD","rui/menu/boosts/boost_icon_harvester_shield","rui/menu/boosts/boost_icon_harvester_shield","#BURNMETER_HARVESTER_SHIELD"
+"burnmeter_arc_trap","REWARD","rui/menu/boosts/boost_icon_arc_trap","rui/menu/boosts/boost_icon_arc_trap","#WPN_ARC_TRAP"
+"burnmeter_at_turret_weapon_infinite","REWARD","rui/menu/boosts/boost_icon_titan_sentry","rui/menu/boosts/boost_icon_titan_sentry","#BURNMETER_AT_TURRETWEAPON"
+"burnmeter_ap_turret_weapon_infinite","REWARD","rui/menu/boosts/boost_icon_personel_sentry","rui/menu/boosts/boost_icon_personel_sentry","#BURNMETER_AP_TURRETWEAPON"
+"burnmeter_rodeo_grenade","REWARD","rui/menu/boosts/boost_icon_core_overload","rui/menu/boosts/boost_icon_core_overload","#BURNMETER_SUPER_RODEO"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/faction_dialogue.csv b/Northstar.CustomServers/mod/scripts/datatable/faction_dialogue.csv new file mode 100644 index 00000000..8e9673d1 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/faction_dialogue.csv @@ -0,0 +1,273 @@ +conversationname,priority,debounce,disabledForFaction,inheritedDebounceConversations
+"scoring_won",3000,10.000000,"",""
+"scoring_lost",3000,10.000000,"",""
+"scoring_tied",3000,10.000000,"",""
+"scoring_wonClose",3000,10.000000,"",""
+"scoring_lostClose",3000,10.000000,"",""
+"scoring_winning",3000,10.000000,"faction_marvin",""
+"scoring_losing",3000,10.000000,"faction_marvin",""
+"scoring_winningClose",3000,10.000000,"faction_marvin",""
+"scoring_losingClose",3000,10.000000,"faction_marvin",""
+"scoring_winningLarge",3000,10.000000,"faction_marvin",""
+"scoring_losingLarge",3000,10.000000,"faction_marvin",""
+"scoring_lostMercy",3000,10.000000,"",""
+"scoring_wonMercy",3000,10.000000,"",""
+"fortwar_matchLoss",3000,10.000000,"",""
+"scoring_flavor",1500,10.000000,"",""
+"scoring_gotMailAlert",1500,10.000000,"",""
+"amphp_modeName",1500,10.000000,"",""
+"mtitan_modeName",1500,10.000000,"",""
+"ffa_modeName",2500,10.000000,"",""
+"freea_modeName",2500,10.000000,"",""
+"at_modeName",2500,10.000000,"",""
+"hp_modeName",2500,10.000000,"",""
+"cp_modeName",2500,10.000000,"",""
+"phunt_modeName",2500,10.000000,"",""
+"fortwar_modeName",2500,10.000000,"",""
+"tw_modeName",2500,10.000000,"",""
+"ctf_modeName",2500,10.000000,"",""
+"bh_modeName",2500,10.000000,"",""
+"front_modeName",2500,10.000000,"",""
+"frontdef_modeName",2500,10.000000,"",""
+"frontatk_modeName",2500,10.000000,"",""
+"lts_modeName",2500,10.000000,"",""
+"mfd_modeName",2500,10.000000,"",""
+"tmfd_modeName",2500,10.000000,"",""
+"extract_modeName",2500,10.000000,"",""
+"mw_modeName",2500,10.000000,"",""
+"pvp_modeName",2500,10.000000,"",""
+"raid_modeName",2500,10.000000,"",""
+"aslt_modeName",2500,10.000000,"",""
+"gnrc_modeDesc",2500,10.000000,"",""
+"ffa_modeDesc",2500,10.000000,"",""
+"ctf_modeDesc",2500,10.000000,"",""
+"lts_modeDesc",2500,10.000000,"",""
+"mfd_modeDesc",2500,10.000000,"",""
+"ltsd_modeDesc",2500,10.000000,"",""
+"ltsa_modeDesc",2500,10.000000,"",""
+"hp_modeDesc",2500,10.000000,"",""
+"mtitan_modeDesc",2500,10.000000,"",""
+"pvp_modeDesc",2500,10.000000,"",""
+"phunt_modeDesc",2500,10.000000,"",""
+"freea_modeDesc",2500,10.000000,"",""
+"grnc_modeDesc",2500,10.000000,"",""
+"mp_titanReady",1200,30.000000,"",""
+"mp_titanSoon",1200,45.000000,"faction_marvin",""
+"mp_titanInbound",1200,10.000000,"",""
+"mp_titanEmergency",1200,10.000000,"faction_marvin",""
+"mp_evacGo",1500,10.000000,"faction_marvin",""
+"mp_evacStop",1500,10.000000,"faction_marvin",""
+"mp_evacGoNag",1500,10.000000,"faction_marvin",""
+"mp_evacStopNag",1500,10.000000,"faction_marvin",""
+"mp_halftime",1500,10.000000,"",""
+"mp_sideSwitching",1500,10.000000,"",""
+"bh_modeDesc",1500,10.000000,"",""
+"bh_incoming",1500,10.000000,"",""
+"bh_collect",1500,10.000000,"faction_marvin",""
+"bh_decrypt",1500,10.000000,"faction_marvin",""
+"bh_collectSuccess",1500,10.000000,"faction_marvin",""
+"bh_collectFail",1500,10.000000,"faction_marvin",""
+"bh_mvp",1500,10.000000,"faction_marvin",""
+"bh_clearedA",1500,10.000000,"",""
+"bh_clearedB",1500,10.000000,"",""
+"bh_clearedC",1500,10.000000,"",""
+"bh_newWave",1500,10.000000,"",""
+"bh_bountyClaimedByEnemy",1500,10.000000,"",""
+"bh_bountyClaimedByFriendly",1500,10.000000,"",""
+"bh_playerKilledBounty",1500,10.000000,"faction_marvin",""
+"lts_atk60",1500,10.000000,"faction_marvin",""
+"lts_atk30",1500,10.000000,"faction_marvin",""
+"lts_def60",1500,10.000000,"faction_marvin",""
+"lts_def30",1500,10.000000,"faction_marvin",""
+"lts_bombDown",1500,10.000000,"faction_marvin",""
+"lts_bombDownAtk",1500,10.000000,"faction_marvin",""
+"lts_bombDownDef",1500,10.000000,"faction_marvin",""
+"lts_bombPickup",1500,10.000000,"faction_marvin",""
+"lts_bombPlanted",1500,10.000000,"faction_marvin",""
+"lts_bombDefusedAtk",1500,10.000000,"faction_marvin",""
+"lts_bombDefusedDef",1500,10.000000,"faction_marvin",""
+"lts_bombPlantedAtk",1500,10.000000,"faction_marvin",""
+"lts_bombPlantedDef",1500,10.000000,"faction_marvin",""
+"fortwar_turretDeployFriendly",1500,10.000000,"faction_marvin",""
+"fortwar_turretDestroyedFriendly",1500,10.000000,"faction_marvin",""
+"fortwar_baseShieldDownFriendly",1500,10.000000,"faction_marvin",""
+"fortwar_baseShieldDownEnemy",1500,10.000000,"faction_marvin",""
+"fortwar_baseShieldUpFriendly",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgFriendly",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgFriendly75",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgFriendly50",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgFriendly25",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgEnemy75",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgEnemy50",1500,10.000000,"faction_marvin",""
+"fortwar_baseDmgEnemy25",1500,10.000000,"faction_marvin",""
+"fortwar_baseEnemyAllyAttacking",1500,30.000000,"faction_marvin",""
+"fortwar_awayTurretsUnderAttack",1450,30.000000,"faction_marvin",""
+"fortwar_baseTurretsUnderAttack",1470,30.000000,"faction_marvin",""
+"fortwar_turretShieldedByFriendlyPilot",1400,10.000000,"faction_marvin",""
+"tw_territoryNag",1500,10.000000,"faction_marvin",""
+"fortwar_terEnemyExpelled",1500,60.000000,"faction_marvin",""
+"fortwar_terFriendlyExpelled",1450,60.000000,"faction_marvin",""
+"fortwar_terEnteredEnemyPilot",1400,60.000000,"faction_marvin",""
+"fortwar_terEnteredEnemyTitan",1450,60.000000,"faction_marvin",""
+"fortwar_terPresentEnemyTitans",1470,60.000000,"faction_marvin",""
+"fortwar_terEnteredEnemyForce",1500,60.000000,"faction_marvin",""
+"amphp_friendlyCappingA",1500,30.000000,"",""
+"amphp_friendlyCappingB",1500,30.000000,"",""
+"amphp_friendlyCappingC",1500,30.000000,"",""
+"amphp_friendlyCappedA",1500,10.000000,"faction_marvin",""
+"amphp_friendlyCappedB",1500,10.000000,"faction_marvin",""
+"amphp_friendlyCappedC",1500,10.000000,"faction_marvin",""
+"amphp_friendlyAmpedA",1500,10.000000,"faction_marvin",""
+"amphp_friendlyAmpedB",1500,10.000000,"faction_marvin",""
+"amphp_friendlyAmpedC",1500,10.000000,"faction_marvin",""
+"amphp_enemyCappedA",1500,10.000000,"",""
+"amphp_enemyCappedB",1500,10.000000,"",""
+"amphp_enemyCappedC",1500,10.000000,"",""
+"amphp_enemyAmpedA",1500,10.000000,"",""
+"amphp_enemyAmpedB",1500,10.000000,"",""
+"amphp_enemyAmpedC",1500,10.000000,"",""
+"amphp_friendlyCapAll",2000,10.000000,"",""
+"amphp_enemyCapAll",2000,10.000000,"",""
+"amphp_youAmpedA",1500,10.000000,"",""
+"amphp_youAmpedB",1500,10.000000,"",""
+"amphp_youAmpedC",1500,10.000000,"",""
+"ctf_flagPickupFriendly",1500,10.000000,"",""
+"ctf_flagPickupYou",1500,10.000000,"",""
+"ctf_flagReturnedFriendly",1500,10.000000,"",""
+"ctf_flagReturnedEnemy",1500,10.000000,"",""
+"ctf_notifyWin1more",1500,10.000000,"faction_marvin",""
+"ctf_notifyLose1more",1500,10.000000,"faction_marvin",""
+"kc_pilotkillLegion",1400,0.100000,"faction_marvin",""
+"kc_pilotkillScorch",1400,0.100000,"faction_marvin",""
+"kc_pilotkillTone",1400,0.100000,"faction_marvin",""
+"kc_pilotkillIon",1400,0.100000,"faction_marvin",""
+"kc_pilotkillRonin",1400,0.100000,"faction_marvin",""
+"kc_pilotkillNorthstar",1400,0.100000,"faction_marvin",""
+"kc_bullseye",1350,0.100000,"faction_marvin",""
+"kc_rodeo",1350,10.000000,"faction_marvin",""
+"kc_rakerodeoguy",1400,10.000000,"faction_marvin",""
+"kc_pilotkilltitan",1400,0.100000,"faction_marvin",""
+"kc_hitandrun",1350,0.100000,"faction_marvin",""
+"kc_firstblood",2100,0.100000,"faction_marvin",""
+"kc_megakill",2100,0.100000,"",""
+"kc_triplekill",2100,0.100000,"",""
+"kc_doublekill",1350,0.100000,"faction_marvin",""
+"kc_iced",1350,0.100000,"faction_marvin",""
+"kc_rampage",1350,0.100000,"faction_marvin",""
+"kc_killingspree",1350,0.100000,"faction_marvin",""
+"kc_dominating",1350,0.100000,"faction_marvin",""
+"kc_retribution",1350,0.100000,"faction_marvin",""
+"kc_comeback",1350,0.100000,"faction_marvin",""
+"mfd_youAreMarked",1500,0.100000,"",""
+"mfd_youKilledMark",1500,0.100000,"",""
+"mfd_markDownEnemy",1500,0.100000,"",""
+"mfd_markDownFriendly",1500,0.100000,"",""
+"mfd_targetsMarkedLong",1500,0.100000,"",""
+"mfd_targetsMarkedShort",1500,0.100000,"",""
+"mfd_youOutlastedEnemy",1500,0.100000,"",""
+"mfd_markCountdown",1500,0.100000,"",""
+"lts_playerLastTitanOnTeam",1500,0.100000,"",""
+"fd_modeDesc",2500,10.000000,"",""
+"fd_firstWaveStartPrefix",2500,10.000000,"",""
+"fd_newWaveStartPrefix",2500,10.000000,"",""
+"fd_finalWaveStartPrefix",2500,10.000000,"",""
+"fd_waveVictory",3000,10.000000,"",""
+"fd_waveRestart",3000,10.000000,"",""
+"fd_waveRedoTwo",3000,10.000000,"",""
+"fd_waveRedoFinal",3000,10.000000,"",""
+"fd_titanReadyNag",1500,10.000000,"",""
+"fd_minimapTip",1500,10.000000,"",""
+"fd_waveNoTitanDrops",1500,10.000000,"",""
+"fd_waveTypeInfantry",1500,10.000000,"",""
+"fd_waveTypeCloakDrone",1500,10.000000,"",""
+"fd_waveTypeTitanReg",1500,10.000000,"",""
+"fd_waveTypeTitanMortar",1500,10.000000,"",""
+"fd_waveTypeTitanNuke",1500,10.000000,"",""
+"fd_waveTypeTitanArc",1500,10.000000,"",""
+"fd_waveComboNukeMortar",1500,10.000000,"",""
+"fd_waveComboArcMortar",1500,10.000000,"",""
+"fd_waveComboArcNuke",1500,10.000000,"",""
+"fd_waveComboNukeCloak",1500,10.000000,"",""
+"fd_waveComboNukeTrain",1500,10.000000,"",""
+"fd_waveComboMultiMix",1500,10.000000,"",""
+"fd_waveTypeReapers",1500,10.000000,"",""
+"fd_waveTypeTicks",1500,10.000000,"",""
+"fd_waveTypeStalkers",1500,10.000000,"",""
+"fd_waveTypeMortarSpectre",1500,10.000000,"",""
+"fd_waveTypeReaperTicks",1500,10.000000,"",""
+"fd_waveTypeEliteTitan",1500,10.000000,"",""
+"fd_waveTypeFlyers",1500,10.000000,"",""
+"fd_baseDeath",3000,10.000000,"",""
+"fd_waveRecapLowHealth",25000,10.000000,"",""
+"fd_waveRecapNearPerfect",2500,10.000000,"",""
+"fd_waveRecapPerfect",2500,10.000000,"",""
+"fd_bigWaveInc",1500,10.000000,"",""
+"fd_finalWaveStartGeneric",1500,10.000000,"",""
+"fd_baseHealthRecharge",2500,10.000000,"",""
+"fd_matchVictory",3000,10.000000,"",""
+"fd_matchDefeat",3000,10.000000,"",""
+"fd_waveCleanup",1500,10.000000,"",""
+"fd_singlePilotDown",2000,10.000000,"",""
+"fd_multiPilotDown",2000,10.000000,"",""
+"fd_onlyPlayerIsAlive",2000,10.000000,"",""
+"fd_pilotRespawn",2000,10.000000,"",""
+"fd_nukeTitanNearBase",1750,10.000000,"",""
+"fd_waveCleanup5",1500,20.000000,"",""
+"fd_waveCleanup4",1500,20.000000,"",""
+"fd_waveCleanup3",1500,20.000000,"",""
+"fd_waveCleanup2",1500,20.000000,"",""
+"fd_waveCleanup1",1500,20.000000,"",""
+"fd_baseShieldTakingDmg",1900,30.000000,"",""
+"fd_baseShieldLow",1910,10.000000,"","fd_baseShieldTakingDmg"
+"fd_baseShieldDown",1930,10.000000,"",""
+"fd_baseShieldUp",1810,8.000000,"","fd_baseShieldTakingDmg fd_baseShieldRecharging"
+"fd_baseShieldRecharging",1800,30.000000,"","fd_baseShieldTakingDmg"
+"fd_baseShieldRechargingShort",1800,30.000000,"",""
+"fd_baseBatteryNagLow",1920,10.000000,"",""
+"fd_baseBatteryNagDown",2000,10.000000,"",""
+"fd_baseShieldLowHolding",2000,10.000000,"",""
+"fd_waveNoTitans",1500,10.000000,"",""
+"fd_incTitansNukeClump",1500,10.000000,"",""
+"fd_incTitansMortarClump",1500,10.000000,"",""
+"fd_incArcTitanClump",1500,10.000000,"",""
+"fd_incCloakDroneClump",1500,10.000000,"",""
+"fd_incReaperClump",1500,10.000000,"",""
+"fd_nagKillTitansMortar",2020,45.000000,"",""
+"fd_nagKillInfantry",1500,45.000000,"",""
+"fd_nagKillStalkers",1000,45.000000,"",""
+"fd_nagKillMortarSpectres",2020,45.000000,"",""
+"fd_nagKillTitanEMP",1500,45.000000,"",""
+"fd_nagTitanArcAtBase",1500,10.000000,"",""
+"fd_baseHealth75",2000,15.000000,"",""
+"fd_baseHealth50",2010,15.000000,"","fd_baseHealth75"
+"fd_baseHealth25",2020,15.000000,"","fd_baseHealth75 fd_baseHealth50"
+"fd_baseLowHealth",2030,15.000000,"","fd_baseHealth75 fd_baseHealth50 fd_baseHealth25"
+"fd_baseHealth50nag",2010,10.000000,"",""
+"fd_baseHealth25nag",2020,10.000000,"",""
+"fd_playerCashNagSurplus",1500,10.000000,"",""
+"fd_playerCashNagReg",1500,10.000000,"",""
+"fd_wavePayoutAddtnl",1500,10.000000,"",""
+"fd_wavePayoutFirst",1500,10.000000,"",""
+"fd_introEasy",1500,10.000000,"",""
+"fd_introMedium",1500,10.000000,"",""
+"fd_introHard",1500,10.000000,"",""
+"fd_turretOffline",1500,10.000000,"",""
+"fd_turretOnline",1500,10.000000,"",""
+"turretKillsLow",1500,10.000000,"",""
+"turretKillsMedium",1500,10.000000,"",""
+"turretKillsHigh",1500,10.000000,"",""
+"turretKillsMega",1500,10.000000,"",""
+"fd_boughtSentryTurret",1500,10.000000,"",""
+"fd_boughtArcTrap",1500,10.000000,"",""
+"fd_boughtCoreOverload",1500,10.000000,"",""
+"fd_playerNeedsToReadyUp",1500,10.000000,"",""
+"fd_boughtAmpedWeapons",1500,10.000000,"",""
+"fd_boughtHarvesterShield",1500,10.000000,"",""
+"fd_boughtBattery",1500,10.000000,"",""
+"matchRecapNoDeaths",1500,10.000000,"",""
+"matchRecapNoPlayerDeath",1500,10.000000,"",""
+"matchRecapPlayerMVP",1500,10.000000,"",""
+"fd_soonNukeTitans",1500,10.000000,"",""
+"fd_soonArcTitans",1500,10.000000,"",""
+"fd_soonMortarTitans",1500,10.000000,"",""
+"fd_stalkerExploNag",1000,300.000000,"",""
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/faction_leaders.csv b/Northstar.CustomServers/mod/scripts/datatable/faction_leaders.csv new file mode 100644 index 00000000..22fb3e45 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/faction_leaders.csv @@ -0,0 +1,8 @@ +persistenceRef,factionDialoguePrefix,logo,image,name,description,factionName,usesWaveform,modelName,skinIndex,menuIdleAnim,propModelName,propAttachment,cost
+"faction_marauder","mcor_sarah","rui/faction/faction_logo_marauder","rui/faction/faction_button_marauder","#FACTION_LEADER_NAME_SARAH","#FACTION_LEADER_DESC_SARAH","#FACTION_MARAUDER",0,"models/humans/heroes/mlt_hero_sarah.mdl",0,"Sarah_menu_pose","models/Weapons/p2011/w_p2011.mdl","KNIFE",100
+"faction_apex","imc_blisk","rui/faction/faction_logo_apex","rui/faction/faction_button_apex","#FACTION_LEADER_NAME_BLISK","#FACTION_LEADER_DESC_BLISK","#FACTION_APEX",0,"models/humans/heroes/imc_hero_blisk.mdl",0,"Blisk_menu_pose","models/Weapons/combat_knife/w_combat_knife.mdl","KNIFE",100
+"faction_vinson","imc_ash","rui/faction/faction_logo_vinson","rui/faction/faction_button_vinson","#FACTION_LEADER_NAME_ASH","#FACTION_LEADER_DESC_ASH","#FACTION_VINSON",0,"models/humans/heroes/imc_hero_ash.mdl",0,"Ash_menu_pose","","",100
+"faction_aces","mcor_barker","rui/faction/faction_logo_aces","rui/faction/faction_button_aces","#FACTION_LEADER_NAME_BARKER","#FACTION_LEADER_DESC_BARKER","#FACTION_ACES",0,"models/humans/heroes/mlt_hero_barker.mdl",0,"Barker_menu_pose","models/props/flask/prop_flask_animated.mdl","PROPGUN",100
+"faction_64","mcor_gates","rui/faction/faction_logo_64","rui/faction/faction_button_64","#FACTION_LEADER_NAME_GATES","#FACTION_LEADER_DESC_GATES","#FACTION_64",0,"models/humans/pilots/sp_medium_geist_f.mdl",0,"Gates_menu_pose","models/Weapons/p2011/w_p2011.mdl","KNIFE",100
+"faction_ares","imc_marder","rui/faction/faction_logo_ares","rui/faction/faction_button_ares","#FACTION_LEADER_NAME_MARDER","#FACTION_LEADER_DESC_MARDER","#FACTION_ARES",0,"models/humans/heroes/imc_hero_marder.mdl",0,"Marder_menu_pose","","",100
+"faction_marvin","mcor_marvin","rui/faction/faction_logo_mrvn","rui/faction/faction_button_mrvn","#FACTION_LEADER_NAME_MARVIN","#FACTION_LEADER_DESC_MARVIN","#FACTION_MARVIN",1,"models/Robots/marvin/marvin.mdl",1,"commander_MP_flyin_marvin_idle","","",100
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/faction_leaders_dropship_anims.csv b/Northstar.CustomServers/mod/scripts/datatable/faction_leaders_dropship_anims.csv new file mode 100644 index 00000000..0d759d93 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/faction_leaders_dropship_anims.csv @@ -0,0 +1,23 @@ +persistenceRef,dropshipAnimName,isEasterEgg
+"faction_marauder","commander_MP_flyin_sarah",0
+"faction_marauder","commander_MP_flyin_sarah_alt",0
+"faction_marauder","commander_MP_flyin_sarah_silent",0
+"faction_apex","commander_MP_flyin_blisk_betta",0
+"faction_apex","commander_MP_flyin_blisk_born",0
+"faction_apex","commander_MP_flyin_blisk_silent",0
+"faction_vinson","commander_MP_flyin_ash_focus",0
+"faction_vinson","commander_MP_flyin_ash_grateful",0
+"faction_vinson","commander_MP_flyin_ash_silent",0
+"faction_aces","commander_MP_flyin_barker",0
+"faction_aces","commander_MP_flyin_barker_victory",0
+"faction_aces","commander_MP_flyin_barker_conductor",0
+"faction_64","commander_MP_flyin_gates_family",0
+"faction_64","commander_MP_flyin_gates_sixfour",0
+"faction_64","commander_MP_flyin_gates_silent",0
+"faction_ares","commander_MP_flyin_marder",0
+"faction_ares","commander_MP_flyin_marder_alt1",0
+"faction_ares","commander_MP_flyin_marder_alt2",0
+"faction_marvin","commander_MP_flyin_marvin_salute",0
+"faction_marvin","commander_MP_flyin_marvin_highfive",0
+"faction_marvin","commander_MP_flyin_marvin_greeter",0
+"faction_marvin","commander_MP_flyin_marvin_freestyle",1
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/fd_awards.csv b/Northstar.CustomServers/mod/scripts/datatable/fd_awards.csv new file mode 100644 index 00000000..01c6254b --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/fd_awards.csv @@ -0,0 +1,15 @@ +ref,priority,displayString,subText,awardDisplayString,displayStyle,image,validityCheck,validityCheckValue,comparisonCheck,needsToBeBest
+"harvesterHeals",5,"#FD_AWARD_0","#FD_AWARD_SUBTEXT_0","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/shielded_harvester","greater_than",1.000000,"highest",1
+"mortarUnitsKilled",3,"#FD_AWARD_1","#FD_AWARD_SUBTEXT_1","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/mortar_units","greater_than",1.000000,"highest",1
+"moneySpent",4,"#FD_AWARD_2","#FD_AWARD_SUBTEXT_2","#FD_AWARD_VALUE_DISPLAY_MONEY","FD_DISPLAY_STYLE_NUMBER","rui/medals/cash_spent","greater_than",2000.000000,"highest",1
+"coresUsed",8,"#FD_AWARD_3","#FD_AWARD_SUBTEXT_3","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/titan_core","greater_than",1.000000,"highest",1
+"longestTitanLife",9,"#FD_AWARD_4","#FD_AWARD_SUBTEXT_4","#FD_AWARD_VALUE_DISPLAY_SECONDS","FD_DISPLAY_STYLE_TIME","rui/medals/least_lost","greater_than",100.000000,"highest",1
+"turretsRepaired",7,"#FD_AWARD_5","#FD_AWARD_SUBTEXT_5","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/turrets_healed","greater_than",5.000000,"highest",1
+"moneyShared",6,"#FD_AWARD_6","#FD_AWARD_SUBTEXT_6","#FD_AWARD_VALUE_DISPLAY_MONEY","FD_DISPLAY_STYLE_NUMBER","rui/medals/cash_shared","greater_than",100.000000,"highest",1
+"damageDealt",1,"#FD_AWARD_7","#FD_AWARD_SUBTEXT_7","#FD_AWARD_VALUE_DISPLAY_POINTS","FD_DISPLAY_STYLE_NUMBER","rui/medals/most_damage","greater_than",-1.000000,"highest",0
+"timeNearHarvester",2,"#FD_AWARD_8","#FD_AWARD_SUBTEXT_8","#FD_AWARD_VALUE_DISPLAY_SECONDS","FD_DISPLAY_STYLE_TIME","rui/medals/harvester_protect","greater_than",200.000000,"highest",1
+"longestLife",0,"#FD_AWARD_9","#FD_AWARD_SUBTEXT_9","#FD_AWARD_VALUE_DISPLAY_SECONDS","FD_DISPLAY_STYLE_TIME","rui/medals/long_life","greater_than",200.000000,"highest",1
+"heals",11,"#FD_AWARD_10","#FD_AWARD_SUBTEXT_10","#FD_AWARD_VALUE_DISPLAY_POINTS","FD_DISPLAY_STYLE_NUMBER","rui/medals/heal","greater_than",5000.000000,"highest",1
+"turretKills",10,"#FD_AWARD_11","#FD_AWARD_SUBTEXT_11","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/turret_damage","greater_than",10.000000,"highest",1
+"mvp",13,"#FD_AWARD_12","#FD_AWARD_SUBTEXT_12","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/mvp","greater_than",2.000000,"highest",1
+"titanKills",12,"#FD_AWARD_13","#FD_AWARD_SUBTEXT_13","#FD_AWARD_VALUE_DISPLAY_BLANK","FD_DISPLAY_STYLE_NUMBER","rui/medals/titans_killed","greater_than",30.000000,"highest",1
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/features_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/features_mp.csv new file mode 100644 index 00000000..8f1b39b3 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/features_mp.csv @@ -0,0 +1,21 @@ +featureRef,featureName,featureDesc,featureIcon,specificType,cost
+"communities","#FEATURE_COMMUNITIES","","rui/hud/common/feature_icon","#ITEM_TYPE_FEATURE",0
+"happy_hour","#FEATURE_HAPPY_HOUR","","rui/hud/common/feature_icon","#ITEM_TYPE_FEATURE",0
+"pilot_loadout_1","#DEFAULT_PILOT_1","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",15
+"pilot_loadout_2","#DEFAULT_PILOT_2","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",15
+"pilot_loadout_3","#DEFAULT_PILOT_3","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",15
+"pilot_loadout_4","#DEFAULT_PILOT_4","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",15
+"pilot_loadout_5","#DEFAULT_PILOT_5","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",15
+"pilot_loadout_6","#DEFAULT_PILOT_6","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",15
+"pilot_loadout_7","#DEFAULT_PILOT_7","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",100
+"pilot_loadout_8","#DEFAULT_PILOT_8","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",100
+"pilot_loadout_9","#DEFAULT_PILOT_9","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",100
+"pilot_loadout_10","#DEFAULT_PILOT_10","","rui/hud/common/feature_icon","#ITEM_TYPE_LOADOUT",100
+"coliseum_ticket","#ITEM_COLISEUM","#ITEM_COLISEUM_DESC","rui/menu/common/ticket_icon","#ITEM_TYPE_PLAYLIST",10
+"double_xp","#DOUBLE_XP","#DOUBLE_XP_DESC","rui/menu/common/dbl_xp_icon","#ITEM_TYPE_DOUBLEXP",0
+"credit_award","#CREDIT_AWARD","#CREDIT_AWARD_DESC","rui/menu/common/credit_symbol_large_color","#ITEM_TYPE_CREDITS",0
+"credit_award_5x","#CREDIT_AWARD_5X","","rui/menu/common/credit_symbol_large_color","#ITEM_TYPE_CREDITS",0
+"advocate_gift","#RANDOM","","rui\menu\common\unlock_random","#UNLOCK_RANDOM",0
+"mp_angel_city","#MP_ANGEL_CITY","","rui/hud/common/feature_icon","#UNLOCK_RANDOM",0
+"random","#RANDOM","","rui\menu\common\unlock_random","#UNLOCK_RANDOM",0
+"classic_music","#CLASSIC_MUSIC","","rui/hud/common/feature_icon","#UNLOCK_CLASSIC_MUSIC",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/flightpath_assets.csv b/Northstar.CustomServers/mod/scripts/datatable/flightpath_assets.csv new file mode 100644 index 00000000..d14566f1 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/flightpath_assets.csv @@ -0,0 +1,8 @@ +name,mp_model,sp_model
+"fp_dropship_model","models/vehicle/goblin_dropship/goblin_dropship.mdl","models/vehicle/goblin_dropship/goblin_dropship.mdl"
+"fp_dropship_hero_model","models/vehicle/goblin_dropship/goblin_dropship_hero.mdl","models/vehicle/goblin_dropship/goblin_dropship_hero.mdl"
+"fp_crow_model","models/vehicle/crow_dropship/crow_dropship.mdl","models/vehicle/crow_dropship/crow_dropship.mdl"
+"fp_crow_hero_model","models/vehicle/crow_dropship/crow_dropship_hero.mdl","models/vehicle/crow_dropship/crow_dropship_hero.mdl"
+"fp_titan_model","models/titans/medium/titan_medium_ajax.mdl","models/titans/medium/sp_titan_medium_ajax.mdl"
+"fp_straton_model","models/vehicle/straton/straton_imc_gunship_01.mdl","models/vehicle/straton/straton_imc_gunship_01.mdl"
+"fp_hornet_model","models/vehicle/hornet/hornet_fighter.mdl","models/vehicle/hornet/hornet_fighter.mdl"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/grunt_chatter_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/grunt_chatter_mp.csv new file mode 100644 index 00000000..c3c15f19 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/grunt_chatter_mp.csv @@ -0,0 +1,47 @@ +conversationname,alias,priority,debounce
+"bc_allygruntdown","bc_allygruntdown",250,20.000000
+"bc_enemytitandown","bc_enemytitandown",250,20.000000
+"bc_enemytitanspotcall","bc_enemytitanspotcall",250,20.000000
+"bc_engageenemycloakedpilot","bc_engageenemycloakedpilot",250,20.000000
+"bc_engagepilotenemy","bc_engagepilotenemy",250,20.000000
+"bc_grenadecall","bc_grenadecall",250,20.000000
+"bc_gruntkillstitan","bc_gruntkillstitan",250,20.000000
+"bc_killenemypilot","bc_killenemypilot",250,20.000000
+"bc_spotenemypilot","bc_spotenemypilot",250,20.000000
+"bc_squaddeplete","bc_squaddeplete",250,20.000000
+"bc_reactGrenadeArc","bc_reactGrenadeArc",250,20.000000
+"bc_reactGrenadeThermite","bc_reactGrenadeThermite",250,20.000000
+"bc_reactGrenadeGravity","bc_reactGrenadeGravity",250,20.000000
+"bc_reactGrenadeElecSmoke","bc_reactGrenadeElecSmoke",250,20.000000
+"bc_grenadeOutCall","bc_grenadeOutCall",250,20.000000
+"bc_fleePlayerTitanCall","bc_spotclosetitancall_01",250,20.000000
+"bc_fleePlayerTitanCall","bc_fleePlayerTitanCall",250,20.000000
+"bc_reactTickSpawnFriendly","bc_reactTickSpawnFriendly_01",250,20.000000
+"bc_reactTickSpawnFriendly","bc_reactTickSpawnFriendly_02",250,20.000000
+"bc_reactTickSpawnFriendly","bc_reactTickSpawnFriendly_03",250,20.000000
+"bc_reactTitanfallFriendlyArrives","bc_reactTitanfallFriendlyArrives_01",250,40.000000
+"bc_reactTitanfallFriendlyArrives","bc_titancheer_01",250,40.000000
+"bc_reactEnemySpotted","bc_engagepilotenemy_01",250,20.000000
+"bc_reactEnemySpotted","bc_engagepilotenemy_02",250,20.000000
+"bc_reactEnemySpotted","bc_engagepilotenemy_06",250,20.000000
+"bc_reactEnemyReaper","diag_sp_ReaperTown_BM102_15_01_mcor_grunt3",250,20.000000
+"bc_reactEnemyReaper","diag_sp_ReaperTown_BM102_16_01_mcor_grunt2",250,20.000000
+"bc_reactReaperFriendlyArrives","bc_reactReaperFriendlyArrives_01",250,40.000000
+"bc_reactFriendlyPilot","diag_sp_ReaperTown_BM103_01a_01_mcor_grunt2",250,180.000000
+"TEMP_bc_reactFriendlyPilot","diag_sp_corkscrew_SE131_02_01_mcor_grunt1",250,180.000000
+"bc_reactFriendlyPilot","diag_sp_corkscrew_SE131_19_01_mcor_grunt1",250,180.000000
+"bc_generalCombat","diag_sp_corkscrew_SE131_21_01_mcor_grunt1",250,20.000000
+"bc_generalCombat","diag_sp_corkscrew_SE131_12_01_mcor_grunt1",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD104_29_01_mcor_grunt6",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD104_24_01_mcor_grunt1",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD103_02_01_mcor_grunt2",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD104_25_01_mcor_grunt2",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD104_26_01_mcor_grunt3",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD104_27_01_mcor_grunt4",250,20.000000
+"bc_generalCombat","diag_sp_intro_WD104_28_01_mcor_grunt5",250,20.000000
+"TEMP_bc_generalNonCombat","diag_sp_ReaperTown_BM102_29a_01_imc_gcaptain",250,100.000000
+"bc_generalNonCombat","diag_sp_ReaperTown_BM103_02a_01_mcor_grunt1",250,100.000000
+"bc_generalCombatTitan","diag_sp_sewerArena_SE151_09_01_imc_grunt1",250,20.000000
+"bc_generalCombatTitan","diag_sp_sewerArena_SE152_01_01_imc_grunt1",250,20.000000
+"bc_generalCombatTitan","diag_sp_intro_WD103_07_01_mcor_grunt1",250,20.000000
+"bc_generalCombatTitan","diag_sp_bigCharge_TD111_06_01_mcor_pilot3",250,20.000000
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/non_loadout_weapons.csv b/Northstar.CustomServers/mod/scripts/datatable/non_loadout_weapons.csv new file mode 100644 index 00000000..8816fd8f --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/non_loadout_weapons.csv @@ -0,0 +1,29 @@ +weapon
+"melee_titan_punch"
+"melee_titan_punch_fighter"
+"melee_titan_punch_ion"
+"melee_titan_punch_tone"
+"melee_titan_punch_northstar"
+"melee_titan_punch_scorch"
+"melee_titan_punch_legion"
+"melee_titan_sword"
+"melee_titan_sword_aoe"
+"mp_titanweapon_flightcore_rockets"
+"mp_titanweapon_orbital_strike"
+"mp_titanweapon_predator_cannon_siege"
+"mp_weapon_spectre_spawner"
+"proto_viewmodel_test"
+"mp_turretweapon_blaster"
+"mp_turretweapon_plasma"
+"mp_turretweapon_sentry"
+"mp_ability_arc_blast"
+"mp_ability_burncardweapon"
+"mp_ability_holopilot_nova"
+"mp_weapon_smart_pistol"
+"mp_weapon_hard_cover"
+"melee_titan_punch_vanguard"
+"mp_titanweapon_rocketeer_rocketstream"
+"mp_titanweapon_shoulder_rockets"
+"mp_ability_swordblock"
+"mp_titanability_nuke_eject"
+"mp_weapon_arc_trap"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pain_death_sounds.csv b/Northstar.CustomServers/mod/scripts/datatable/pain_death_sounds.csv new file mode 100644 index 00000000..00d5e595 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pain_death_sounds.csv @@ -0,0 +1,53 @@ +event,priority,blocksNextPriority,method,bodyType,alias_1p_victim_only,alias_3p_except_victim,alias_3p_attacker_only,alias_3p_except_attacker,spmp
+"death",105,0,"SE_GIB","NPC_GRUNT","","death.pinkmist","","","spmp"
+"death",105,0,"SE_GIB","NPC_MARVIN","","","","","spmp"
+"death",105,0,"SE_GIB","NPC_PROWLER","","","","","spmp"
+"death",105,0,"SE_GIB","NPC_SPECTRE","","","","","spmp"
+"death",105,0,"SE_GIB","NPC_STALKER","","","","","spmp"
+"death",110,1,"SE_HEADSHOT_BULLET","NPC_GRUNT","","","","Flesh.Light.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_BULLET","NPC_MARVIN","","","","Android.Light.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_BULLET","NPC_SPECTRE","","","","Android.Light.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_BULLET","NPC_STALKER","","","","Android.Light.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_SHOTGUN","NPC_GRUNT","","","","Flesh.Shotgun.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_SHOTGUN","NPC_MARVIN","","","","Android.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_SHOTGUN","NPC_SPECTRE","","","","Android.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_SHOTGUN","NPC_STALKER","","","","Android.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_TITAN","NPC_GRUNT","","","","Flesh.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_TITAN","NPC_MARVIN","","","","Android.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_TITAN","NPC_SPECTRE","","","","Android.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",110,1,"SE_HEADSHOT_TITAN","NPC_STALKER","","","","Android.Heavy.BulletImpact_Headshot_3P_vs_3P","spmp"
+"death",120,1,"SE_NECK_SNAP","NPC_GRUNT","","diag_efforts_DeathNeck_gl_grunt_3p","","","spmp"
+"death",140,1,"SE_DISSOLVE","NPC_GRUNT","","diag_efforts_DeathBurn_gl_grunt_3p","","","spmp"
+"death",160,1,"SE_ELECTRICAL","NPC_GRUNT","","diag_efforts_DeathElec_gl_grunt_3p","","","spmp"
+"death",180,1,"SE_EXPLOSION","NPC_GRUNT","","diag_efforts_DeathExplo_gl_grunt_3p","","","spmp"
+"death",200,1,"SE_FALL","NPC_GRUNT","","diag_efforts_DeathFall_gl_grunt_3p","","","spmp"
+"death",220,1,"SE_PROWLER","NPC_GRUNT","","diag_efforts_DeathProwler_gl_grunt_3p","","","spmp"
+"death",290,1,"SE_TITAN_STEP","NPC_GRUNT","","titan_grunt_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","NPC_MARVIN","","titan_spectre_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","NPC_SPECTRE","","titan_spectre_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","NPC_STALKER","","titan_spectre_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","NPC_PROWLER","","titan_grunt_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_HUMAN_MALE","","titan_grunt_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_HUMAN_MALE","","titan_grunt_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_ANDROID_MALE","","titan_spectre_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_HUMAN_FEMALE","","titan_grunt_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_ANDROID_FEMALE","","titan_spectre_squish","","","spmp"
+"death",290,1,"SE_TITAN_STEP","NPC_GRUNT","","diag_efforts_DeathCrush_gl_grunt_3p","","","spmp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_HUMAN_MALE","diag_efforts_DeathCrush_sp_cooper_3p_vs_1p","diag_efforts_DeathCrush_mp_maleHuman_3p","","","sp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_HUMAN_MALE","diag_efforts_DeathCrush_mp_maleHuman_3p_vs_1p","diag_efforts_DeathCrush_mp_maleHuman_3p","","","mp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_ANDROID_MALE","diag_efforts_DeathCrush_mp_maleRobot_3p_vs_1p","diag_efforts_DeathCrush_mp_maleRobot_3p","","","mp"
+"death",290,1,"SE_TITAN_STEP","PLAYER_HUMAN_FEMALE","diag_efforts_DeathCrush_mp_femaleHuman_3p_vs_1p","diag_efforts_DeathCrush_mp_femaleHuman_3p","","","mp"
+"death",400,1,"SE_ANY","NPC_MARVIN","","marvin_death","","","spmp"
+"death",400,1,"SE_TITAN_STEP","PLAYER_ANDROID_FEMALE","diag_efforts_DeathCrush_mp_femaleRobot_3p_vs_1p","diag_efforts_DeathCrush_mp_femaleRobot_3p","","","mp"
+"death",500,1,"SE_ANY","NPC_GRUNT","","diag_efforts_DeathQuick_gl_grunt_3p","","","spmp"
+"death",500,1,"SE_ANY","TITAN","titan_death_explode","titan_death_explode","","","spmp"
+"pain",300,1,"SE_ELECTRICAL","NPC_GRUNT","","diag_efforts_hitByArc_gl_grunt_3p","","","spmp"
+"pain",300,1,"SE_THERMITE_GRENADE","NPC_GRUNT","","diag_efforts_burns_gl_grunt_3p","","","spmp"
+"pain",400,0,"SE_PROWLER","NPC_GRUNT","","diag_efforts_hitByProwler_gl_grunt_3p","","","spmp"
+"pain",400,0,"SE_SMOKE","NPC_GRUNT","","diag_efforts_cough_gl_grunt_3p","","","spmp"
+"pain",400,0,"SE_ANY","NPC_GRUNT","","diag_efforts_hits_gl_grunt_3p","","","spmp"
+"pain",400,0,"SE_ANY","PLAYER_ANDROID_FEMALE","diag_efforts_hits_mp_femaleRobot_3p_vs_1p","","","","mp"
+"pain",400,0,"SE_ANY","PLAYER_ANDROID_MALE","diag_efforts_hits_mp_maleRobot_3p_vs_1p","","","","mp"
+"pain",400,0,"SE_ANY","PLAYER_HUMAN_FEMALE","diag_efforts_hits_mp_femaleHuman_3p_vs_1p","","","","mp"
+"pain",400,0,"SE_ANY","PLAYER_HUMAN_MALE","diag_efforts_hits_mp_maleHuman_3p_vs_1p","","","","mp"
+"pain",400,0,"SE_ANY","PLAYER_HUMAN_MALE","diag_efforts_hits_sp_cooper_3p_vs_1p","","","","sp"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_abilities.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_abilities.csv new file mode 100644 index 00000000..e9949479 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_abilities.csv @@ -0,0 +1,16 @@ +itemRef,type,damageSource,hidden,cost
+"mp_ability_grapple","PILOT_SPECIAL",0,0,180
+"mp_ability_heal","PILOT_SPECIAL",0,0,180
+"mp_ability_holopilot","PILOT_SPECIAL",0,0,180
+"mp_weapon_grenade_sonar","PILOT_SPECIAL",1,0,180
+"mp_ability_shifter","PILOT_SPECIAL",0,0,180
+"mp_weapon_deployable_cover","PILOT_SPECIAL",0,0,180
+"mp_ability_cloak","PILOT_SPECIAL",0,0,180
+"mp_weapon_frag_grenade","PILOT_ORDNANCE",1,0,220
+"mp_weapon_grenade_emp","PILOT_ORDNANCE",1,0,220
+"mp_weapon_grenade_gravity","PILOT_ORDNANCE",1,0,220
+"mp_weapon_grenade_electric_smoke","PILOT_ORDNANCE",1,0,220
+"mp_weapon_thermite_grenade","PILOT_ORDNANCE",1,0,220
+"mp_weapon_satchel","PILOT_ORDNANCE",1,0,220
+"melee_pilot_sword","NOT_LOADOUT",1,1,220
+"mp_ability_shifter_super","PILOT_SPECIAL",0,1,220
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_executions.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_executions.csv new file mode 100644 index 00000000..faae9db7 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_executions.csv @@ -0,0 +1,14 @@ +ref,name,description,image,hidden,cost
+"execution_neck_snap","#PILOT_EXECUTION_NECK_SNAP","#PILOT_EXECUTION_NECK_SNAP_DESC","rui/pilot_loadout/execution/execution_neck_snap",0,0
+"execution_face_stab","#PILOT_EXECUTION_FACE_STAB","#PILOT_EXECUTION_FACE_STAB_DESC","rui/pilot_loadout/execution/execution_face_stab",0,300
+"execution_backshot","#PILOT_EXECUTION_BACK_SHOT","#PILOT_EXECUTION_BACK_SHOT_DESC","rui/pilot_loadout/execution/execution_backshot",0,300
+"execution_combo","#PILOT_EXECUTION_COMBO","#PILOT_EXECUTION_COMBO_DESC","rui/pilot_loadout/execution/execution_combo",0,300
+"execution_knockout","#PILOT_EXECUTION_KNOCKOUT","#PILOT_EXECUTION_KNOCKOUT_DESC","rui/pilot_loadout/execution/execution_knockout",0,300
+"execution_telefrag","#PILOT_EXECUTION_TELEFRAG","#PILOT_EXECUTION_TELEFRAG_DESC","rui/pilot_loadout/execution/execution_inner_pieces",0,0
+"execution_stim","#PILOT_EXECUTION_STIM","#PILOT_EXECUTION_STIM_DESC","rui/pilot_loadout/execution/execution_straight_blast",0,0
+"execution_grapple","#PILOT_EXECUTION_GRAPPLE","#PILOT_EXECUTION_GRAPPLE_DESC","rui/pilot_loadout/execution/execution_grapple",0,0
+"execution_pulseblade","#PILOT_EXECUTION_PULSEBLADE","#PILOT_EXECUTION_PULSEBLADE_DESC","rui/pilot_loadout/execution/execution_pulseblade",0,0
+"execution_random","#PILOT_EXECUTION_RANDOM","#PILOT_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0
+"execution_cloak","#PILOT_EXECUTION_CLOAK","#PILOT_EXECUTION_CLOAK_DESC","rui/pilot_loadout/execution/execution_now_you_see_me",0,0
+"execution_holopilot","#PILOT_EXECUTION_HOLOPILOT","#PILOT_EXECUTION_HOLOPILOT_DESC","rui/pilot_loadout/execution/execution_holopilot",0,0
+"execution_ampedwall","#PILOT_EXECUTION_AMPEDWALL","#PILOT_EXECUTION_AMPEDWALL_DESC","rui/pilot_loadout/execution/execution_amped_wall",0,0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_passives.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_passives.csv new file mode 100644 index 00000000..a13a98f2 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_passives.csv @@ -0,0 +1,10 @@ +passive,type,name,description,image,hidden,cost
+"pas_enemy_death_icons","PILOT_PASSIVE2","#GEAR_ENEMY_DEATH_ICONS","#GEAR_ENEMY_DEATH_ICONS_DESC","rui/pilot_loadout/kit/kill_report_menu",0,25
+"pas_ordnance_pack","PILOT_PASSIVE1","#GEAR_EXPLOSIVES_PACK","#GEAR_EXPLOSIVES_PACK_DESC","rui/pilot_loadout/kit/ordnance_expert_menu",0,125
+"pas_power_cell","PILOT_PASSIVE1","#GEAR_POWER_CELL","#GEAR_POWER_CELL_DESC","rui/pilot_loadout/kit/power_cell_menu",0,25
+"pas_fast_embark","PILOT_PASSIVE1","#GEAR_FAST_EMBARK","#GEAR_FAST_EMBARK_DESC","rui/pilot_loadout/kit/phase_embark_menu",0,125
+"pas_ads_hover","PILOT_PASSIVE2","#GEAR_ADS_HOVER","#GEAR_ADS_HOVER_DESC","rui/pilot_loadout/kit/hover_menu",0,225
+"pas_wallhang","PILOT_PASSIVE2","#GEAR_WALLHANG","#GEAR_WALLHANG_DESC","rui/pilot_loadout/kit/wall_hang_menu",0,25
+"pas_fast_health_regen","PILOT_PASSIVE1","#GEAR_FAST_HEALTH_REGEN","#GEAR_FAST_HEALTH_REGEN_DESC","rui/pilot_loadout/kit/quick_regen_menu",0,25
+"pas_stealth_movement","PILOT_PASSIVE2","#GEAR_STEALTH_KIT","#GEAR_STEALTH_KIT_DESC","rui/pilot_loadout/kit/stealth_movement_menu",0,225
+"pas_at_hunter","PILOT_PASSIVE2","#GEAR_AT_HUNTER_KIT","#GEAR_AT_HUNTER_KIT_DESC","rui/pilot_loadout/kit/titan_hunter_menu",0,225
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_properties.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_properties.csv new file mode 100644 index 00000000..6e40e332 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_properties.csv @@ -0,0 +1,8 @@ +type,image,tactical,defaultPassive1,defaultPassive2,melee,cost
+"nomad","rui/pilot_loadout/suit/nomad","mp_ability_heal","pas_power_cell","pas_enemy_death_icons","melee_pilot_emptyhanded",180
+"light","rui/pilot_loadout/suit/light","mp_ability_shifter","pas_fast_health_regen","pas_wallhang","melee_pilot_emptyhanded",180
+"geist","rui/pilot_loadout/suit/geist","mp_ability_cloak","pas_power_cell","pas_enemy_death_icons","melee_pilot_emptyhanded",180
+"medium","rui/pilot_loadout/suit/medium","mp_weapon_grenade_sonar","pas_fast_health_regen","pas_wallhang","melee_pilot_emptyhanded",180
+"grapple","rui/pilot_loadout/suit/grapple","mp_ability_grapple","pas_power_cell","pas_wallhang","melee_pilot_emptyhanded",180
+"heavy","rui/pilot_loadout/suit/heavy","mp_weapon_deployable_cover","pas_fast_health_regen","pas_enemy_death_icons","melee_pilot_emptyhanded",180
+"stalker","rui/pilot_loadout/suit/stalker","mp_ability_holopilot","pas_power_cell","pas_enemy_death_icons","melee_pilot_emptyhanded",180
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_features.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_features.csv new file mode 100644 index 00000000..2226eb79 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_features.csv @@ -0,0 +1,5 @@ +featureRef,featureName,featureDesc,featureIcon,cost
+"primarymod2","#EXTRA_MOD","","rui/hud/common/feature_icon",0
+"secondarymod2","#EXTRA_MOD","","rui/hud/common/feature_icon",0
+"primarymod3","#MOD_PRO_SCREEN_NAME","","rui/hud/common/feature_icon",0
+"secondarymod3","#MOD_PRO_SCREEN_NAME","","rui/hud/common/feature_icon",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_mods.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_mods.csv new file mode 100644 index 00000000..b59acb18 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_mods.csv @@ -0,0 +1,250 @@ +mod,weapon,statDamage,statAccuracy,statRange,statFireRate,statClipSize,hidden
+"extended_ammo","mp_weapon_r97",0,0,0,0,10,0
+"extended_ammo","mp_weapon_shotgun",0,0,0,0,3,0
+"extended_ammo","mp_weapon_mastiff",0,0,0,0,3,0
+"extended_ammo","mp_weapon_car",0,0,0,0,10,0
+"extended_ammo","mp_weapon_rspn101",0,0,0,0,6,0
+"extended_ammo","mp_weapon_rspn101_og",0,0,0,0,6,0
+"extended_ammo","mp_weapon_hemlok",0,0,0,0,6,0
+"extended_ammo","mp_weapon_g2",0,0,0,0,4,0
+"extended_ammo","mp_weapon_vinson",0,0,0,0,6,0
+"extended_ammo","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"extended_ammo","mp_weapon_alternator_smg",0,0,0,0,0,0
+"extended_ammo","mp_weapon_wingman",0,0,0,0,0,0
+"extended_ammo","mp_weapon_wingman_n",0,0,0,0,0,0
+"extended_ammo","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"extended_ammo","mp_weapon_sniper",0,0,0,0,0,0
+"extended_ammo","mp_weapon_defender",0,0,0,0,0,0
+"extended_ammo","mp_weapon_dmr",0,0,0,0,0,0
+"extended_ammo","mp_weapon_doubletake",0,0,0,0,0,0
+"extended_ammo","mp_weapon_softball",0,0,0,0,0,0
+"extended_ammo","mp_weapon_epg",0,0,0,0,0,0
+"extended_ammo","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"extended_ammo","mp_weapon_smr",0,0,0,0,0,0
+"extended_ammo","mp_weapon_rocket_launcher",0,0,0,0,0,0
+"extended_ammo","mp_weapon_mgl",0,0,0,0,0,0
+"extended_ammo","mp_weapon_arc_launcher",0,0,0,0,0,0
+"extended_ammo","mp_weapon_semipistol",0,0,0,0,0,0
+"extended_ammo","mp_weapon_autopistol",0,0,0,0,0,0
+"extended_ammo","mp_weapon_lmg",0,0,0,0,0,0
+"extended_ammo","mp_weapon_lstar",0,0,0,0,0,0
+"extended_ammo","mp_weapon_esaw",0,0,0,0,0,0
+"silencer","mp_weapon_wingman",0,0,0,0,0,0
+"silencer","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"silencer","mp_weapon_autopistol",0,0,0,0,0,0
+"silencer","mp_weapon_semipistol",0,0,0,0,0,0
+"hcog","mp_weapon_rspn101",0,0,0,0,0,0
+"hcog","mp_weapon_rspn101_og",0,0,0,0,0,0
+"hcog","mp_weapon_hemlok",0,0,0,0,0,0
+"hcog","mp_weapon_g2",0,0,0,0,0,0
+"hcog","mp_weapon_vinson",0,0,0,0,0,0
+"hcog","mp_weapon_alternator_smg",0,0,0,0,0,0
+"redline_sight","mp_weapon_r97",0,0,0,0,0,0
+"redline_sight","mp_weapon_car",0,0,0,0,0,0
+"redline_sight","mp_weapon_rspn101",0,0,0,0,0,0
+"redline_sight","mp_weapon_rspn101_og",0,0,0,0,0,0
+"redline_sight","mp_weapon_hemlok",0,0,0,0,0,0
+"redline_sight","mp_weapon_g2",0,0,0,0,0,0
+"redline_sight","mp_weapon_lmg",0,0,0,0,0,0
+"redline_sight","mp_weapon_vinson",0,0,0,0,0,0
+"redline_sight","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"redline_sight","mp_weapon_alternator_smg",0,0,0,0,0,0
+"redline_sight","mp_weapon_lstar",0,0,0,0,0,0
+"redline_sight","mp_weapon_esaw",0,0,0,0,0,0
+"redline_sight","mp_weapon_shotgun",0,0,0,0,0,0
+"redline_sight","mp_weapon_mastiff",0,0,0,0,0,0
+"aog","mp_weapon_lstar",0,0,0,0,0,0
+"aog","mp_weapon_lmg",0,0,0,0,0,0
+"aog","mp_weapon_esaw",0,0,0,0,0,0
+"holosight","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"holosight","mp_weapon_car",0,0,0,0,0,0
+"holosight","mp_weapon_r97",0,0,0,0,0,0
+"holosight","mp_weapon_shotgun",0,0,0,0,0,0
+"holosight","mp_weapon_mastiff",0,0,0,0,0,0
+"scope_4x","mp_weapon_dmr",0,0,0,0,0,0
+"scope_4x","mp_weapon_sniper",0,0,0,0,0,0
+"scope_4x","mp_weapon_doubletake",0,0,0,0,0,0
+"ricochet","mp_weapon_sniper",0,0,0,0,0,0
+"ricochet","mp_weapon_doubletake",0,0,0,0,0,0
+"ricochet","mp_weapon_wingman_n",0,0,0,0,0,0
+"threat_scope","mp_weapon_rspn101",0,0,0,0,0,0
+"threat_scope","mp_weapon_rspn101_og",0,0,0,0,0,0
+"threat_scope","mp_weapon_vinson",0,0,0,0,0,0
+"threat_scope","mp_weapon_hemlok",0,0,0,0,0,0
+"threat_scope","mp_weapon_g2",0,0,0,0,0,0
+"threat_scope","mp_weapon_car",0,0,0,0,0,0
+"threat_scope","mp_weapon_r97",0,0,0,0,0,0
+"threat_scope","mp_weapon_alternator_smg",0,0,0,0,0,0
+"threat_scope","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"threat_scope","mp_weapon_sniper",0,0,0,0,0,0
+"threat_scope","mp_weapon_dmr",0,0,0,0,0,0
+"threat_scope","mp_weapon_doubletake",0,0,0,0,0,0
+"threat_scope","mp_weapon_lmg",0,0,0,0,0,0
+"threat_scope","mp_weapon_lstar",0,0,0,0,0,0
+"threat_scope","mp_weapon_esaw",0,0,0,0,0,0
+"threat_scope","mp_weapon_shotgun",0,0,0,0,0,0
+"threat_scope","mp_weapon_mastiff",0,0,0,0,0,0
+"quick_charge","mp_weapon_defender",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_rspn101",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_rspn101_og",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_vinson",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_hemlok",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_g2",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_car",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_r97",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_alternator_smg",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_lmg",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_lstar",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_esaw",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_sniper",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_dmr",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_doubletake",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_wingman",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_wingman_n",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_autopistol",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_semipistol",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_shotgun",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_mastiff",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_softball",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_epg",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"tactical_cdr_on_kill","mp_weapon_smr",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_rspn101",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_rspn101_og",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_vinson",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_hemlok",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_g2",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_car",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_r97",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_alternator_smg",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_lmg",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_lstar",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_esaw",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_sniper",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_dmr",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_doubletake",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_wingman",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_wingman_n",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_autopistol",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_semipistol",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_shotgun",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_mastiff",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_softball",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_epg",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_smr",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_defender",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_rocket_launcher",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_mgl",0,0,0,0,0,0
+"pas_fast_ads","mp_weapon_arc_launcher",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_rspn101",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_rspn101_og",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_vinson",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_hemlok",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_g2",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_car",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_r97",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_alternator_smg",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_lmg",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_lstar",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_esaw",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_sniper",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_dmr",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_doubletake",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_shotgun",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_mastiff",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_softball",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_epg",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_smr",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_defender",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_rocket_launcher",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_mgl",0,0,0,0,0,0
+"pas_fast_swap","mp_weapon_arc_launcher",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_rspn101",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_rspn101_og",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_vinson",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_hemlok",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_g2",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_car",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_r97",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_alternator_smg",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_lmg",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_lstar",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_esaw",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_sniper",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_dmr",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_doubletake",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_wingman",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_wingman_n",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_autopistol",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_semipistol",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_shotgun",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_mastiff",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_softball",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_epg",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_smr",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_rocket_launcher",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_mgl",0,0,0,0,0,0
+"pas_fast_reload","mp_weapon_arc_launcher",0,0,0,0,0,0
+"pro_screen","mp_weapon_r97",0,0,0,0,0,0
+"pro_screen","mp_weapon_shotgun",0,0,0,0,0,0
+"pro_screen","mp_weapon_mastiff",0,0,0,0,0,0
+"pro_screen","mp_weapon_car",0,0,0,0,0,0
+"pro_screen","mp_weapon_rspn101",0,0,0,0,0,0
+"pro_screen","mp_weapon_rspn101_og",0,0,0,0,0,0
+"pro_screen","mp_weapon_hemlok",0,0,0,0,0,0
+"pro_screen","mp_weapon_g2",0,0,0,0,0,0
+"pro_screen","mp_weapon_vinson",0,0,0,0,0,0
+"pro_screen","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"pro_screen","mp_weapon_alternator_smg",0,0,0,0,0,0
+"pro_screen","mp_weapon_wingman",0,0,0,0,0,0
+"pro_screen","mp_weapon_wingman_n",0,0,0,0,0,0
+"pro_screen","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"pro_screen","mp_weapon_sniper",0,0,0,0,0,0
+"pro_screen","mp_weapon_defender",0,0,0,0,0,0
+"pro_screen","mp_weapon_dmr",0,0,0,0,0,0
+"pro_screen","mp_weapon_doubletake",0,0,0,0,0,0
+"pro_screen","mp_weapon_softball",0,0,0,0,0,0
+"pro_screen","mp_weapon_epg",0,0,0,0,0,0
+"pro_screen","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"pro_screen","mp_weapon_smr",0,0,0,0,0,0
+"pro_screen","mp_weapon_rocket_launcher",0,0,0,0,0,0
+"pro_screen","mp_weapon_mgl",0,0,0,0,0,0
+"pro_screen","mp_weapon_arc_launcher",0,0,0,0,0,0
+"pro_screen","mp_weapon_semipistol",0,0,0,0,0,0
+"pro_screen","mp_weapon_autopistol",0,0,0,0,0,0
+"pro_screen","mp_weapon_lmg",0,0,0,0,0,0
+"pro_screen","mp_weapon_lstar",0,0,0,0,0,0
+"pro_screen","mp_weapon_esaw",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_r97",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_shotgun",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_mastiff",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_car",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_rspn101",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_rspn101_og",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_hemlok",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_g2",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_vinson",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_hemlok_smg",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_alternator_smg",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_wingman",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_wingman_n",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_shotgun_pistol",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_softball",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_epg",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_pulse_lmg",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_smr",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_semipistol",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_autopistol",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_lmg",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_lstar",0,0,0,0,0,0
+"pas_run_and_gun","mp_weapon_esaw",0,0,0,0,0,0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_mods_common.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_mods_common.csv new file mode 100644 index 00000000..4718c126 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapon_mods_common.csv @@ -0,0 +1,27 @@ +mod,type,name,shortName,description,image,cost,costSniper,costPistol,costAT
+"iron_sights","attachment","#FACTORY_ISSUE_NAME","","#FACTORY_ISSUE_SIGHT_DESC","r2_ui/menus/loadout_icons/attachments/iron_sights",0,0,0,0
+"holosight","attachment","#MOD_HOLOSIGHT_NAME","","#MOD_HOLOSIGHT_DESC","r2_ui/menus/loadout_icons/attachments/holosight",0,0,0,0
+"hcog","attachment","#MOD_HCOG_NAME","HCOG","#MOD_HCOG_DESC","r2_ui/menus/loadout_icons/attachments/hcog_ranger",0,0,0,0
+"aog","attachment","#MOD_AOG_NAME","AOG","#MOD_AOG_DESC","r2_ui/menus/loadout_icons/attachments/aog",0,0,0,0
+"scope_4x","attachment","#MOD_SCOPE_4X_NAME","","#MOD_SCOPE_4X_DESC","r2_ui/menus/loadout_icons/attachments/variable_zoom",0,0,0,0
+"scope_6x","attachment","4x Zoom Scope","4x Zoom","#MOD_SCOPE_4X_DESC","ui/menu/items/attachment_icons/scope_6x",0,0,0,0
+"redline_sight","attachment","#MOD_ZOOM_SIGHT_NAME","#MOD_ZOOM_SIGHT_NAME","#MOD_ZOOM_SIGHT_DESC","r2_ui/menus/loadout_icons/attachments/hcog",0,0,0,0
+"threat_scope","attachment","#MOD_THREAT_SIGHT_NAME","T-Scope","#MOD_THREAT_SIGHT_DESC","r2_ui/menus/loadout_icons/attachments/threat_scope",0,0,0,0
+"extended_ammo","mod","#MOD_EXTENDED_AMMO_NAME","Ext. Mag","#MOD_EXTENDED_AMMO_DESC","rui/pilot_loadout/mods/extended_ammo",0,0,0,0
+"silencer","mod","#MOD_SILENCER_NAME","Suppressor","#MOD_SILENCER_DESC","r2_ui/menus/loadout_icons/attachments/suppressor",0,0,0,0
+"stabilizer","mod","Stabilizer","Stabilizer","Reduces sway when looking down scope","ui/menu/items/mod_icons/stabilizer",0,0,0,0
+"slammer","mod","Slammer","Slammer","Increases rodeo damage","ui/menu/items/mod_icons/slammer",0,0,0,0
+"enhanced_targeting","mod","Enhanced Targeting","E. Targeting","Enables multiple lock-on capability","ui/menu/items/mod_icons/enhanced_targeting",0,0,0,0
+"single_lock","mod","Single Lock","Single Lock","Single Lock on Pilots","ui/menu/items/mod_icons/enhanced_targeting",0,0,0,0
+"ricochet","mod","#MOD_RICOCHET_NAME","Ricochet","#MOD_RICOCHET_DESC","rui/pilot_loadout/mods/ricochet",0,0,0,0
+"ar_trajectory","mod","Ar Trajectory","Ar Trajectory","Displays estimated trajectory","rui/pilot_loadout/mods/ar_trajectory",0,0,0,0
+"alt_spread","mod","Alt Spread","Alt Spread","Alternate spread pattern","ui/temp",0,0,0,0
+"delayed_shot","mod","Soft Launch","Soft Launch","Delayed ignition with fast rockets","ui/temp",0,0,0,0
+"quick_charge","mod","#MOD_CHARGE_HACK_NAME","Charge Hack","#MOD_CHARGE_HACK_DESC","rui/pilot_loadout/mods/charge_hack",0,0,0,0
+"pas_run_and_gun","mod","#MOD_GUNRUNNER_NAME","Gunrunner","#MOD_GUNRUNNER_DESC","rui/pilot_loadout/mods/gunrunner",0,0,0,0
+"tactical_cdr_on_kill","mod","#MOD_TACTIKILL_NAME","Tactikill","#MOD_TACTIKILL_DESC","rui/pilot_loadout/mods/tactikill",0,0,0,0
+"pas_fast_ads","mod","#MOD_GUN_READY_NAME","Fast ADS","#MOD_GUN_READY_DESC","rui/pilot_loadout/mods/gun_ready",0,0,0,0
+"pas_fast_swap","mod","#MOD_SPEED_TRANSITION_NAME","Fast Swap","#MOD_SPEED_TRANSITION_DESC","rui/pilot_loadout/mods/speed_transition",0,0,0,0
+"pas_fast_reload","mod","#GEAR_QUICK_RELOAD","#GEAR_QUICK_RELOAD","#GEAR_QUICK_RELOAD_DESC","rui/pilot_loadout/kit/speed_loader",0,0,0,0
+"pro_screen","mod3","#MOD_PRO_SCREEN_NAME","Pro Screen","#MOD_PRO_SCREEN_DESC","rui/pilot_loadout/mods/pro_screen",0,0,0,0
+"rocket_arena","mod","#MOD_PRO_SCREEN_NAME","Pro Screen","#MOD_PRO_SCREEN_DESC","rui/pilot_loadout/mods/pro_screen",0,0,0,0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/pilot_weapons.csv b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapons.csv new file mode 100644 index 00000000..d8bbfb0a --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/pilot_weapons.csv @@ -0,0 +1,33 @@ +itemRef,type,defaultAttachment,defaultMod1,defaultMod2,defaultMod3,hidden,xpPerLevelType,cost
+"mp_weapon_r97","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_alternator_smg","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_car","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_hemlok_smg","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_lmg","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_lstar","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_esaw","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_rspn101","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_vinson","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_hemlok","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_g2","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_shotgun","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_mastiff","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_dmr","PILOT_PRIMARY","","","","",0,"sniper",100
+"mp_weapon_doubletake","PILOT_PRIMARY","","","","",0,"sniper",100
+"mp_weapon_sniper","PILOT_PRIMARY","","","","",0,"sniper",100
+"mp_weapon_epg","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_smr","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_pulse_lmg","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_softball","PILOT_PRIMARY","","","","",0,"default",100
+"mp_weapon_autopistol","PILOT_SECONDARY","","","","",0,"pistol",50
+"mp_weapon_semipistol","PILOT_SECONDARY","","","","",0,"pistol",50
+"mp_weapon_wingman","PILOT_SECONDARY","","","","",0,"pistol",50
+"mp_weapon_shotgun_pistol","PILOT_PRIMARY","","","","",0,"default",50
+"mp_weapon_rocket_launcher","PILOT_SECONDARY","","","","",0,"antititan",50
+"mp_weapon_arc_launcher","PILOT_SECONDARY","","","","",0,"antititan",50
+"mp_weapon_defender","PILOT_SECONDARY","","","","",0,"antititan",50
+"mp_weapon_mgl","PILOT_SECONDARY","","","","",0,"antititan",50
+"melee_pilot_emptyhanded","PILOT_MELEE","","","","",0,"default",100
+"melee_pilot_arena","PILOT_MELEE","","","","",0,"default",100
+"mp_weapon_wingman_n","PILOT_PRIMARY","","","","",0,"default",50
+"mp_weapon_rspn101_og","PILOT_PRIMARY","","","","",0,"default",100
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/playlist_items.csv b/Northstar.CustomServers/mod/scripts/datatable/playlist_items.csv new file mode 100644 index 00000000..f485fe70 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/playlist_items.csv @@ -0,0 +1,27 @@ +playlist,name,image,thumbnail,cost
+"at","#PL_attrition","rui/menu/gametype_select/bounty_hunt","rui/menu/gametype_select/playlist_bounty_hunt",5
+"aitdm","#PL_aitdm","rui/menu/gametype_select/attrition","rui/menu/gametype_select/playlist_attrition",5
+"cp","#PL_hardpoint","rui/menu/gametype_select/hardpoint","rui/menu/gametype_select/playlist_amped_hardpoint",5
+"ctf","#PL_capture_the_flag","rui/menu/gametype_select/capture_the_flag","rui/menu/gametype_select/playlist_ctf",5
+"lts","#PL_last_titan_standing","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_lts",5
+"tdm","#PL_pilot_hunter","rui/menu/gametype_select/pilot_hunter","rui/menu/gametype_select/playlist_skirmish",5
+"varietypack","Variety Pack","rui/menu/gametype_select/variety_pack","rui/menu/gametype_select/playlist_gen_weapon",5
+"coliseum","#PL_coliseum","rui/menu/gametype_select/colosseum","rui/menu/gametype_select/playlist_coliseum",0
+"fnf","Friday Night Fights","rui/menu/gametype_select/friday_night_fights","rui/menu/gametype_select/playlist_gen_star",5
+"ffa","#PL_ffa","rui/menu/gametype_select/free_for_all","rui/menu/gametype_select/playlist_free_for_all",5
+"ps","#PL_pilot_skirmish","rui/menu/gametype_select/pilot_v_pilot","rui/menu/gametype_select/playlist_pilot_vs_pilot",5
+"default","Default","rui/menu/gametype_select/bounty_hunt","rui/menu/gametype_select/playlist_gen_star",5
+"fw","#PL_titan_war","rui/menu/gametype_select/titan_war","rui/menu/gametype_select/playlist_gen_arrow",5
+"private_match","#PL_private_match","rui/menu/gametype_select/private_match","rui/menu/gametype_select/playlist_gen_star",0
+"lf","#PL_speedball","rui/menu/gametype_select/hardcore_pilot_hunter","rui/menu/gametype_select/playlist_live_fire",5
+"angel_city_247","#PL_angel_city","rui/menu/gametype_select/angel_city","rui/menu/gametype_select/playlist_gen_star",5
+"hunted","#PL_hunted","rui/menu/gametype_select/variety_pack","rui/menu/gametype_select/playlist_apex",5
+"mfd","#PL_mfd","rui/menu/gametype_select/pilot_hunter","rui/menu/gametype_select/playlist_marked_for_death",5
+"speedball","#PL_speedball","rui/menu/gametype_select/hardcore_pilot_hunter","rui/menu/gametype_select/playlist_live_fire",0
+"fd_easy","#PL_fd_easy","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_fd_easy",0
+"fd","#PL_fd_normal","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_fd_normal",0
+"fd_normal","#PL_fd_normal","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_fd_normal",0
+"fd_hard","#PL_fd_hard","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_fd_hard",0
+"fd_master","#PL_fd_master","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_fd_master",0
+"fd_insane","#PL_fd_insane","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_fd_insane",0
+"ttdm","#PL_titan_brawl","rui/menu/gametype_select/last_titan_standing","rui/menu/gametype_select/playlist_titan_brawl",5
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/score_events.csv b/Northstar.CustomServers/mod/scripts/datatable/score_events.csv new file mode 100644 index 00000000..d71d3ac9 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/score_events.csv @@ -0,0 +1,221 @@ +name,splashText,medalText,pointValue,burnPointValue,pointType,xpValue,xpValueTitan,xpValueWeapon,xpValueFaction,xpType,displayType,medalIcon,conversation,scaleScoreForAutoTitan
+"AttritionAirDroneKilled","#SCORE_EVENT_AT_AIR_DRONE_KILLED","#SCORE_EVENT_AT_AIR_DRONE_KILLED","ATTRITION_SCORE_AIR_DRONE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionBossKilled","#SCORE_EVENT_AT_BOSS_KILLED","#SCORE_EVENT_AT_BOSS_KILLED","ATTRITION_SCORE_BOSS","","ASSAULT","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionBountySurvived","#SCORE_EVENT_AT_BOUNTY_SURVIVED","#SCORE_EVENT_AT_BOUNTY_SURVIVED","ATTRITION_SCORE_BOUNTY_SURVIVAL","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/victory","",0
+"AttritionGruntKilled","#SCORE_EVENT_AT_GRUNT_KILLED","#SCORE_EVENT_AT_GRUNT_KILLED","ATTRITION_SCORE_GRUNT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"AttritionMegaTurretKilled","#SCORE_EVENT_AT_MEGA_TURRET_KILLED","#SCORE_EVENT_AT_MEGA_TURRET_KILLED","ATTRITION_SCORE_MEGATURRET","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionSentryTurretKilled","#SCORE_EVENT_AT_SENTRY_TURRET_KILLED","#SCORE_EVENT_AT_SENTRY_TURRET_KILLED","ATTRITION_SCORE_SENTRYTURRET","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionPilotKilled","#SCORE_EVENT_AT_PILOT_KILLED","#SCORE_EVENT_AT_PILOT_KILLED","ATTRITION_SCORE_PILOT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"AttritionProwlerKilled","#SCORE_EVENT_AT_PROWLER_KILLED","#SCORE_EVENT_AT_PROWLER_KILLED","ATTRITION_SCORE_PROWLER","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"AttritionSpectreKilled","#SCORE_EVENT_AT_SPECTRE_KILLED","#SCORE_EVENT_AT_SPECTRE_KILLED","ATTRITION_SCORE_SPECTRE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionStalkerKilled","#SCORE_EVENT_AT_STALKER_KILLED","#SCORE_EVENT_AT_STALKER_KILLED","ATTRITION_SCORE_STALKER","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionSuperSpectreKilled","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","ATTRITION_SCORE_SUPER_SPECTRE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionTitanDoomed","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","ATTRITION_SCORE_TITAN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionTitanKilled","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","ATTRITION_SCORE_TITAN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"AttritionCashedBonus","#SCORE_EVENT_AT_CASHED_BONUS","#SCORE_EVENT_AT_CASHED_BONUS","ATTRITION_SCORE_BONUS","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"AttritionBonusStolen","#SCORE_EVENT_AT_BONUS_STOLEN","#SCORE_EVENT_AT_BONUS_STOLEN","ATTRITION_SCORE_BONUS_STOLEN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"BombCarry","#SCORE_EVENT_BOMB_CARRY_POINTS","#SCORE_EVENT_BOMB_CARRY_POINTS","GAMEMODE_BOMB_SCORE_CARRY","","DISTANCE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/bomb","",0
+"BombPlant","#SCORE_EVENT_BOMB_PLANT_POINTS","#SCORE_EVENT_BOMB_PLANT_POINTS","GAMEMODE_BOMB_SCORE_PLANT","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/bomb","",0
+"BombDefuse","#SCORE_EVENT_BOMB_DEFUSE_POINTS","#SCORE_EVENT_BOMB_DEFUSE_POINTS","GAMEMODE_BOMB_SCORE_DEFUSE","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/bomb","",0
+"BombExplode","#SCORE_EVENT_BOMB_EXPLODE_POINTS","#SCORE_EVENT_BOMB_EXPLODE_POINTS","GAMEMODE_BOMB_SCORE_EXPLODE","","DETONATION","0","0","0","0","","MEDAL GAMEMODE","rui/medals/bomb","",0
+"ChallengeCompleted","#SCORE_EVENT_CHALLENGE_COMPLETED","#SCORE_EVENT_CHALLENGE_COMPLETED","0","","","0","0","0","0","","MEDAL","rui/medals/victory","",0
+"ChallengePVPKillCount","#SCORE_EVENT_CHALLENGE_PVP_KILLS","#SCORE_EVENT_CHALLENGE_PVP_KILLS","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeATAssault","#SCORE_EVENT_CHALLENGE_AT_ASSAULT","#SCORE_EVENT_CHALLENGE_AT_ASSAULT","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeCPAssault","#SCORE_EVENT_CHALLENGE_CP_ASSAULT","#SCORE_EVENT_CHALLENGE_CP_ASSAULT","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeCPDefense","#SCORE_EVENT_CHALLENGE_CP_DEFENSE","#SCORE_EVENT_CHALLENGE_CP_DEFENSE","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeCTFCapAssist","#SCORE_EVENT_ASSIST_WITH_FLAG_CAP","#SCORE_EVENT_ASSIST_WITH_FLAG_CAP","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeCTFRetAssist","#SCORE_EVENT_ASSIST_WITH_FLAG_RET","#SCORE_EVENT_ASSIST_WITH_FLAG_RET","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeFW","#SCORE_EVENT_USE_N_BATTERIES","#SCORE_EVENT_USE_N_BATTERIES","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeFFA","#SCORE_EVENT_KILL_N_PILOTS","#SCORE_EVENT_KILL_N_PILOTS","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeTDM","#SCORE_EVENT_KILL_N_IN_A_ROW","#SCORE_EVENT_KILL_N_IN_A_ROW","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeTTDM","#SCORE_EVENT_CHALLENGE_COMPLETED","#SCORE_EVENT_CHALLENGE_COMPLETED","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeLTS","#SCORE_EVENT_KILL_N_TITANS","#SCORE_EVENT_KILL_N_TITANS","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeSPEEDBALL","#SCORE_EVENT_KILL_N_PILOTS","#SCORE_EVENT_KILL_N_PILOTS","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeMFD","#SCORE_EVENT_CHALLENGE_COMPLETED","#SCORE_EVENT_CHALLENGE_COMPLETED","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"ChallengeFD","#SCORE_EVENT_CHALLENGE_FD","#SCORE_EVENT_CHALLENGE_FD","","","","1","0","0","0","SCORE_MILESTONE","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"Comeback","#SCORE_EVENT_COMEBACK","#SCORE_EVENT_COMEBACK","POINTVALUE_COMEBACK","","","0","0","0","0","","MEDAL","rui/medals/kill","kc_comeback",0
+"ControlPanelHeavyTurretActivate","#SCORE_EVENT_HEAVY_TURRET_ACTIVATED","#SCORE_EVENT_HEAVY_TURRET_ACTIVATED","POINTVALUE_CONTROL_PANEL_ACTIVATE","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"ControlPanelLightTurretActivate","#SCORE_EVENT_LIGHT_TURRETS_ACTIVATED","#SCORE_EVENT_LIGHT_TURRETS_ACTIVATED","POINTVALUE_CONTROL_PANEL_ACTIVATE_LIGHT","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"ControlPointCapture","#SCORE_EVENT_HARDPOINT_CAPTURED","#SCORE_EVENT_HARDPOINT_CAPTURED","POINTVALUE_HARDPOINT_CAPTURE","","ASSAULT","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointCaptureAssist","#SCORE_EVENT_HARDPOINT_CAPTURE_ASSIST","#SCORE_EVENT_HARDPOINT_CAPTURE_ASSIST","POINTVALUE_HARDPOINT_CAPTURE_ASSIST","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointHold","#SCORE_EVENT_HARDPOINT_HOLD","#SCORE_EVENT_HARDPOINT_HOLD","POINTVALUE_HARDPOINT_HOLD","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointTake","#SCORE_EVENT_HARDPOINT_TAKE","#SCORE_EVENT_HARDPOINT_TAKE","POINTVALUE_HARDPOINT_HOLD","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointAmped","#SCORE_EVENT_HARDPOINT_AMPED","#SCORE_EVENT_HARDPOINT_AMPED","POINTVALUE_HARDPOINT_AMPED","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointAmpedHold","#SCORE_EVENT_HARDPOINT_AMPED_HOLD","#SCORE_EVENT_HARDPOINT_AMPED_HOLD","POINTVALUE_HARDPOINT_AMPED_HOLD","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointNeutralize","#SCORE_EVENT_HARDPOINT_NEUTRALIZED","#SCORE_EVENT_HARDPOINT_NEUTRALIZED","POINTVALUE_HARDPOINT_NEUTRALIZE","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"ControlPointNeutralizeAssist","#SCORE_EVENT_HARDPOINT_NEUTRALIZE_ASSIST","#SCORE_EVENT_HARDPOINT_NEUTRALIZE_ASSIST","POINTVALUE_HARDPOINT_NEUTRALIZE_ASSIST","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"Damage","#SCORE_EVENT_DAMAGE_GENERIC","#SCORE_EVENT_DAMAGE_GENERIC","0","","","0","0","0","0","","CENTER","rui/medals/kill","",0
+"DamageTitan","#SCORE_EVENT_DAMAGE_TITAN","#SCORE_EVENT_DAMAGE_TITAN","0","","","0","0","0","0","","CENTER","rui/medals/kill","",0
+"StealMeter","#SCORE_EVENT_STEAL_METER","#SCORE_EVENT_STEAL_METER","0","","","0","0","0","0","","CENTER","rui/medals/kill","",0
+"Destored_Proximity_Mine","#SCORE_EVENT_DESTROYED_PROXIMITY_CHARGE","#SCORE_EVENT_DESTROYED_PROXIMITY_CHARGE","POINTVALUE_DESTROYED_PROXIMITY_MINE","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"Destroyed_Satchel","#SCORE_EVENT_DESTROYED_SATCHEL_CHARGE","#SCORE_EVENT_DESTROYED_SATCHEL_CHARGE","POINTVALUE_DESTROYED_SATCHEL","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"Dominating","#SCORE_EVENT_DOMINATING","#SCORE_EVENT_DOMINATING","POINTVALUE_DOMINATING","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","kc_dominating",0
+"DoomAutoTitan","#MEDAL_DOOMED_TITAN","#MEDAL_DOOMED_TITAN","100","BURN_METER_SMALL_POINT_VALUE","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"DoomTitan","#MEDAL_DOOMED_TITAN","#MEDAL_DOOMED_TITAN","100","BURN_METER_SMALL_POINT_VALUE","","0","0","0","0","","BIG MEDAL","rui/medals/kill_robot","",0
+"DoubleKill","#SCORE_EVENT_DOUBLE_KILL","#SCORE_EVENT_DOUBLE_KILL","POINTVALUE_DOUBLEKILL","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","kc_doublekill",0
+"EliminatePilot","#SCORE_EVENT_ELIMINATED_PILOT","#MEDAL_ELIMINATED_PILOT","POINTVALUE_ELIMINATE_PILOT","BURN_METER_SMALL_POINT_VALUE","","0","0","1","0","KILL","BIG MEDAL CENTER","rui/medals/kill","",0
+"EliminateTitan","#MEDAL_ELIMINATED_TITAN","#MEDAL_ELIMINATED_TITAN","1","BURN_METER_SMALL_POINT_VALUE","","0","0","1","0","","CALLINGCARD MEDAL","rui/medals/kill_robot","",0
+"EliminateAutoTitan","#MEDAL_ELIMINATED_TITAN","#MEDAL_ELIMINATED_TITAN","1","BURN_METER_SMALL_POINT_VALUE","","0","0","1","0","","CALLINGCARD MEDAL","rui/medals/kill_robot","",0
+"FirstStrike","#SCORE_EVENT_FIRST_STRIKE","#SCORE_EVENT_FIRST_STRIKE","POINTVALUE_FIRST_STRIKE","","","0","0","0","0","","CALLINGCARD MEDAL","rui/medals/first_strike","kc_firstblood",0
+"FirstTitanfall","#SCORE_EVENT_FIRST_TITANFALL","#SCORE_EVENT_FIRST_TITANFALL","POINTVALUE_FIRST_TITANFALL","","","0","1","0","0","TITAN_FALL","CALLINGCARD MEDAL","rui/medals/titanfall","",0
+"FishInBarrel","#SCORE_EVENT_FISH_IN_A_BARREL","#SCORE_EVENT_FISH_IN_A_BARREL","POINTVALUE_FISHINBARREL","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"FlagCapture","#SCORE_EVENT_FLAG_CAPTURE","#SCORE_EVENT_FLAG_CAPTURE","POINTVALUE_FLAG_CAPTURE","","","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/ctf","",0
+"FlagTaken","#SCORE_EVENT_FLAG_TAKEN","#SCORE_EVENT_FLAG_TAKEN","POINTVALUE_FLAG_TAKEN","","","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/ctf","",0
+"FlagCaptureAssist","#SCORE_EVENT_FLAG_CAPTURE_ASSIST","#SCORE_EVENT_FLAG_CAPTURE_ASSIST","POINTVALUE_FLAG_CAPTURE_ASSIST","","","0","0","0","0","","MEDAL","rui/medals/ctf","",0
+"FlagCarrierKill","#SCORE_EVENT_KILLED_FLAG_CARRIER","#SCORE_EVENT_KILLED_FLAG_CARRIER","POINTVALUE_FLAG_CARRIER_KILL","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/ctf","",0
+"FlagReturn","#SCORE_EVENT_FLAG_RETURN","#SCORE_EVENT_FLAG_RETURN","POINTVALUE_FLAG_RETURN","","","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/ctf","",0
+"FlyerKill","#SCORE_EVENT_KILLED_FLYER","#MEDAL_KILLED_FLYER","POINTVALUE_KILL_FLYER","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"GetToChopper","#SCORE_EVENT_GET_TO_THE_CHOPPER","#SCORE_EVENT_GET_TO_THE_CHOPPER","POINTVALUE_GET_TO_CHOPPER","","","0","0","0","0","","MEDAL","rui/medals/extract","",0
+"GiveRide","#SCORE_EVENT_GIVE_A_FRIEND_A_LIFT","#SCORE_EVENT_GIVE_A_FRIEND_A_LIFT","POINTVALUE_FRIEND_RIDE","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"HappyHourBonus","#SCORE_EVENT_HAPPY_HOUR_BONUS","#SCORE_EVENT_HAPPY_HOUR_BONUS","","","","5","0","0","0","HAPPY_HOUR","MEDAL CHALLENGE GAMEMODE","rui/medals/victory","",0
+"HardpointAssault","#SCORE_EVENT_HARDPOINT_ASSAULT","#SCORE_EVENT_HARDPOINT_ASSAULT","POINTVALUE_HARDPOINT_ASSAULT","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"HardpointDefense","#SCORE_EVENT_HARDPOINT_DEFENSE","#SCORE_EVENT_HARDPOINT_DEFENSE","POINTVALUE_HARDPOINT_DEFENSE","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"HardpointPerimeterDefense","#SCORE_EVENT_HARDPOINT_PERIMETER_DEFENSE","#SCORE_EVENT_HARDPOINT_PERIMETER_DEFENSE","POINTVALUE_HARDPOINT_PERIMETER_DEFENSE","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"HardpointSiege","#SCORE_EVENT_HARDPOINT_SIEGE","#SCORE_EVENT_HARDPOINT_SIEGE","POINTVALUE_HARDPOINT_SIEGE","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"HardpointSnipe","#SCORE_EVENT_HARDPOINT_RANGED_SUPPORT","#SCORE_EVENT_HARDPOINT_RANGED_SUPPORT","POINTVALUE_HARDPOINT_SNIPE","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"Headshot","#MEDAL_HEADSHOT","#MEDAL_HEADSHOT","POINTVALUE_HEADSHOT","","","0","0","0","0","","MEDAL","rui/medals/headshot","",0
+"HitchRide","#SCORE_EVENT_HITCH_A_RIDE","#SCORE_EVENT_HITCH_A_RIDE","POINTVALUE_RODEOD_FRIEND","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"HotZoneExtract","#SCORE_EVENT_HOT_ZONE_EXTRACT","#SCORE_EVENT_HOT_ZONE_EXTRACT","POINTVALUE_HOTZONE_EXTRACT","","","1","0","0","1","EVAC","MEDAL","rui/medals/extract","",0
+"KillAutoTitan","#MEDAL_KILLED_TITAN","#MEDAL_KILLED_TITAN","POINTVALUE_KILL_TITAN","BURN_METER_SMALL_POINT_VALUE","","0","0","1","0","","CALLINGCARD MEDAL","rui/medals/kill_robot","",0
+"KillDrone","#SCORE_EVENT_KILLED_DRONE","#MEDAL_KILLED_DRONE","POINTVALUE_KILL_DRONE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"KillDropship","#SCORE_EVENT_EVAC_DENIED","#SCORE_EVENT_EVAC_DENIED","POINTVALUE_EVAC_DENIED","","","0","0","0","0","","MEDAL","rui/medals/extract","",0
+"KilledEscapee","#SCORE_EVENT_KILLED_EVACUATING_ENEMY","#MEDAL_KILLED_EVACUATING_ENEMY","POINTVALUE_KILLED_ESCAPEE","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"KilledMVP","#SCORE_EVENT_KILLED_MVP","#MEDAL_KILLED_MVP","POINTVALUE_KILLED_MVP","","","0","0","0","0","","MEDAL","rui/medals/kill","",0
+"KillGrunt","#SCORE_EVENT_KILLED_MILITIA","#SCORE_EVENT_KILLED_MILITIA","POINTVALUE_KILL_FIRETEAM_AI","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill","",0
+"KillHeavyTurret","#SCORE_EVENT_KILLED_HEAVY_TURRET","#SCORE_EVENT_KILLED_HEAVY_TURRET","POINTVALUE_KILL_HEAVY_TURRET","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"KillingSpree","#SCORE_EVENT_KILLING_SPREE","#SCORE_EVENT_KILLING_SPREE","POINTVALUE_KILLINGSPREE","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","kc_killingspree",0
+"KillLightTurret","#SCORE_EVENT_KILLED_LIGHT_TURRET","#SCORE_EVENT_KILLED_LIGHT_TURRET","POINTVALUE_KILL_LIGHT_TURRET","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"KillPilot","#SCORE_EVENT_KILLED_PILOT","#MEDAL_KILLED_PILOT","1","BURN_METER_SMALL_POINT_VALUE","","0","0","1","0","KILL","BIG MEDAL CENTER","rui/medals/kill","",0
+"KillProwler","#SCORE_EVENT_KILLED_PROWLER","#MEDAL_KILLED_PROWLER","POINTVALUE_KILL_PROWLER","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"KillRescueShip","#SCORE_EVENT_EVAC_DENIED","#SCORE_EVENT_EVAC_DENIED","POINTVALUE_EVAC_DENIED","","","0","0","0","0","","MEDAL","rui/medals/extract","",0
+"KillSpectre","#SCORE_EVENT_KILLED_SPECTRE","#MEDAL_KILLED_SPECTRE","POINTVALUE_KILL_SPECTRE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"KillStalker","#SCORE_EVENT_KILLED_STALKER","#MEDAL_KILLED_STALKER","POINTVALUE_KILL_STALKER","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"KillHackedSpectre","#SCORE_EVENT_KILLED_HACKED_SPECTRE","#MEDAL_KILLED_SPECTRE","POINTVALUE_KILL_SPECTRE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"KillSuperSpectre","#SCORE_EVENT_KILLED_SUPER_SPECTRE","#MEDAL_KILLED_SUPER_SPECTRE","POINTVALUE_KILL_SUPER_SPECTRE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"KillTitan","#MEDAL_KILLED_TITAN","#MEDAL_KILLED_TITAN","POINTVALUE_KILL_TITAN","BURN_METER_SMALL_POINT_VALUE","","0","0","1","0","KILL","CALLINGCARD MEDAL CENTER","rui/medals/kill_robot","",0
+"TitanKillTitan","#MEDAL_KILLED_TITAN","#MEDAL_KILLED_TITAN","POINTVALUE_KILL_TITAN","BURN_METER_SMALL_POINT_VALUE","","0","1","1","0","KILL","CALLINGCARD MEDAL CENTER","rui/medals/kill_robot","",0
+"LeechDrone","#SCORE_EVENT_LEECHED_DRONE","#SCORE_EVENT_LEECHED_DRONE","POINTVALUE_LEECH_DRONE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"LeechSpectre","#SCORE_EVENT_LEECHED_SPECTRE","#SCORE_EVENT_LEECHED_SPECTRE","POINTVALUE_LEECH_SPECTRE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"LeechSuperSpectre","#SCORE_EVENT_LEECHED_SUPER_SPECTRE","#SCORE_EVENT_LEECHED_SUPER_SPECTRE","POINTVALUE_LEECH_SUPER_SPECTRE","","","0","0","0","0","","MEDAL","rui/medals/kill_robot","",0
+"MarkedEscort","#SCORE_EVENT_PROTECTED_MARKED_TARGET","#SCORE_EVENT_PROTECTED_MARKED_TARGET","POINTVALUE_MARKED_ESCORT","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill","",0
+"MarkedKilledMarked","#SCORE_EVENT_MARKED_KILLED_MARKED","#SCORE_EVENT_MARKED_KILLED_MARKED","POINTVALUE_MARKED_KILLED_MARKED","","","0","0","0","0","","MEDAL GAMEMODE","rui/hud/gametype_icons/mfd/mfd_enemy","",0
+"MarkedOutlastedEnemyMarked","#SCORE_EVENT_MARKED_OUTLASTED_ENEMY_MARK","#SCORE_EVENT_MARKED_OUTLASTED_ENEMY_MARK","POINTVALUE_MARKED_OUTLASTED_ENEMY_MARKED","","","0","0","0","0","","MEDAL GAMEMODE","rui/hud/gametype_icons/mfd/mfd_friendly","",0
+"MarkedSurvival","#SCORE_EVENT_MARKED_SURVIVAL","#SCORE_EVENT_MARKED_SURVIVAL","POINTVALUE_MARKED_SURVIVAL","","","0","0","0","0","","MEDAL GAMEMODE","rui/hud/gametype_icons/mfd/mfd_friendly","",0
+"MarkedTargetKilled","#SCORE_EVENT_KILLED_MARKED_TARGET","#SCORE_EVENT_KILLED_MARKED_TARGET","POINTVALUE_MARKED_TARGET_KILLED","","","0","0","0","0","","MEDAL GAMEMODE","rui/hud/gametype_icons/mfd/mfd_enemy","",0
+"MatchComplete","#SCORE_EVENT_COMPLETION","#SCORE_EVENT_COMPLETION","POINTVALUE_MATCH_COMPLETION","","","1","0","0","0","MATCH_COMPLETED","MEDAL","rui/medals/victory","",0
+"MatchVictory","#SCORE_EVENT_VICTORY","#SCORE_EVENT_VICTORY","POINTVALUE_MATCH_VICTORY","","","1","0","0","1","MATCH_VICTORY","MEDAL GAMEMODE","rui/medals/victory","",0
+"Mayhem","#SCORE_EVENT_MAYHEM","#SCORE_EVENT_MAYHEM","POINTVALUE_MAYHEM","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"MegaKill","#SCORE_EVENT_MEGA_KILL","#SCORE_EVENT_MEGA_KILL","POINTVALUE_MEGAKILL","","","0","0","0","0","","CALLINGCARD MEDAL","rui/medals/kill_multiple","kc_megakill",0
+"Nemesis","#SCORE_EVENT_NEMESIS","#SCORE_EVENT_NEMESIS","POINTVALUE_NEMESIS","","","0","0","0","0","","MEDAL","rui/medals/kill","kc_retribution",0
+"NewPlayerBonus","#SCORE_EVENT_NEW_PLAYER_BONUS","#SCORE_EVENT_NEW_PLAYER_BONUS","POINTVALUE_MATCH_VICTORY","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/victory","",0
+"NPCHeadshot","#SCORE_EVENT_HEADSHOT","#SCORE_EVENT_HEADSHOT","POINTVALUE_NPC_HEADSHOT","","","0","0","0","0","","MEDAL","rui/medals/headshot","",0
+"Onslaught","#SCORE_EVENT_ONSLAUGHT","#SCORE_EVENT_ONSLAUGHT","POINTVALUE_ONSLAUGHT","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"PilotAmmoPickup","Picked Up Ammo","Picked Up Ammo","50","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",1
+"PilotAssist","#MEDAL_ASSIST_PILOT","#MEDAL_ASSIST_PILOT","POINTVALUE_ASSIST","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill","",0
+"PilotBatteryApplied","#SCORE_EVENT_BATTERY_APPLY","#SCORE_EVENT_BATTERY_APPLY","50","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",1
+"PilotBatteryPickup","#SCORE_EVENT_BATTERY_PICKUP","#SCORE_EVENT_BATTERY_PICKUP","50","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",1
+"PilotBatteryStolen","#SCORE_EVENT_BATTERY_STEAL","#SCORE_EVENT_BATTERY_STEAL","50","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",1
+"QuickRevenge","#SCORE_EVENT_QUICK_REVENGE","#SCORE_EVENT_QUICK_REVENGE","POINTVALUE_REVENGE_QUICK","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"Rampage","#SCORE_EVENT_RAMPAGE","#SCORE_EVENT_RAMPAGE","POINTVALUE_RAMPAGE","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","kc_rampage",0
+"Revenge","#SCORE_EVENT_REVENGE","#SCORE_EVENT_REVENGE","POINTVALUE_REVENGE","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"RodeoEnemyTitan","#SCORE_EVENT_RODEOED_ENEMY_TITAN","#SCORE_EVENT_RODEOED_ENEMY_TITAN","POINTVALUE_RODEOD","","","0","0","0","0","","MEDAL","rui/medals/medal_prototype","",0
+"RoundComplete","#SCORE_EVENT_ROUND_COMPLETION","#SCORE_EVENT_ROUND_COMPLETION","POINTVALUE_ROUND_COMPLETION","","","0","0","0","0","","MEDAL","rui/medals/victory","",0
+"RoundVictory","#SCORE_EVENT_ROUND_WIN","#SCORE_EVENT_ROUND_WIN","POINTVALUE_ROUND_WIN","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/victory","",0
+"SelfBonusKilledAll","#SCORE_EVENT_SOLO_KILLED_ALL_COMBATANTS","#SCORE_EVENT_SOLO_KILLED_ALL_COMBATANTS","POINTVALUE_FULL_TEAM_KILL_SOLO","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"Showstopper","#SCORE_EVENT_SHOWSTOPPER","#SCORE_EVENT_SHOWSTOPPER","POINTVALUE_SHOWSTOPPER","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","kc_iced",0
+"SoleSurvivor","#SCORE_EVENT_SOLE_SURVIVOR","#SCORE_EVENT_SOLE_SURVIVOR","POINTVALUE_SOLE_SURVIVOR","","","0","0","0","0","","MEDAL","rui/medals/extract","",0
+"SpotAssist","#SCORE_EVENT_SPOT_ASSIST","#SCORE_EVENT_SPOT_ASSIST","POINTVALUE_ASSIST","","","0","0","0","0","","MEDAL","rui/medals/headshot","",0
+"TeamBonusFullEvac","#SCORE_EVENT_TEAM_BONUS_FULL_TEAM_EVAC","#SCORE_EVENT_TEAM_BONUS_FULL_TEAM_EVAC","POINTVALUE_FULL_TEAM_EVAC","","","0","0","0","0","","MEDAL","rui/medals/extract","",0
+"TeamBonusKilledAll","#SCORE_EVENT_TEAM_BONUS_KILLED_ALL_COMBATANTS","#SCORE_EVENT_TEAM_BONUS_KILLED_ALL_COMBATANTS","POINTVALUE_FULL_TEAM_KILL","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","",0
+"TitanAssist","#MEDAL_ASSIST_TITAN","#MEDAL_ASSIST_TITAN","POINTVALUE_ASSIST_TITAN","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"TitanCoreEarned","#SCORE_EVENT_CORE_EARNED","#SCORE_EVENT_CORE_EARNED","POINTVALUE_CALLED_IN_TITAN","","","0","1","0","0","TITAN_CORE_EARNED","CALLINGCARD MEDAL","rui/medals/titanfall","",0
+"Titanfall","#SCORE_EVENT_TITANFALL","#SCORE_EVENT_TITANFALL","POINTVALUE_CALLED_IN_TITAN","","","0","1","0","0","TITAN_FALL","CALLINGCARD MEDAL","rui/medals/titanfall","",0
+"TripleKill","#SCORE_EVENT_TRIPLE_KILL","#SCORE_EVENT_TRIPLE_KILL","POINTVALUE_TRIPLEKILL","","","0","0","0","0","","MEDAL","rui/medals/kill_multiple","kc_triplekill",0
+"VictoryKill","#SCORE_EVENT_VICTORY_KILL","#SCORE_EVENT_VICTORY_KILL","POINTVALUE_VICTORYKILL","BURN_METER_SMALL_POINT_VALUE","","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/kill","",0
+"FactionLevelUp","","","","","","1","0","0","0","FACTION_LEVELED","","","",0
+"TitanLevelUp","","","","","","1","0","0","0","TITAN_LEVELED","","","",0
+"WeaponLevelUp","","","","","","1","0","0","0","WEAPON_LEVELED","","","",0
+"FortWarAssault","#SCORE_EVENT_FW_ASSAULT","#SCORE_EVENT_FW_ASSAULT","POINTVALUE_FW_ASSAULT","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarDefense","#SCORE_EVENT_FW_DEFENSE","#SCORE_EVENT_FW_DEFENSE","POINTVALUE_FW_DEFENSE","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarPerimeterDefense","#SCORE_EVENT_FW_PERIMETER_DEFENSE","#SCORE_EVENT_FW_PERIMETER_DEFENSE","POINTVALUE_FW_PERIMETER_DEFENSE","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarSiege","#SCORE_EVENT_FW_SIEGE","#SCORE_EVENT_FW_SIEGE","POINTVALUE_FW_SIEGE","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarSnipe","#SCORE_EVENT_FW_RANGED_SUPPORT","#SCORE_EVENT_FW_RANGED_SUPPORT","POINTVALUE_FW_SNIPE","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarBaseConstruction","#SCORE_EVENT_FW_BASE_CONSTRUCTION","#SCORE_EVENT_FW_BASE_CONSTRUCTION","POINTVALUE_FW_BASE_CONSTRUCTION","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarForwardConstruction","#SCORE_EVENT_FW_FORWARD_CONSTRUCTION","#SCORE_EVENT_FW_FORWARD_CONSTRUCTION","POINTVALUE_FW_FORWARD_CONSTRUCTION","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarInvasiveConstruction","#SCORE_EVENT_FW_INVASIVE_CONSTRUCTION","#SCORE_EVENT_FW_INVASIVE_CONSTRUCTION","POINTVALUE_FW_INVASIVE_CONSTRUCTION","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarShieldConstruction","#SCORE_EVENT_FW_SHIELD_CONSTRUCTION","#SCORE_EVENT_FW_SHIELD_CONSTRUCTION","POINTVALUE_FW_SHIELD_CONSTRUCTION","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarResourceDenial","#SCORE_EVENT_FW_RESOURCE_DENIAL","#SCORE_EVENT_FW_RESOURCE_DENIAL","POINTVALUE_FW_RESOURCE_DENIAL","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarTowerDamage","#SCORE_EVENT_FW_TOWER_DAMAGE","#SCORE_EVENT_FW_TOWER_DAMAGE","POINTVALUE_FW_TOWER_DAMAGE","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarTowerDefense","#SCORE_EVENT_FW_TOWER_DEFENSE","#SCORE_EVENT_FW_TOWER_DEFENSE","POINTVALUE_FW_TOWER_DEFENSE","","DEFENSE","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarTeamTurretControlBonus_One","#SCORE_EVENT_FW_TURRET_CONTROL_ONE","#SCORE_EVENT_FW_TURRET_CONTROL_ONE","POINTVALUE_FW_TEAM_TURRET_CONTROL","","DEFENSE","0","0","0","0","","MEDAL","rui/medals/hardpoint","",0
+"FortWarTeamTurretControlBonus_Two","#SCORE_EVENT_FW_TURRET_CONTROL_TWO","#SCORE_EVENT_FW_TURRET_CONTROL_TWO","POINTVALUE_FW_TEAM_TURRET_CONTROL","","DEFENSE","0","0","0","0","","MEDAL","rui/medals/hardpoint","",0
+"FortWarTeamTurretControlBonus_Three","#SCORE_EVENT_FW_TURRET_CONTROL_THREE","#SCORE_EVENT_FW_TURRET_CONTROL_THREE","POINTVALUE_FW_TEAM_TURRET_CONTROL","","DEFENSE","0","0","0","0","","MEDAL","rui/medals/hardpoint","",0
+"FortWarTeamTurretControlBonus_Four","#SCORE_EVENT_FW_TURRET_CONTROL_FOUR","#SCORE_EVENT_FW_TURRET_CONTROL_FOUR","POINTVALUE_FW_TEAM_TURRET_CONTROL","","DEFENSE","0","0","0","0","","MEDAL","rui/medals/hardpoint","",0
+"FortWarTeamTurretControlBonus_Five","#SCORE_EVENT_FW_TURRET_CONTROL_FIVE","#SCORE_EVENT_FW_TURRET_CONTROL_FIVE","POINTVALUE_FW_TEAM_TURRET_CONTROL","","DEFENSE","0","0","0","0","","MEDAL","rui/medals/hardpoint","",0
+"FortWarTeamTurretControlBonus_Six","#SCORE_EVENT_FW_TURRET_CONTROL_SIX","#SCORE_EVENT_FW_TURRET_CONTROL_SIX","POINTVALUE_FW_TEAM_TURRET_CONTROL","","DEFENSE","0","0","0","0","","MEDAL","rui/medals/hardpoint","",0
+"FortWarSecuringGatheredResources","#SCORE_EVENT_FW_SECURING_RESOURCES","#SCORE_EVENT_FW_SECURING_RESOURCES","POINTVALUE_FW_SECURING_RESOURCES","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"FortWarShieldDestroyed","#SCORE_EVENT_FW_DESTROYED_TURRET_SHIELD","#SCORE_EVENT_FW_DESTROYED_TURRET_SHIELD","POINTVALUE_FW_DESTROY_TURRET_SHIELD","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/hardpoint","",0
+"HuntedEliminatePilot","#SCORE_EVENT_HUNTED_HUNTER_KILLED","#SCORE_EVENT_HUNTED_HUNTER_KILLED","POINTVALUE_HUNTED_ELIMINATE_HUNTER","","DEFENSE","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"HuntedEliminateGrunt","#SCORE_EVENT_HUNTED_GRUNT_KILLED","#SCORE_EVENT_HUNTED_GRUNT_KILLED","POINTVALUE_HUNTED_ELIMINATE_GRUNT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"HuntedEliminateSquad","#SCORE_EVENT_HUNTED_SQUAD_KILLED","#SCORE_EVENT_HUNTED_SQUAD_KILLED","POINTVALUE_HUNTED_ELIMINATE_SQUAD","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_multiple","",0
+"HuntedAquireAsset","#SCORE_EVENT_HUNTED_AQUIRE_ASSET","#SCORE_EVENT_HUNTED_AQUIRE_ASSET","POINTVALUE_HUNTED_AQUIRE_ASSET","","DEFENSE","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"HuntedSecureAsset","#SCORE_EVENT_HUNTED_AQUIRE_SECURED","#SCORE_EVENT_HUNTED_AQUIRE_SECURED","POINTVALUE_HUNTED_SECURE_ASSET","","DEFENSE","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"HuntedExtractAsset","#SCORE_EVENT_HUNTED_AQUIRE_EXTRACTED","#SCORE_EVENT_HUNTED_AQUIRE_EXTRACTED","POINTVALUE_HUNTED_EXTRACT_ASSET","","DEFENSE","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"HuntedSurvival","#SCORE_EVENT_HUNTED_OBJECTIVE_SURVIVAL","#SCORE_EVENT_HUNTED_OBJECTIVE_SURVIVAL","POINTVALUE_HUNTED_OBJECTIVE_SURVIVAL","","DEFENSE","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"HuntedMissionSurvival","#SCORE_EVENT_HUNTED_MISSION_SURVIVAL","#SCORE_EVENT_HUNTED_MISSION_SURVIVAL","POINTVALUE_HUNTED_MISSION_SURVIVAL","","DEFENSE","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"MFDMarked","#SCORE_EVENT_MARKED_FOR_DEATH_TARGET","#SCORE_EVENT_MARKED_FOR_DEATH_TARGET","POINTVALUE_MARKED_TARGET","","","0","1","0","0","","CALLINGCARD MEDAL","rui/medals/titanfall","",0
+"BombPlantRaid","#SCORE_EVENT_BOMB_PLANT_POINTS","#SCORE_EVENT_BOMB_PLANT_POINTS","GAMEMODE_RAID_SCORE_PLANT","","ASSAULT","0","0","0","0","","MEDAL GAMEMODE","rui/medals/bomb","",0
+"ATCOOPAirDroneKilled","#SCORE_EVENT_AT_AIR_DRONE_KILLED","#SCORE_EVENT_AT_AIR_DRONE_KILLED","ATCOOP_SCORE_AIR_DRONE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPBossKilled","#SCORE_EVENT_AT_BOSS_KILLED","#SCORE_EVENT_AT_BOSS_KILLED","ATCOOP_SCORE_BOSS","","ASSAULT","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPBountySurvived","#SCORE_EVENT_AT_BOUNTY_SURVIVED","#SCORE_EVENT_AT_BOUNTY_SURVIVED","ATCOOP_SCORE_BOUNTY_SURVIVAL","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/victory","",0
+"ATCOOPGruntKilled","#SCORE_EVENT_AT_GRUNT_KILLED","#SCORE_EVENT_AT_GRUNT_KILLED","ATCOOP_SCORE_GRUNT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"ATCOOPMegaTurretKilled","#SCORE_EVENT_AT_MEGA_TURRET_KILLED","#SCORE_EVENT_AT_MEGA_TURRET_KILLED","ATCOOP_SCORE_MEGATURRET","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPSentryTurretKilled","#SCORE_EVENT_AT_SENTRY_TURRET_KILLED","#SCORE_EVENT_AT_SENTRY_TURRET_KILLED","ATCOOP_SCORE_SENTRYTURRET","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPPilotKilled","#SCORE_EVENT_AT_PILOT_KILLED","#SCORE_EVENT_AT_PILOT_KILLED","ATCOOP_SCORE_PILOT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"ATCOOPProwlerKilled","#SCORE_EVENT_AT_PROWLER_KILLED","#SCORE_EVENT_AT_PROWLER_KILLED","ATCOOP_SCORE_PROWLER","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"ATCOOPSpectreKilled","#SCORE_EVENT_AT_SPECTRE_KILLED","#SCORE_EVENT_AT_SPECTRE_KILLED","ATCOOP_SCORE_SPECTRE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPStalkerKilled","#SCORE_EVENT_AT_STALKER_KILLED","#SCORE_EVENT_AT_STALKER_KILLED","ATCOOP_SCORE_STALKER","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPSuperSpectreKilled","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","ATCOOP_SCORE_SUPER_SPECTRE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPTitanDoomed","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","ATCOOP_SCORE_TITAN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPTitanKilled","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","ATCOOP_SCORE_TITAN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"ATCOOPCashedBonus","#SCORE_EVENT_AT_CASHED_BONUS","#SCORE_EVENT_AT_CASHED_BONUS","ATCOOP_SCORE_BONUS","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"ATCOOPBonusStolen","#SCORE_EVENT_AT_BONUS_STOLEN","#SCORE_EVENT_AT_BONUS_STOLEN","ATCOOP_SCORE_BONUS_STOLEN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXAirDroneKilled","#SCORE_EVENT_AT_AIR_DRONE_KILLED","#SCORE_EVENT_AT_AIR_DRONE_KILLED","PVE_SANDBOX_SCORE_AIR_DRONE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXBossKilled","#SCORE_EVENT_AT_BOSS_KILLED","#SCORE_EVENT_AT_BOSS_KILLED","PVE_SANDBOX_SCORE_BOSS","","ASSAULT","0","0","0","0","","CALLINGCARD MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXBountySurvived","#SCORE_EVENT_AT_BOUNTY_SURVIVED","#SCORE_EVENT_AT_BOUNTY_SURVIVED","PVE_SANDBOX_SCORE_BOUNTY_SURVIVAL","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/victory","",0
+"PVESANDBOXGruntKilled","#SCORE_EVENT_AT_GRUNT_KILLED","#SCORE_EVENT_AT_GRUNT_KILLED","PVE_SANDBOX_SCORE_GRUNT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"PVESANDBOXMegaTurretKilled","#SCORE_EVENT_AT_MEGA_TURRET_KILLED","#SCORE_EVENT_AT_MEGA_TURRET_KILLED","PVE_SANDBOX_SCORE_MEGATURRET","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXSentryTurretKilled","#SCORE_EVENT_AT_SENTRY_TURRET_KILLED","#SCORE_EVENT_AT_SENTRY_TURRET_KILLED","PVE_SANDBOX_SCORE_SENTRYTURRET","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXPilotKilled","#SCORE_EVENT_AT_PILOT_KILLED","#SCORE_EVENT_AT_PILOT_KILLED","PVE_SANDBOX_SCORE_PILOT","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"PVESANDBOXProwlerKilled","#SCORE_EVENT_AT_PROWLER_KILLED","#SCORE_EVENT_AT_PROWLER_KILLED","PVE_SANDBOX_SCORE_PROWLER","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"PVESANDBOXSpectreKilled","#SCORE_EVENT_AT_SPECTRE_KILLED","#SCORE_EVENT_AT_SPECTRE_KILLED","PVE_SANDBOX_SCORE_SPECTRE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXStalkerKilled","#SCORE_EVENT_AT_STALKER_KILLED","#SCORE_EVENT_AT_STALKER_KILLED","PVE_SANDBOX_SCORE_STALKER","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXSuperSpectreKilled","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","PVE_SANDBOX_SCORE_SUPER_SPECTRE","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXTitanDoomed","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","PVE_SANDBOX_SCORE_TITAN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXTitanKilled","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","PVE_SANDBOX_SCORE_TITAN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"PVESANDBOXCashedBonus","#SCORE_EVENT_AT_CASHED_BONUS","#SCORE_EVENT_AT_CASHED_BONUS","PVE_SANDBOX_SCORE_BONUS","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"PVESANDBOXBonusStolen","#SCORE_EVENT_AT_BONUS_STOLEN","#SCORE_EVENT_AT_BONUS_STOLEN","PVE_SANDBOX_SCORE_BONUS_STOLEN","","ASSAULT","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDAirDroneKilled","#SCORE_EVENT_AT_AIR_DRONE_KILLED","#SCORE_EVENT_AT_AIR_DRONE_KILLED","FD_SCORE_AIR_DRONE","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDGruntKilled","#SCORE_EVENT_AT_GRUNT_KILLED","#SCORE_EVENT_AT_GRUNT_KILLED","FD_SCORE_GRUNT","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill","",0
+"FDSpectreKilled","#SCORE_EVENT_AT_SPECTRE_KILLED","#SCORE_EVENT_AT_SPECTRE_KILLED","FD_SCORE_SPECTRE","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDStalkerKilled","#SCORE_EVENT_AT_STALKER_KILLED","#SCORE_EVENT_AT_STALKER_KILLED","FD_SCORE_STALKER","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDSuperSpectreKilled","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","#SCORE_EVENT_AT_SUPER_SPECTRE_KILLED","FD_SCORE_SUPER_SPECTRE","","","0","0","0","0","","ATTRITION MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDTitanKilled","#SCORE_EVENT_AT_TITAN_DOOMED","#SCORE_EVENT_AT_TITAN_DOOMED","FD_SCORE_TITAN","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDEnemiesKilled","#SCORE_EVENT_FD_ENEMIES_KILLED","#SCORE_EVENT_FD_ENEMIES_KILLED","FD_SCORE_ENEMIES","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill","",0
+"FDWaveMVP","#SCORE_EVENT_FD_WAVE_MVP","#SCORE_EVENT_FD_WAVE_MVP","FD_SCORE_MVP","","","0","0","0","0","","MEDAL_FORCED GAMEMODE CALLINGCARD","rui/medals/mvp","",0
+"FDTeamFinalWave","#SCORE_EVENT_FD_TEAM_FINAL_WAVE","#SCORE_EVENT_FD_TEAM_FINAL_WAVE","FD_SCORE_TEAM_FINAL_WAVE","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"FDTeamWave","#SCORE_EVENT_FD_TEAM_WAVE","#SCORE_EVENT_FD_TEAM_WAVE","FD_SCORE_TEAM_WAVE","","","0","0","0","0","","MEDAL_FORCED GAMEMODE","rui/medals/harvester_protect","",0
+"FDTeamFlawlessWave","#SCORE_EVENT_FD_TEAM_FLAWLESS_WAVE","#SCORE_EVENT_FD_TEAM_FLAWLESS_WAVE","FD_SCORE_TEAM_FLAWLESS_WAVE","","","0","0","0","0","","MEDAL_FORCED GAMEMODE","rui/medals/shielded_harvester","",0
+"PasTitanHunter","#GEAR_AT_HUNTER_KIT","#GEAR_AT_HUNTER_KIT","","","","0","0","0","0","KILL","MEDAL","rui/medals/kill_robot","",0
+"Execution","#SCORE_EVENT_EXECUTION","#SCORE_EVENT_EXECUTION","0","BURN_METER_LARGE_POINT_VALUE","","0","0","0","0","","MEDAL","rui/medals/kill","",0
+"FDRepairTurret","#SCORE_EVENT_REPAIR_TURRET","#SCORE_EVENT_REPAIR_TURRET","FD_SCORE_REPAIR_TURRET","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"FDDidntDie","#SCORE_EVENT_DIDNT_DIE","#SCORE_EVENT_DIDNT_DIE","FD_SCORE_DIDNT_DIE","","","0","0","0","0","","MEDAL_FORCED GAMEMODE","rui/medals/heal","",0
+"FDShieldHarvester","#SCORE_EVENT_FD_SHIELD_HARVESTER","#SCORE_EVENT_FD_SHIELD_HARVESTER","FD_SCORE_SHIELD_HARVESTER","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/shielded_harvester","",0
+"FDSonarPulse","#SCORE_EVENT_FD_SONAR_PULSE","#SCORE_EVENT_FD_SONAR_PULSE","FD_SCORE_SONAR_PULSE","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"FDArcTrapTriggered","#SCORE_EVENT_FD_ARC_TRAP_TRIGGERED","#SCORE_EVENT_FD_ARC_TRAP_TRIGGERED","FD_SCORE_ARC_TRAP_TRIGGERED","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDTetherTriggered","#SCORE_EVENT_FD_TETHER_TRAP_TRIGGERED","#SCORE_EVENT_FD_TETHER_TRAP_TRIGGERED","FD_SCORE_TETHER_TRAP_TRIGGERED","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/kill_robot","",0
+"FDArcWave","#SCORE_EVENT_FD_ARC_WAVE","#SCORE_EVENT_FD_ARC_WAVE","FD_SCORE_ARC_WAVE","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/medal_prototype","",0
+"FDTeamHeal","#SCORE_EVENT_FD_TEAM_HEAL","#SCORE_EVENT_FD_TEAM_HEAL","FD_SCORE_TEAM_HEAL","","","0","0","0","0","","MEDAL GAMEMODE","rui/medals/heal","",0
+"FDDamageBonus","#SCORE_EVENT_FD_DAMAGE_BONUS","#SCORE_EVENT_FD_DAMAGE_BONUS","FD_SCORE_DAMAGE_BONUS","","","0","0","0","0","","MEDAL_FORCED GAMEMODE SHOW_SCORE","rui/medals/medal_prototype","",0
+"FDHealingBonus","#SCORE_EVENT_FD_HEALING_BONUS","#SCORE_EVENT_FD_HEALING_BONUS","FD_SCORE_HEALING_BONUS","","","0","0","0","0","","MEDAL_FORCED GAMEMODE SHOW_SCORE","rui/medals/heal","",0
+"FDSupportBonus","#SCORE_EVENT_FD_SUPPORT_BONUS","#SCORE_EVENT_FD_SUPPORT_BONUS","FD_SCORE_SUPPORT_BONUS","","","0","0","0","0","","MEDAL_FORCED GAMEMODE SHOW_SCORE","rui/medals/kill_robot","",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/sp_levels.csv b/Northstar.CustomServers/mod/scripts/datatable/sp_levels.csv new file mode 100644 index 00000000..f373d4ed --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/sp_levels.csv @@ -0,0 +1,17 @@ +levelNum,level,startPoint,levelId,mainEntry,showLions,title,desc,missionSelectImage
+0,"sp_training","Pod Intro","sp_training",1,1,"#SP_TRAINING_CAMPAIGN_NAME","#SP_TRAINING_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image1"
+0,"sp_training","Gauntlet Mode","training_gauntlet_mode",0,1,"","",""
+1,"sp_crashsite","LevelStart","sp_crashsite",1,1,"#SP_CRASHSITE_CAMPAIGN_NAME","#SP_CRASHSITE_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image2"
+2,"sp_sewers1","Channel Mortar Run","sp_sewers1",1,1,"#SP_SEWERS1_CAMPAIGN_NAME","#SP_SEWERS1_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image3"
+3,"sp_boomtown_start","Intro","sp_boomtown_start",1,1,"#SP_BOOMTOWN_START_CAMPAIGN_NAME","#SP_BOOMTOWN_START_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image4"
+3,"sp_boomtown","Start","sp_boomtown",0,1,"","",""
+3,"sp_boomtown_end","Intro Caves","sp_boomtown_end",0,1,"","",""
+4,"sp_hub_timeshift","LECTURE HALLS","sp_hub_timeshift",1,0,"#SP_HUB_TIMESHIFT_CAMPAIGN_NAME","#SP_HUB_TIMESHIFT_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image5"
+4,"sp_timeshift_spoke02","Timeshift Device","sp_timeshift_spoke02",0,1,"","",""
+4,"sp_hub_timeshift","PRISTINE CAMPUS","timeshift_pt3",0,1,"","",""
+5,"sp_beacon","Level Start","sp_beacon",1,0,"#SP_BEACON_CAMPAIGN_NAME","#SP_BEACON_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image6"
+5,"sp_beacon_spoke0","Level Start","sp_beacon_spoke0",0,1,"","",""
+5,"sp_beacon","Spoke_0_Complete","beacon_pt3",0,1,"","",""
+6,"sp_tday","Intro","sp_tday",1,1,"#SP_TDAY_CAMPAIGN_NAME","#SP_TDAY_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image7"
+7,"sp_s2s","Level Start","sp_s2s",1,1,"#SP_S2S_CAMPAIGN_NAME","#SP_S2S_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image8"
+8,"sp_skyway_v1","Level Start","sp_skyway_v1",1,1,"#SP_SKYWAY_V1_CAMPAIGN_NAME","#SP_SKYWAY_V1_CAMPAIGN_DESC_MILITIA","rui/menu/level_select/level_image9"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/spectre_chatter_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/spectre_chatter_mp.csv new file mode 100644 index 00000000..4194a938 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/spectre_chatter_mp.csv @@ -0,0 +1,8 @@ +conversationname,priority,debounce
+"diag_imc_spectre_gs_spotclosetitancall_01",200,20.000000
+"diag_imc_spectre_gs_engagepilotenemy_01_1",200,20.000000
+"diag_imc_spectre_gs_grenadeout_01_1",200,20.000000
+"diag_imc_spectre_gs_killenemypilot_01_1",200,20.000000
+"diag_imc_spectre_gs_gruntkillstitan_02_1",200,20.000000
+"diag_imc_spectre_gs_squaddeplete_01_1",200,20.000000
+"diag_imc_spectre_gs_allygrundown_05_1",200,20.000000
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/spotlight_images.csv b/Northstar.CustomServers/mod/scripts/datatable/spotlight_images.csv new file mode 100644 index 00000000..1e6946c1 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/spotlight_images.csv @@ -0,0 +1,30 @@ +image
+"rui/menu/main_menu/spotlight_01"
+"rui/menu/main_menu/spotlight_02"
+"rui/menu/main_menu/spotlight_03"
+"rui/menu/main_menu/spotlight_04"
+"rui/menu/main_menu/spotlight_05"
+"rui/menu/main_menu/spotlight_06"
+"rui/menu/main_menu/spotlight_07"
+"rui/menu/main_menu/spotlight_08"
+"rui/menu/main_menu/spotlight_09"
+"rui/menu/main_menu/spotlight_10"
+"rui/menu/main_menu/spotlight_11"
+"rui/menu/main_menu/spotlight_12"
+"rui/menu/main_menu/spotlight_13"
+"rui/menu/main_menu/spotlight_14"
+"rui/menu/main_menu/spotlight_15"
+"rui/menu/main_menu/spotlight_16"
+"rui/menu/main_menu/spotlight_17"
+"rui/menu/main_menu/spotlight_18"
+"rui/menu/main_menu/spotlight_19"
+"rui/menu/main_menu/spotlight_20"
+"rui/menu/main_menu/spotlight_21"
+"rui/menu/main_menu/spotlight_22"
+"rui/menu/main_menu/spotlight_23"
+"rui/menu/main_menu/spotlight_24"
+"rui/menu/main_menu/spotlight_25"
+"rui/menu/main_menu/spotlight_26"
+"rui/menu/main_menu/spotlight_27"
+"rui/menu/main_menu/spotlight_28"
+"rui/menu/main_menu/spotlight_29"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/startpoints.csv b/Northstar.CustomServers/mod/scripts/datatable/startpoints.csv new file mode 100644 index 00000000..a171cd8a --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/startpoints.csv @@ -0,0 +1,313 @@ +level,startpoint,loadScreenIndex,hasDetente,spLog,spLogTitle,isLeft
+"sp_grunt_arena","Pilot vs 3 Grunts (Trial)",0,0,"","",0
+"sp_grunt_arena","Pilot and Leeched Spectre vs Grunts (Trial)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Spectre (Trial)",0,0,"","",0
+"sp_grunt_arena","Arc Grenades vs Spectres and Grunts (Trial)",0,0,"","",0
+"sp_grunt_arena","Learn to use Shield Drone (Trial)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Grunts (Small Arena)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Grunts (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Shield Drone vs Turrets (Trial)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Captains (Trial)",0,0,"","",0
+"sp_grunt_arena","Use Turrets vs AI (Trial)",0,0,"","",0
+"sp_grunt_arena","Turret Maze Part 1 (Trial)",0,0,"","",0
+"sp_grunt_arena","Turret Maze Part 2 (Trial)",0,0,"","",0
+"sp_grunt_arena","Learn to use Suicide Spectres (Trial)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Mixed AI (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Pilot and Titan vs Many AI (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Titan Wingman Arena (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Titan vs Many AI (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Super Spectre (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Super Spectres (Small Arena)",0,0,"","",0
+"sp_grunt_arena","Titan vs Super Spectres (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Spectres (Big Arena)",0,0,"","",0
+"sp_grunt_arena","Pilot vs Stalker progressive (Big Arena)",0,0,"","",0
+"sp_grunt_arena","The End!",0,0,"","",0
+"sp_ab_gym","gym_windmills",0,0,"","",0
+"sp_ab_gym","gym_bongo_board",0,0,"","",0
+"sp_ab_testfire2","room1",0,0,"","",0
+"sp_ab_testfire2","room2",0,0,"","",0
+"sp_ola_hub","topside",0,0,"","",0
+"sp_ola_hub","hub_intro",0,0,"","",0
+"sp_ola_hub","engine1_connect",0,0,"","",0
+"sp_ola_spoke1","sp_ola_spoke1",0,0,"","",0
+"sp_ola_spoke1","ola_spoke1_cleanroom",0,0,"","",0
+"sp_ola_spoke1","ola_spoke1_powerrod_factory",0,0,"","",0
+"sp_ola_spoke1","ola_spoke1_canyon",0,0,"","",0
+"sp_ola_sewers","ola_sewers_drain",0,0,"","",0
+"sp_ola_sewers","ola_sewers_sludge_test1",0,0,"","",0
+"sp_ola_sewers","ola_sewers_sludge_test2",0,0,"","",0
+"sp_ola_sewers","ola_sewers_sludge_test3",0,0,"","",0
+"sp_ola_sewers","ola_sewers_sludge_test4",0,0,"","",0
+"sp_ola_sewers","ola_sewers_sludge_bt_test1",0,0,"","",0
+"sp_ola_canyon_test","ola_canyontest1",0,0,"","",0
+"sp_ola_canyon_test","ola_canyontest2",0,0,"","",0
+"sp_ola_canyon_test","ola_canyontest3",0,0,"","",0
+"sp_ola_canyon_test","ola_canyontest4",0,0,"","",0
+"sp_ola_canyon_test","dish_array",0,0,"","",0
+"sp_ola_canyon_test","ledge_run",0,0,"","",0
+"sp_ab_canyon_prowler","prowler_canyon_1",0,0,"","",0
+"sp_ab_canyon_prowler","prowler_canyon_2",0,0,"","",0
+"sp_ab_canyon_prowler","prowler_canyon_3",0,0,"","",0
+"sp_hub_timeshift","LECTURE HALLS",0,1,"SP_MISSION_LOG_TIMESHIFT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_hub_timeshift","OVERGROWN CAMPUS",1,0,"SP_MISSION_LOG_TIMESHIFT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_hub_timeshift","Corpse Search",1,0,"SP_MISSION_LOG_TIMESHIFT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_hub_timeshift","BT EXPLAINS IT ALL",1,0,"SP_MISSION_LOG_TIMESHIFT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_hub_timeshift","Zipline",1,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_hub_timeshift","Security",1,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_hub_timeshift","Skybridge",1,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_hub_timeshift","PRISTINE CAMPUS",2,1,"SP_MISSION_LOG_TIMESHIFT_SPLOG1","MENU_SP_LOG_TITLE_TIMESHIFT2",1
+"sp_hub_timeshift","Hub Fight",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG1","MENU_SP_LOG_TITLE_TIMESHIFT2",1
+"sp_hub_timeshift","Extended Bridge",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG1","MENU_SP_LOG_TITLE_TIMESHIFT2",1
+"sp_hub_timeshift","REACTOR MELTDOWN",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG1","MENU_SP_LOG_TITLE_TIMESHIFT2",1
+"sp_hub_timeshift","Core Scan",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG1","MENU_SP_LOG_TITLE_TIMESHIFT2",1
+"sp_hub_timeshift","Level End",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG1","MENU_SP_LOG_TITLE_TIMESHIFT2",1
+"sp_timeshift_spoke02","Timeshift Device",1,1,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_timeshift_spoke02","WILDLIFE RESEARCH",1,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_timeshift_spoke02","First Timeshift Fight",1,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_timeshift_spoke02","Elevator Fight",1,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_timeshift_spoke02","HUMAN RESEARCH",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_timeshift_spoke02","Sphere Room",2,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",1
+"sp_timeshift_spoke02","Human Room",3,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",0
+"sp_timeshift_spoke02","CAMPUS RETURN",3,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",0
+"sp_timeshift_spoke02","Fan Drop",3,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",0
+"sp_timeshift_spoke02","Fan Drop End",3,0,"SP_MISSION_LOG_TIMESHIFT_SPLOG0","MENU_SP_LOG_TITLE_TIMESHIFT1",0
+"sp_beacon","Level Start",1,1,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon","Control Room",1,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Spoke_0_Complete",2,1,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Power Relays Online",1,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Fastball to Spoke 1",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Spoke 1 Start",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Spoke 1 First Combat",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Spoke 1 Second Combat",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Spoke 1 Pillar Room",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Double Crane Puzzle",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Second Beacon",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Spoke 1 Arena",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Wallrun Panels",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Back at HUB",3,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Climb Dish",1,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon","Final Battle",4,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon","Send Signal",4,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon","Beacon Ending",4,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon_spoke0","Level Start",0,1,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon_spoke0","First Fight",1,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon_spoke0","Get Arc Tool",1,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon_spoke0","Got Arc Tool",2,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon_spoke0","Horizontal Fan",2,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon_spoke0","Horizontal Fan Complete",2,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon_spoke0","Fan Wallrun",2,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",0
+"sp_beacon_spoke2","Level Start",0,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon_spoke2","Fastball",0,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_beacon_spoke2","Loading Dock",0,0,"#SP_MISSION_LOG_BEACON","MENU_SP_OBJECTIVES_TITLE",1
+"sp_boomtown_ride","1 - Level Start",0,0,"","",0
+"sp_boomtown_ride","2 - Assembly Line",0,0,"","",0
+"sp_boomtown_ride","3 - First Fight",0,0,"","",0
+"sp_boomtown_ride","4 - First Ride",0,0,"","",0
+"sp_boomtown_ride","5 - Second Ride",0,0,"","",0
+"sp_ab_moving_geo_combat_1","1 - Moving Cover",0,0,"","",0
+"sp_ab_moving_geo_combat_1","2 - Moving Cover with High Ceiling",0,0,"","",0
+"sp_ab_moving_geo_combat_1","3 - Rotating Cover (CQC)",0,0,"","",0
+"sp_ab_moving_geo_combat_1","4 - Rotating Cover - Only Grunts",0,0,"","",0
+"sp_ab_moving_geo_combat_1","5 - Rotating Cover - Stationary Reaper",0,0,"","",0
+"sp_ab_moving_geo_combat_1","6 - Rotating Cover - Mobile Reaper",0,0,"","",0
+"sp_ab_moving_geo_combat_1","7 - Building Assembly Battle",0,0,"","",0
+"sp_training","Pod Intro",1,1,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Basic Movement",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Zen Garden",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Firing Range",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Gauntlet",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Gauntlet Challenge",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Titanfall",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Pod Outro",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Meet OG",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Gauntlet Mode",1,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_FIRSTRUN",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_WIP",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_01",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_02",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_03",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_04",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_05",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_06",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_07",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_08",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","DEV_GHOSTREC_GAUNTLET_CHAL_09",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Pod Intro DEV",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_training","Pod Outro DEV",0,0,"#SP_MISSION_LOG_TRAINING","MENU_SP_OBJECTIVES_TITLE",0
+"sp_wild","1 - Spoke 1: Escape Pod",0,0,"","",0
+"sp_wild","2 - Spoke 1: Basic Movement",0,0,"","",0
+"sp_wild","placeholder 3 - Spoke 1: Spectre Forest",0,0,"","",0
+"sp_wild","placeholder 4 - Spoke 1: Friend or Foe?",0,0,"","",0
+"sp_wild","placeholder 5 - Spoke 1: Grand Reveal",0,0,"","",0
+"sp_wild","placeholder 6 - Spoke 1: Checkpoint Zulu",0,0,"","",0
+"sp_wild","placeholder 7 - Spoke 1: Pistol Puzzle",0,0,"","",0
+"sp_wild","placeholder 8 - Spoke 1: Intruder",0,0,"","",0
+"sp_wild","placeholder 9 - HUB p-1: Gravity",0,0,"","",0
+"sp_wild","placeholder 10 - HUB p-1: Flirtation",0,0,"","",0
+"sp_wild","placeholder 11 - HUB p-1: Chase",0,0,"","",0
+"sp_wild","placeholder 12 - Spoke 2: Gorilla in the Mist",0,0,"","",0
+"sp_wild","13 - Spoke 2: Upgrades",0,0,"","",0
+"sp_wild","placeholder 14 - Spoke 2: A whole new world",0,0,"","",0
+"sp_wild","placeholder 15 - HUB p-2: Making Friends",0,0,"","",0
+"sp_wild","placeholder 16 - HUB p-2: Influencing People",0,0,"","",0
+"sp_wild","placeholder 17 - Spoke 3: Survivors",0,0,"","",0
+"sp_wild","placeholder 18 - Spoke 3: Prisoners",0,0,"","",0
+"sp_wild","placeholder 19 - HUB p-3: Snatch and Grab",0,0,"","",0
+"sp_wild","placeholder 20 - HUB p-3: Hero to Zero",0,0,"","",0
+"sp_wild","placeholder 21 - Spoke 4: Outpost Cherokee",0,0,"","",0
+"sp_wild","placeholder 22 - Spoke 4: Grenades",0,0,"","",0
+"sp_wild","placeholder 23 - Spoke 4: QRF",0,0,"","",0
+"sp_wild","placeholder 24 - Spoke 4: Those Eyes",0,0,"","",0
+"sp_wild","placeholder 25 - Spoke 5: Tree of Life",0,0,"","",0
+"sp_wild","26 - Spoke 5: Gift From the Gods",0,0,"","",0
+"sp_wild","placeholder 27 - HUB p-4: Energizer",0,0,"","",0
+"sp_wild","placeholder 28 - HUB p-4: One Man Army",0,0,"","",0
+"sp_wild","placeholder 29 - Spoke 5: p-2: Sleeping Beauty",0,0,"","",0
+"sp_wild","placeholder 30 - Spoke 5: p-2: Prowler Den",0,0,"","",0
+"sp_wild","placeholder 31 - Spoke 5: p-2: Common Ground",0,0,"","",0
+"sp_wild","placeholder 32 - Spoke 5: p-2: Dharma Hatch",0,0,"","",0
+"sp_crashsite","LevelStart",1,1,"SP_MISSION_LOG_WILDS_SPLOG0","MENU_SP_LOG_TITLE_WILDS",1
+"sp_crashsite","BT_Intro",1,0,"SP_MISSION_LOG_WILDS_SPLOG0","MENU_SP_LOG_TITLE_WILDS",1
+"sp_crashsite","Blisk_Intro",1,0,"SP_MISSION_LOG_WILDS_SPLOG0","MENU_SP_LOG_TITLE_WILDS",1
+"sp_crashsite","FamilyPhoto",1,0,"SP_MISSION_LOG_WILDS_SPLOG0","MENU_SP_LOG_TITLE_WILDS",1
+"sp_crashsite","Waking_Up",2,0,"SP_MISSION_LOG_WILDS_SPLOG0","MENU_SP_LOG_TITLE_WILDS",1
+"sp_crashsite","Field_Promotion",2,0,"SP_MISSION_LOG_WILDS_SPLOG0","MENU_SP_LOG_TITLE_WILDS",1
+"sp_crashsite","Grave",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","Battery2_Path",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","Battery2_Combat",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","Battery2_Ship",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","Battery3_Path",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","Battery3_Combat",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","Battery3_Ship",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_crashsite","PilotLink",2,0,"SP_MISSION_LOG_WILDS_ALT","MENU_SP_OBJECTIVES_TITLE",0
+"sp_ship_01","S2S_GOBLIN",0,0,"","",0
+"sp_ship_01","Goblin Deploy",0,0,"","",0
+"sp_ship_01","Goblin Deploy Zip",0,0,"","",0
+"sp_ship_01","S2S_FASTBALL",0,0,"","",0
+"sp_ship_01","S2S_REDEYE",0,0,"","",0
+"sp_ship_01","S2S_SENTINEL",0,0,"","",0
+"sp_ship_01","Model Test [ solid ]",0,0,"","",0
+"sp_ship_01","Model Test [ notsolid ]",0,0,"","",0
+"sp_ship_01","Bug: Skycam Parent",0,0,"","",0
+"sp_ship_01","Bug: Skycam Move/Rotate",0,0,"","",0
+"sp_ship_01","Bug: Ents outside Bounds",0,0,"","",0
+"sp_ship_01","S2S_COMBAT1-p1",0,0,"","",0
+"sp_ship_01","S2S_COMBAT1-p2",0,0,"","",0
+"sp_ship_01","S2S_COMBAT1-p3",0,0,"","",0
+"sp_ship_01","S2S_COMBAT1-p4",0,0,"","",0
+"sp_ship_03","hull combat p1",0,0,"","",0
+"sp_ship_04","hull combat p1",0,0,"","",0
+"sp_ship_05","hull combat p1",0,0,"","",0
+"sp_s2s","Level Start",1,1,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Intro",1,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Gibraltar",1,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Boss Intro",1,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Widow Fall",1,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Barker Ship",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","FastBall 1",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Intro",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Drone Room",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Guns",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Widow Jump",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Hangar",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Breach",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Bridge",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Reunite with BT",2,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Malta Deck",3,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","BT Tackle",3,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Boss Fight",3,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Viper Dead",3,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",0
+"sp_s2s","Life Boats",4,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",1
+"sp_s2s","Core Room",4,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",1
+"sp_s2s","OLA Crash",4,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",1
+"sp_s2s","--------------",4,0,"SP_MISSION_LOG_S2S","MENU_SP_OBJECTIVES_TITLE",1
+"sp_s2s","TestBed",1,0,"","",0
+"sp_s2s","Dropship Combat Test",1,0,"","",0
+"sp_s2s","LightEdit Connect",1,0,"","",0
+"sp_s2s","TRAILER bridge",1,0,"","",0
+"sp_scrapyard_test","Arena 1",0,0,"","",0
+"sp_sewers1","Channel Mortar Run",1,1,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",1
+"sp_sewers1","Sewer Split",2,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",0
+"sp_sewers1","Sludge Falls",3,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",1
+"sp_sewers1","Corkscrew Room",4,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",0
+"sp_sewers1","Pipe Room Climb",5,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",1
+"sp_sewers1","Sewer Arena",6,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",1
+"sp_sewers1","Sewer Arena Defend",6,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",1
+"sp_sewers1","Kane Arena",7,0,"SP_MISSION_LOG_SEWERS","MENU_SP_OBJECTIVES_TITLE",1
+"sp_davis_sewer_battle","Sneaky Section",0,0,"","",0
+"sp_davis_sewer_battle","Combat Arena",0,0,"","",0
+"sp_davis_sewer_battle","Cylinder Tick Tunnels",0,0,"","",0
+"sp_ab_titan_arena","TvT Linear w 1.5 Boss Titans",0,0,"","",0
+"sp_ab_titan_arena","TvT Arena",0,0,"","",0
+"sp_ab_titan_arena","1v1 Arena A",0,0,"","",0
+"sp_ab_titan_arena","1v1 Arena B",0,0,"","",0
+"sp_ab_titan_arena","1v1 Arena C",0,0,"","",0
+"sp_ab_titan_arena","1v1 Arena D",0,0,"","",0
+"sp_boomtown_townboot","Town Boot",0,0,"","",0
+"sp_boomtown_townboot","Town Delivery",0,0,"","",0
+"sp_boomtown_townboot","Spotlight",0,0,"","",0
+"sp_ab_wilds_combat_test","Battery2",0,0,"","",0
+"sp_ab_wilds_combat_test","Battery3",0,0,"","",0
+"sp_skyway_v1","Level Start",0,1,"","",0
+"sp_skyway_v1","Torture Room B",1,0,"","",0
+"sp_skyway_v1","Smart Pistol Run",1,0,"","",0
+"sp_skyway_v1","Bridge Fight",2,0,"","",0
+"sp_skyway_v1","BT Reunion",3,0,"","",0
+"sp_skyway_v1","Titan Hill",3,0,"","",0
+"sp_skyway_v1","Titan Smash Hallway",3,0,"","",0
+"sp_skyway_v1","Sculptor Climb",3,0,"","",0
+"sp_skyway_v1","Targeting Room",4,0,"","",0
+"sp_skyway_v1","Injector Room",4,0,"","",0
+"sp_skyway_v1","Blisk's Farewell",4,0,"","",0
+"sp_skyway_v1","BT Sacrifice",4,0,"","",0
+"sp_skyway_v1","Rising World Run",5,0,"","",0
+"sp_skyway_v1","Rising World Jump",5,0,"","",0
+"sp_skyway_v1","Exploding Planet",5,0,"","",0
+"sp_skyway_v1","Harmony",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","--- CREDITS ---",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","sarah intro",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","walk",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","hug",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","cheer",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor jack cooper",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor BT / OG",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor blisk",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor sarah",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor bosses",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor marder",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actors 6-4",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","actor barker",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","new BT",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","board ship",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_skyway_v1","final image",5,0,"SP_MISSION_LOG_SKYWAY_ALT","MENU_SP_OBJECTIVES_TITLE",1
+"sp_template","Level Start",0,0,"","",0
+"sp_template","Big Fight",0,0,"","",0
+"sp_template","Finale",0,0,"","",0
+"sp_tday","Intro",1,1,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",1
+"sp_tday","Wall Bombardment",1,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",1
+"sp_tday","Militia Big Charge",1,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",1
+"sp_tday","Underground Fuel Storage",2,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",1
+"sp_tday","Elevator",2,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",1
+"sp_tday","VTOL",3,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",0
+"sp_tday","Fire on the Runway",4,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",0
+"sp_tday","OLA Launch",4,0,"SP_MISSION_LOG_TDAY","MENU_SP_OBJECTIVES_TITLE",0
+"sp_boomtown_start","Intro",0,1,"SP_MISSION_LOG_BOOMTOWN_1","MENU_SP_OBJECTIVES_TITLE",0
+"sp_boomtown_start","Prop House",1,0,"SP_MISSION_LOG_BOOMTOWN_1","MENU_SP_OBJECTIVES_TITLE",1
+"sp_boomtown_start","Narrow Hallway",1,0,"SP_MISSION_LOG_BOOMTOWN_1","MENU_SP_OBJECTIVES_TITLE",1
+"sp_boomtown_start","Titan Arena",1,0,"SP_MISSION_LOG_BOOMTOWN_1","MENU_SP_OBJECTIVES_TITLE",1
+"sp_boomtown_start","Loading Dock",1,0,"SP_MISSION_LOG_BOOMTOWN_1","MENU_SP_OBJECTIVES_TITLE",1
+"sp_boomtown","Start",0,1,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Assembly_Start",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Assembly_Dirt",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Assembly_Wallrun",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Assembly_Furniture",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Assembly_Walls",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Assembly_Highway",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","Town_Climb_Entry",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown","ReaperTown",2,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG0","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown_end","Intro Caves",0,1,"SP_MISSION_LOG_BOOMTOWN_SPLOG1","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown_end","Prowler Towers",0,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG1","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown_end","Above The Dome",1,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG1","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown_end","Pre Ash Fight",2,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG1","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"sp_boomtown_end","Ash Fight",3,0,"SP_MISSION_LOG_BOOMTOWN_SPLOG1","MENU_SP_LOG_TITLE_BOOMTOWN",1
+"eof","eof",0,0,"","",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_abilities.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_abilities.csv new file mode 100644 index 00000000..46164792 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_abilities.csv @@ -0,0 +1,36 @@ +itemRef,type,damageSource,hidden
+"mp_titancore_flame_wave","TITAN_CORE_ABILITY",1,0
+"mp_titancore_flight_core","TITAN_CORE_ABILITY",0,0
+"mp_titancore_laser_cannon","TITAN_CORE_ABILITY",1,0
+"mp_titancore_salvo_core","TITAN_CORE_ABILITY",1,0
+"mp_titancore_shift_core","TITAN_CORE_ABILITY",0,0
+"mp_titancore_siege_mode","TITAN_CORE_ABILITY",0,0
+"mp_titancore_amp_core","TITAN_CORE_ABILITY",0,0
+"mp_titancore_dash_core","TITAN_CORE_ABILITY",0,0
+"mp_titanweapon_arc_wave","TITAN_ORDNANCE",1,0
+"mp_titanweapon_dumbfire_rockets","TITAN_ORDNANCE",1,0
+"mp_titanweapon_flame_wall","TITAN_ORDNANCE",1,0
+"mp_titanweapon_homing_rockets","TITAN_ORDNANCE",1,0
+"mp_titanweapon_laser_lite","TITAN_ORDNANCE",1,0
+"mp_titanweapon_salvo_rockets","TITAN_ORDNANCE",1,0
+"mp_titanweapon_shoulder_rockets","TITAN_ORDNANCE",1,0
+"mp_titanweapon_tracker_rockets","TITAN_ORDNANCE",1,0
+"mp_titanability_power_shot","TITAN_ORDNANCE",1,0
+"mp_titanability_tether_trap","TITAN_ORDNANCE",0,0
+"mp_titanability_basic_block","TITAN_SPECIAL",0,0
+"mp_titanability_particle_wall","TITAN_SPECIAL",0,0
+"mp_titanweapon_vortex_shield","TITAN_SPECIAL",1,0
+"mp_titanweapon_vortex_shield_ion","TITAN_SPECIAL",1,0
+"mp_titanweapon_heat_shield","TITAN_SPECIAL",1,0
+"mp_titanability_gun_shield","TITAN_SPECIAL",1,0
+"mp_titanability_smoke","TITAN_SPECIAL",0,0
+"mp_titanability_hover","TITAN_ANTIRODEO",0,0
+"mp_titanability_phase_dash","TITAN_ANTIRODEO",0,0
+"mp_titanability_laser_trip","TITAN_ANTIRODEO",0,0
+"mp_titanability_slow_trap","TITAN_ANTIRODEO",0,0
+"mp_titanability_ammo_swap","TITAN_ANTIRODEO",1,0
+"mp_titanability_sonar_pulse","TITAN_ANTIRODEO",1,0
+"mp_titanability_rocketeer_ammo_swap","TITAN_ANTIRODEO",0,0
+"mp_titanweapon_stun_laser","TITAN_SPECIAL",1,0
+"mp_titanability_rearm","TITAN_ANTIRODEO",1,0
+"mp_titancore_upgrade","TITAN_CORE_ABILITY",0,0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_executions.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_executions.csv new file mode 100644 index 00000000..09c4a4d1 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_executions.csv @@ -0,0 +1,26 @@ +ref,setfile,attackerAnim,attackerAnimVsAutoTitan,victimAnim_lt,victimAnim_md,victimAnim_hv,victimAnim_pt_lt,victimAnim_pt_md,victimAnim_pt_hv,attackerAnim_pt_lt,attackerAnim_pt_mt,attackerAnim_pt_ht,sound_1p,sound_3p,camAttach,type,name,description,image,hidden,cost,reqPrime,linkedExecutions
+"execution_legion","titan_ogre_minigun","htPRED_MP_Sync_Execution_Attacker","htPRED_MP_Sync_Execution_Attacker","t_MeleeExecuted_By_htPred","t_MeleeExecuted_By_htPred","t_MeleeExecuted_By_htPred","","","","","","","Ogre_1p_Sync_Melee","Ogre_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_LEGION_EXECUTION","#TITAN_EXECUTION_LEGION","#TITAN_EXECUTION_LEGION_DESC","rui/titan_loadout/execution/titan_execution_legion",0,0,0,""
+"execution_legion_prime","titan_ogre_legion_prime","htLegionPrime_MP_Sync_Execution_attacker","htLegionPrime_MP_Sync_Execution_attacker","t_MeleeExecuted_By_htLegionPrime","t_MeleeExecuted_By_htLegionPrime","t_MeleeExecuted_By_htLegionPrime","","","","","","","Ogre_1p_Sync_Melee","Ogre_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_LEGION_EXECUTION","#TITAN_EXECUTION_LEGION_PRIME","#TITAN_EXECUTION_LEGION_PRIME_DESC","rui/titan_loadout/execution/titan_execution_legion_prime",0,0,1,""
+"execution_scorch","titan_ogre_meteor","htThermite_MP_Sync_Execution_Attacker","htThermite_MP_Sync_Execution_Attacker","t_MeleeExecuted_By_htThermite","t_MeleeExecuted_By_htThermite","t_MeleeExecuted_By_htThermite","","","","","","","Ogre_1p_Sync_Melee","Ogre_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_SCORCH_EXECUTION","#TITAN_EXECUTION_SCORCH","#TITAN_EXECUTION_SCORCH_DESC","rui/titan_loadout/execution/titan_execution_scorch",0,0,0,""
+"execution_scorch_prime","titan_ogre_scorch_prime","htScorchPrime_MP_Sync_Execution_attacker","htScorchPrime_MP_Sync_Execution_attacker","t_MeleeExecuted_By_htScorchPrime","t_MeleeExecuted_By_htScorchPrime","t_MeleeExecuted_By_htScorchPrime","","","","","","","Ogre_1p_Sync_Melee","Ogre_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_SCORCH_EXECUTION","#TITAN_EXECUTION_SCORCH_PRIME","#TITAN_EXECUTION_SCORCH_PRIME_DESC","rui/titan_loadout/execution/titan_execution_scorch_prime",0,0,1,""
+"execution_ronin","titan_stryder_leadwall","lt_execution_attacker_sword_01","lt_execution_attacker_sword_01","lt_execution_victim_sword_01","mt_execution_victim_sword_01","ht_execution_victim_sword_01","pt_lt_execution_victim_sword_01","pt_mt_execution_victim_sword_01","pt_ht_execution_victim_sword_01","","","","Stryder_1p_Sync_Melee","Stryder_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_RONIN_EXECUTION","#TITAN_EXECUTION_RONIN","#TITAN_EXECUTION_RONIN_DESC","rui/titan_loadout/execution/titan_execution_ronin",0,0,0,""
+"execution_ronin_prime","titan_stryder_ronin_prime","lt_execution_attacker_sword_02_prime","lt_execution_attacker_sword_02_prime","lt_execution_victim_sword_02","mt_execution_victim_sword_02","ht_execution_victim_sword_02","pt_lt_execution_victim_sword_02","pt_mt_execution_victim_sword_02","pt_ht_execution_victim_sword_02","","","","Stryder_1p_Sync_Melee","Stryder_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_RONIN_EXECUTION","#TITAN_EXECUTION_RONIN_PRIME","#TITAN_EXECUTION_RONIN_PRIME_DESC","rui/titan_loadout/execution/titan_execution_ronin_prime",0,0,1,""
+"execution_ion","titan_atlas_stickybomb","mt_execution_attacker_laser","mt_execution_attacker_laser","lt_execution_victim_laser","mt_execution_victim_laser","ht_execution_victim_laser","pt_execution_victim_laser","pt_execution_victim_laser","pt_execution_victim_laser","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_ION_EXECUTION","#TITAN_EXECUTION_ION","#TITAN_EXECUTION_ION_DESC","rui/titan_loadout/execution/titan_execution_ion",0,0,0,""
+"execution_ion_prime","titan_atlas_ion_prime","mt_execution_attacker_ion_prime","mt_execution_attacker_ion_prime","lt_execution_victim_ion_prime","mt_execution_victim_ion_prime","ht_execution_victim_ion_prime","pt_execution_victim_ion_prime","pt_execution_victim_ion_prime","pt_execution_victim_ion_prime","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_ION_EXECUTION","#TITAN_EXECUTION_ION_PRIME","#TITAN_EXECUTION_ION_PRIME_DESC","rui/titan_loadout/execution/titan_execution_ion_prime",0,0,1,""
+"execution_bt","titan_buddy","bt_synced_titan_execute_flip_takedown_A","bt_synced_titan_execute_flip_takedown_A","titan_synced_bt_execute_flip_takedown_V","titan_synced_bt_execute_flip_takedown_V","titan_synced_bt_execute_flip_takedown_V","","","","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","","","","",1,0,0,""
+"execution_tone","titan_atlas_tracker","mt_execution_attacker_tone","mt_execution_attacker_tone_auto","lt_execution_victim_tone","mt_execution_victim_tone","ht_execution_victim_tone","pt_execution_victim_tone","pt_execution_victim_tone","pt_execution_victim_tone","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_TONE_EXECUTION","#TITAN_EXECUTION_TONE","#TITAN_EXECUTION_TONE_DESC","rui/titan_loadout/execution/titan_execution_tone",0,0,0,""
+"execution_tone_prime","titan_atlas_tone_prime","mt_execution_attacker_tone_prime","mt_execution_attacker_tone_prime","lt_execution_victim_tone_prime","mt_execution_victim_tone_prime","ht_execution_victim_tone_prime","","","","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_TONE_EXECUTION","#TITAN_EXECUTION_TONE_PRIME","#TITAN_EXECUTION_TONE_PRIME_DESC","rui/titan_loadout/execution/titan_execution_tone_prime",0,0,1,""
+"execution_northstar","titan_stryder_sniper","lt_execution_attacker_sweep_01","lt_execution_attacker_sweep_01","lt_execution_victim_sweep_01","mt_execution_victim_sweep_01","ht_execution_victim_sweep_01","","","","","","","Stryder_1p_Sync_Melee","Stryder_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_NORTHSTAR_EXECUTION","#TITAN_EXECUTION_NORTHSTAR","#TITAN_EXECUTION_NORTHSTAR_DESC","rui/titan_loadout/execution/titan_execution_northstar",0,0,0,""
+"execution_northstar_prime","titan_stryder_northstar_prime","lt_execution_attacker_armsrip","lt_execution_attacker_armsrip","lt_execution_victim_armsrip","mt_execution_victim_armsrip","ht_execution_victim_armsrip","","","","","","","Stryder_1p_Sync_Melee","Stryder_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_NORTHSTAR_EXECUTION","#TITAN_EXECUTION_NORTHSTAR_PRIME","#TITAN_EXECUTION_NORTHSTAR_PRIME_DESC","rui/titan_loadout/execution/titan_execution_northstar_prime",0,0,1,""
+"execution_vanguard","titan_atlas_vanguard","mt_execution_attacker_vanguard","mt_execution_autoTitan_attacker_vanguard","lt_execution_victim_vanguard","mt_execution_victim_vanguard","ht_execution_victim_vanguard","pt_lt_execution_victim_vanguard","pt_mt_execution_victim_vanguard","pt_ht_execution_victim_vanguard","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","TITAN_VANGUARD_EXECUTION","#TITAN_EXECUTION_VANGUARD","#TITAN_EXECUTION_VANGUARD_DESC","rui/titan_loadout/execution/titan_execution_monarch",0,0,0,""
+"execution_vanguard_kit","titan_atlas_vanguard_kit","mt_execution_battery_attacker_vanguard","mt_execution_battery_attacker_vanguard","lt_execution_battery_victim_vanguard","mt_execution_battery_victim_vanguard","ht_execution_battery_victim_vanguard","pt_lt_execution_battery_victim_vanguard","pt_mt_execution_battery_victim_vanguard","pt_ht_execution_battery_victim_vanguard","pt_lt_execution_battery_attacker_vanguard","pt_mt_execution_battery_attacker_vanguard","pt_ht_execution_battery_attacker_vanguard","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","","","","",1,0,0,""
+"execution_random_0","","","","","","","","","","","","","","","","TITAN_ION_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_ion,execution_ion_prime"
+"execution_random_1","","","","","","","","","","","","","","","","TITAN_SCORCH_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_scorch,execution_scorch_prime"
+"execution_random_2","","","","","","","","","","","","","","","","TITAN_NORTHSTAR_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_northstar,execution_northstar_prime"
+"execution_random_3","","","","","","","","","","","","","","","","TITAN_RONIN_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_ronin,execution_ronin_prime"
+"execution_random_4","","","","","","","","","","","","","","","","TITAN_TONE_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_tone,execution_tone_prime"
+"execution_random_5","","","","","","","","","","","","","","","","TITAN_LEGION_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_legion,execution_legion_prime"
+"execution_random_6","","","","","","","","","","","","","","","","TITAN_VANGUARD_EXECUTION","#TITAN_EXECUTION_RANDOM","#TITAN_EXECUTION_RANDOM_DESC","rui/pilot_loadout/execution/execution_random",0,0,0,"execution_vanguard"
+"execution_bt_flip","titan_buddy","bt_synced_titan_execute_flip_takedown_A","bt_synced_titan_execute_flip_takedown_A","titan_synced_bt_execute_flip_takedown_V","titan_synced_bt_execute_flip_takedown_V","titan_synced_bt_execute_flip_takedown_V","","","","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","","","","",1,0,0,""
+"execution_bt_kickshoot","titan_buddy","bt_synced_titan_execute_kickshoot_A","bt_synced_titan_execute_kickshoot_A","titan_synced_bt_execute_kickshoot_V","titan_synced_bt_execute_kickshoot_V","titan_synced_bt_execute_kickshoot_V","pt_lt_synced_bt_execute_kickshoot_V","pt_mt_synced_bt_execute_kickshoot_V","pt_ht_synced_bt_execute_kickshoot_V","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","","","","",1,0,0,""
+"execution_bt_pilotrip","titan_buddy","bt_synced_titan_execute_pilot_rip_A","bt_synced_titan_execute_pilot_rip_A","titan_synced_bt_execute_pilot_rip_V","titan_synced_bt_execute_pilot_rip_V","titan_synced_bt_execute_pilot_rip_V","pt_lt_synced_bt_execute_pilot_rip_V","pt_mt_synced_bt_execute_pilot_rip_V","pt_ht_synced_bt_execute_pilot_rip_V","","","","Atlas_1p_Sync_Melee","Atlas_3p_Sync_Melee","vehicle_driver_eyes camera_2 camera_3","","","","",1,0,0,""
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_fd_upgrades.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_fd_upgrades.csv new file mode 100644 index 00000000..aab61afb --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_fd_upgrades.csv @@ -0,0 +1,50 @@ +ref,parentref,upgradeType,name,description,image,lockedImage,cost,slot,unlockLevel
+"fd_upgrade_tone_utility_tier_1","tone","utility","#FD_UPGRADE_TONE_UTILITY_TIER_1","#FD_UPGRADE_TONE_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_tone_signal_strength","rui/menu/fd_menu/disabled/upgrade_tone_signal_strength",1,2,12
+"fd_upgrade_tone_utility_tier_2","tone","utility","#FD_UPGRADE_TONE_UTILITY_TIER_2","#FD_UPGRADE_TONE_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_tone_weak_points","rui/menu/fd_menu/disabled/upgrade_tone_weak_points",2,3,6
+"fd_upgrade_tone_defense_tier_1","tone","defensive","#FD_UPGRADE_TONE_DEFENSE_TIER_1","#FD_UPGRADE_TONE_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_tone_chassis","rui/menu/fd_menu/disabled/upgrade_tone_chassis",1,0,4
+"fd_upgrade_tone_defense_tier_2","tone","defensive","#FD_UPGRADE_TONE_DEFENSE_TIER_2","#FD_UPGRADE_TONE_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_tone_shield","rui/menu/fd_menu/disabled/upgrade_tone_shield",2,1,10
+"fd_upgrade_tone_weapon_tier_1","tone","weapon","#FD_UPGRADE_TONE_WEAPON_TIER_1","#FD_UPGRADE_TONE_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_tone_splasher_rounds","rui/menu/fd_menu/disabled/upgrade_tone_splasher_rounds",1,4,8
+"fd_upgrade_tone_weapon_tier_2","tone","weapon","#FD_UPGRADE_TONE_WEAPON_TIER_2","#FD_UPGRADE_TONE_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_tone_extended_ammo","rui/menu/fd_menu/disabled/upgrade_tone_extended_ammo",2,5,2
+"fd_upgrade_tone_ultimate","tone","ultimate","#FD_UPGRADE_TONE_ULTIMATE","#FD_UPGRADE_TONE_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_tone_salvo_core","rui/menu/fd_menu/disabled/upgrade_tone_salvo_core",3,6,14
+"fd_upgrade_ion_utility_tier_1","ion","utility","#FD_UPGRADE_ION_UTILITY_TIER_1","#FD_UPGRADE_ION_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_ion_energy_master","rui/menu/fd_menu/disabled/upgrade_ion_energy_master",1,2,12
+"fd_upgrade_ion_utility_tier_2","ion","utility","#FD_UPGRADE_ION_UTILITY_TIER_2","#FD_UPGRADE_ION_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_ion_energy_storage","rui/menu/fd_menu/disabled/upgrade_ion_energy_storage",2,3,6
+"fd_upgrade_ion_defense_tier_1","ion","defensive","#FD_UPGRADE_ION_DEFENSE_TIER_1","#FD_UPGRADE_ION_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_ion_chassis","rui/menu/fd_menu/disabled/upgrade_ion_chassis",1,0,4
+"fd_upgrade_ion_defense_tier_2","ion","defensive","#FD_UPGRADE_ION_DEFENSE_TIER_2","#FD_UPGRADE_ION_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_ion_shield","rui/menu/fd_menu/disabled/upgrade_ion_shield",2,1,10
+"fd_upgrade_ion_weapon_tier_1","ion","weapon","#FD_UPGRADE_ION_WEAPON_TIER_1","#FD_UPGRADE_ION_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_ion_split_shot","rui/menu/fd_menu/disabled/upgrade_ion_split_shot",1,4,2
+"fd_upgrade_ion_weapon_tier_2","ion","weapon","#FD_UPGRADE_ION_WEAPON_TIER_2","#FD_UPGRADE_ION_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_ion_splitter_damage","rui/menu/fd_menu/disabled/upgrade_ion_splitter_damage",2,5,8
+"fd_upgrade_ion_ultimate","ion","ultimate","#FD_UPGRADE_ION_ULTIMATE","#FD_UPGRADE_ION_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_ion_laser_reset","rui/menu/fd_menu/disabled/upgrade_ion_laser_reset",3,6,14
+"fd_upgrade_vanguard_utility_tier_1","vanguard","utility","#FD_UPGRADE_VANGUARD_UTILITY_TIER_1","#FD_UPGRADE_VANGUARD_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_monarch_energize_smoke","rui/menu/fd_menu/disabled/upgrade_monarch_energize_smoke",1,2,2
+"fd_upgrade_vanguard_utility_tier_2","vanguard","utility","#FD_UPGRADE_VANGUARD_UTILITY_TIER_2","#FD_UPGRADE_VANGUARD_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_monarch_energize_smoke_2","rui/menu/fd_menu/disabled/upgrade_monarch_energize_smoke_2",2,3,8
+"fd_upgrade_vanguard_defense_tier_1","vanguard","defensive","#FD_UPGRADE_VANGUARD_DEFENSE_TIER_1","#FD_UPGRADE_VANGUARD_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_monarch_chassis","rui/menu/fd_menu/disabled/upgrade_monarch_chassis",1,0,4
+"fd_upgrade_vanguard_defense_tier_2","vanguard","defensive","#FD_UPGRADE_VANGUARD_DEFENSE_TIER_2","#FD_UPGRADE_VANGUARD_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_monarch_shield","rui/menu/fd_menu/disabled/upgrade_monarch_shield",2,1,10
+"fd_upgrade_vanguard_weapon_tier_1","vanguard","weapon","#FD_UPGRADE_VANGUARD_WEAPON_TIER_1","#FD_UPGRADE_VANGUARD_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_monarch_threat_optics","rui/menu/fd_menu/disabled/upgrade_monarch_threat_optics",1,4,6
+"fd_upgrade_vanguard_weapon_tier_2","vanguard","weapon","#FD_UPGRADE_VANGUARD_WEAPON_TIER_2","#FD_UPGRADE_VANGUARD_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_monarch_xo16_sniper","rui/menu/fd_menu/disabled/upgrade_monarch_xo16_sniper",2,5,12
+"fd_upgrade_vanguard_ultimate","vanguard","ultimate","#FD_UPGRADE_VANGUARD_ULTIMATE","#FD_UPGRADE_VANGUARD_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_monarch_apex_titan","rui/menu/fd_menu/disabled/upgrade_monarch_apex_titan",3,6,14
+"fd_upgrade_ronin_utility_tier_1","ronin","utility","#FD_UPGRADE_RONIN_UTILITY_TIER_1","#FD_UPGRADE_RONIN_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_ronin_ghost_machine","rui/menu/fd_menu/disabled/upgrade_ronin_ghost_machine",1,2,6
+"fd_upgrade_ronin_utility_tier_2","ronin","utility","#FD_UPGRADE_RONIN_UTILITY_TIER_2","#FD_UPGRADE_RONIN_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_ronin_wraith","rui/menu/fd_menu/disabled/upgrade_ronin_wraith",2,3,12
+"fd_upgrade_ronin_defense_tier_1","ronin","defensive","#FD_UPGRADE_RONIN_DEFENSE_TIER_1","#FD_UPGRADE_RONIN_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_ronin_chassis","rui/menu/fd_menu/disabled/upgrade_ronin_chassis",1,0,4
+"fd_upgrade_ronin_defense_tier_2","ronin","defensive","#FD_UPGRADE_RONIN_DEFENSE_TIER_2","#FD_UPGRADE_RONIN_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_ronin_shield","rui/menu/fd_menu/disabled/upgrade_ronin_shield",2,1,10
+"fd_upgrade_ronin_weapon_tier_1","ronin","weapon","#FD_UPGRADE_RONIN_WEAPON_TIER_1","#FD_UPGRADE_RONIN_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_ronin_sword_mastery","rui/menu/fd_menu/disabled/upgrade_ronin_sword_mastery",1,4,2
+"fd_upgrade_ronin_weapon_tier_2","ronin","weapon","#FD_UPGRADE_RONIN_WEAPON_TIER_2","#FD_UPGRADE_RONIN_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_ronin_kinetic_transfer","rui/menu/fd_menu/disabled/upgrade_ronin_kinetic_transfer",2,5,8
+"fd_upgrade_ronin_ultimate","ronin","ultimate","#FD_UPGRADE_RONIN_ULTIMATE","#FD_UPGRADE_RONIN_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_ronin_blade_master","rui/menu/fd_menu/disabled/upgrade_ronin_blade_master",3,6,14
+"fd_upgrade_northstar_utility_tier_1","northstar","utility","#FD_UPGRADE_NORTHSTAR_UTILITY_TIER_1","#FD_UPGRADE_NORTHSTAR_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_northstar_explosive_trap","rui/menu/fd_menu/disabled/upgrade_northstar_explosive_trap",1,2,2
+"fd_upgrade_northstar_utility_tier_2","northstar","utility","#FD_UPGRADE_NORTHSTAR_UTILITY_TIER_2","#FD_UPGRADE_NORTHSTAR_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_northstar_trap_master","rui/menu/fd_menu/disabled/upgrade_northstar_trap_master",2,3,8
+"fd_upgrade_northstar_defense_tier_1","northstar","defensive","#FD_UPGRADE_NORTHSTAR_DEFENSE_TIER_1","#FD_UPGRADE_NORTHSTAR_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_northstar_chassis","rui/menu/fd_menu/disabled/upgrade_northstar_chassis",1,0,4
+"fd_upgrade_northstar_defense_tier_2","northstar","defensive","#FD_UPGRADE_NORTHSTAR_DEFENSE_TIER_2","#FD_UPGRADE_NORTHSTAR_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_northstar_shield","rui/menu/fd_menu/disabled/upgrade_northstar_shield",2,1,10
+"fd_upgrade_northstar_weapon_tier_1","northstar","weapon","#FD_UPGRADE_NORTHSTAR_WEAPON_TIER_1","#FD_UPGRADE_NORTHSTAR_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_northstar_quick_charge","rui/menu/fd_menu/disabled/upgrade_northstar_quick_charge",1,4,6
+"fd_upgrade_northstar_weapon_tier_2","northstar","weapon","#FD_UPGRADE_NORTHSTAR_WEAPON_TIER_2","#FD_UPGRADE_NORTHSTAR_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_northstar_one_shot_kill","rui/menu/fd_menu/disabled/upgrade_northstar_one_shot_kill",2,5,12
+"fd_upgrade_northstar_ultimate","northstar","ultimate","#FD_UPGRADE_NORTHSTAR_ULTIMATE","#FD_UPGRADE_NORTHSTAR_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_northstar_twin_cluster","rui/menu/fd_menu/disabled/upgrade_northstar_twin_cluster",3,6,14
+"fd_upgrade_scorch_utility_tier_1","scorch","utility","#FD_UPGRADE_SCORCH_UTILITY_TIER_1","#FD_UPGRADE_SCORCH_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_scorch_hot_streak","rui/menu/fd_menu/disabled/upgrade_scorch_hot_streak",1,2,6
+"fd_upgrade_scorch_utility_tier_2","scorch","utility","#FD_UPGRADE_SCORCH_UTILITY_TIER_2","#FD_UPGRADE_SCORCH_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_scorch_roaring_flame","rui/menu/fd_menu/disabled/upgrade_scorch_roaring_flame",2,3,8
+"fd_upgrade_scorch_defense_tier_1","scorch","defensive","#FD_UPGRADE_SCORCH_DEFENSE_TIER_1","#FD_UPGRADE_SCORCH_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_scorch_chassis","rui/menu/fd_menu/disabled/upgrade_scorch_chassis",1,0,4
+"fd_upgrade_scorch_defense_tier_2","scorch","defensive","#FD_UPGRADE_SCORCH_DEFENSE_TIER_2","#FD_UPGRADE_SCORCH_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_scorch_shield","rui/menu/fd_menu/disabled/upgrade_scorch_shield",2,1,10
+"fd_upgrade_scorch_weapon_tier_1","scorch","weapon","#FD_UPGRADE_SCORCH_WEAPON_TIER_1","#FD_UPGRADE_SCORCH_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_scorch_double_threat","rui/menu/fd_menu/disabled/upgrade_scorch_double_threat",1,4,2
+"fd_upgrade_scorch_weapon_tier_2","scorch","weapon","#FD_UPGRADE_SCORCH_WEAPON_TIER_2","#FD_UPGRADE_SCORCH_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_scorch_triple_threat","rui/menu/fd_menu/disabled/upgrade_scorch_triple_threat",2,5,12
+"fd_upgrade_scorch_ultimate","scorch","ultimate","#FD_UPGRADE_SCORCH_ULTIMATE","#FD_UPGRADE_SCORCH_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_scorch_explosive_barrells","rui/menu/fd_menu/disabled/upgrade_scorch_explosive_barrells",3,6,14
+"fd_upgrade_legion_utility_tier_1","legion","utility","#FD_UPGRADE_LEGION_UTILITY_TIER_1","#FD_UPGRADE_LEGION_UTILITY_TIER_1_DESC","rui/menu/fd_menu/upgrade_legion_executioner","rui/menu/fd_menu/disabled/upgrade_legion_executioner",1,2,6
+"fd_upgrade_legion_utility_tier_2","legion","utility","#FD_UPGRADE_LEGION_UTILITY_TIER_2","#FD_UPGRADE_LEGION_UTILITY_TIER_2_DESC","rui/menu/fd_menu/upgrade_legion_drill_shot","rui/menu/fd_menu/disabled/upgrade_legion_drill_shot",2,3,12
+"fd_upgrade_legion_defense_tier_1","legion","defensive","#FD_UPGRADE_LEGION_DEFENSE_TIER_1","#FD_UPGRADE_LEGION_DEFENSE_TIER_1_DESC","rui/menu/fd_menu/upgrade_legion_chassis","rui/menu/fd_menu/disabled/upgrade_legion_chassis",1,0,4
+"fd_upgrade_legion_defense_tier_2","legion","defensive","#FD_UPGRADE_LEGION_DEFENSE_TIER_2","#FD_UPGRADE_LEGION_DEFENSE_TIER_2_DESC","rui/menu/fd_menu/upgrade_legion_shield","rui/menu/fd_menu/disabled/upgrade_legion_shield",2,1,10
+"fd_upgrade_legion_weapon_tier_1","legion","weapon","#FD_UPGRADE_LEGION_WEAPON_TIER_1","#FD_UPGRADE_LEGION_WEAPON_TIER_1_DESC","rui/menu/fd_menu/upgrade_legion_piercing_shot","rui/menu/fd_menu/disabled/upgrade_legion_piercing_shot",1,4,2
+"fd_upgrade_legion_weapon_tier_2","legion","weapon","#FD_UPGRADE_LEGION_WEAPON_TIER_2","#FD_UPGRADE_LEGION_WEAPON_TIER_2_DESC","rui/menu/fd_menu/upgrade_legion_redirect","rui/menu/fd_menu/disabled/upgrade_legion_redirect",2,5,8
+"fd_upgrade_legion_ultimate","legion","ultimate","#FD_UPGRADE_LEGION_ULTIMATE","#FD_UPGRADE_LEGION_ULTIMATE_DESC","rui/menu/fd_menu/upgrade_legion_double_down","rui/menu/fd_menu/disabled/upgrade_legion_double_down",3,6,14
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_nose_art.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_nose_art.csv new file mode 100644 index 00000000..56bcf556 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_nose_art.csv @@ -0,0 +1,191 @@ +ref,titanRef,image,name,cost
+"ion_nose_art_none","ion","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"ion_nose_art_01","ion","rui/titan_loadout/nose_art/ion_nose_art_01","#ION_NOSE_ART_01",0
+"ion_nose_art_02","ion","rui/titan_loadout/nose_art/ion_nose_art_02","#ION_NOSE_ART_02",0
+"ion_nose_art_03","ion","rui/titan_loadout/nose_art/ion_nose_art_03","#ION_NOSE_ART_03",0
+"ion_nose_art_04","ion","rui/titan_loadout/nose_art/ion_nose_art_04","#ION_NOSE_ART_04",0
+"ion_nose_art_05","ion","rui/titan_loadout/nose_art/ion_nose_art_05","#ION_NOSE_ART_05",300
+"ion_nose_art_06","ion","rui/titan_loadout/nose_art/ion_nose_art_06","#ION_NOSE_ART_06",0
+"ion_nose_art_07","ion","rui/titan_loadout/nose_art/ion_nose_art_07","#ION_NOSE_ART_07",0
+"ion_nose_art_08","ion","rui/titan_loadout/nose_art/ion_nose_art_08","#ION_NOSE_ART_08",0
+"ion_nose_art_09","ion","rui/titan_loadout/nose_art/ion_nose_art_09","#ION_NOSE_ART_09",0
+"ion_nose_art_10","ion","rui/titan_loadout/nose_art/ion_nose_art_10","#ION_NOSE_ART_10",0
+"ion_nose_art_11","ion","rui/titan_loadout/nose_art/ion_nose_art_11","#ION_NOSE_ART_11",0
+"ion_nose_art_12","ion","rui/titan_loadout/nose_art/ion_nose_art_12","#ION_NOSE_ART_12",0
+"ion_nose_art_13","ion","rui/titan_loadout/nose_art/ion_nose_art_13","#ION_NOSE_ART_13",0
+"ion_nose_art_14","ion","rui/titan_loadout/nose_art/ion_nose_art_14","#ION_NOSE_ART_14",0
+"scorch_nose_art_none","scorch","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"scorch_nose_art_01","scorch","rui/titan_loadout/nose_art/scorch_nose_art_01","#SCORCH_NOSE_ART_01",0
+"scorch_nose_art_02","scorch","rui/titan_loadout/nose_art/scorch_nose_art_02","#SCORCH_NOSE_ART_02",0
+"scorch_nose_art_03","scorch","rui/titan_loadout/nose_art/scorch_nose_art_03","#SCORCH_NOSE_ART_03",0
+"scorch_nose_art_04","scorch","rui/titan_loadout/nose_art/scorch_nose_art_04","#SCORCH_NOSE_ART_04",0
+"scorch_nose_art_05","scorch","rui/titan_loadout/nose_art/scorch_nose_art_05","#SCORCH_NOSE_ART_05",0
+"scorch_nose_art_06","scorch","rui/titan_loadout/nose_art/scorch_nose_art_06","#SCORCH_NOSE_ART_06",0
+"scorch_nose_art_07","scorch","rui/titan_loadout/nose_art/scorch_nose_art_07","#SCORCH_NOSE_ART_07",0
+"scorch_nose_art_08","scorch","rui/titan_loadout/nose_art/scorch_nose_art_08","#SCORCH_NOSE_ART_08",0
+"scorch_nose_art_09","scorch","rui/titan_loadout/nose_art/scorch_nose_art_09","#SCORCH_NOSE_ART_09",0
+"scorch_nose_art_10","scorch","rui/titan_loadout/nose_art/scorch_nose_art_10","#SCORCH_NOSE_ART_10",0
+"scorch_nose_art_11","scorch","rui/titan_loadout/nose_art/scorch_nose_art_11","#SCORCH_NOSE_ART_11",0
+"scorch_nose_art_12","scorch","rui/titan_loadout/nose_art/scorch_nose_art_12","#SCORCH_NOSE_ART_12",300
+"scorch_nose_art_13","scorch","rui/titan_loadout/nose_art/scorch_nose_art_13","#SCORCH_NOSE_ART_13",0
+"scorch_nose_art_14","scorch","rui/titan_loadout/nose_art/scorch_nose_art_14","#SCORCH_NOSE_ART_14",0
+"ronin_nose_art_none","ronin","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"ronin_nose_art_01","ronin","rui/titan_loadout/nose_art/ronin_nose_art_01","#RONIN_NOSE_ART_01",0
+"ronin_nose_art_02","ronin","rui/titan_loadout/nose_art/ronin_nose_art_02","#RONIN_NOSE_ART_02",0
+"ronin_nose_art_03","ronin","rui/titan_loadout/nose_art/ronin_nose_art_03","#RONIN_NOSE_ART_03",0
+"ronin_nose_art_04","ronin","rui/titan_loadout/nose_art/ronin_nose_art_04","#RONIN_NOSE_ART_04",0
+"ronin_nose_art_05","ronin","rui/titan_loadout/nose_art/ronin_nose_art_05","#RONIN_NOSE_ART_05",0
+"ronin_nose_art_06","ronin","rui/titan_loadout/nose_art/ronin_nose_art_06","#RONIN_NOSE_ART_06",0
+"ronin_nose_art_07","ronin","rui/titan_loadout/nose_art/ronin_nose_art_07","#RONIN_NOSE_ART_07",0
+"ronin_nose_art_08","ronin","rui/titan_loadout/nose_art/ronin_nose_art_08","#RONIN_NOSE_ART_08",300
+"ronin_nose_art_09","ronin","rui/titan_loadout/nose_art/ronin_nose_art_09","#RONIN_NOSE_ART_09",0
+"ronin_nose_art_10","ronin","rui/titan_loadout/nose_art/ronin_nose_art_10","#RONIN_NOSE_ART_10",0
+"ronin_nose_art_11","ronin","rui/titan_loadout/nose_art/ronin_nose_art_11","#RONIN_NOSE_ART_11",0
+"ronin_nose_art_12","ronin","rui/titan_loadout/nose_art/ronin_nose_art_12","#RONIN_NOSE_ART_12",300
+"ronin_nose_art_13","ronin","rui/titan_loadout/nose_art/ronin_nose_art_13","#RONIN_NOSE_ART_13",0
+"ronin_nose_art_14","ronin","rui/titan_loadout/nose_art/ronin_nose_art_14","#RONIN_NOSE_ART_14",0
+"tone_nose_art_none","tone","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"tone_nose_art_01","tone","rui/titan_loadout/nose_art/tone_nose_art_01","#TONE_NOSE_ART_01",0
+"tone_nose_art_02","tone","rui/titan_loadout/nose_art/tone_nose_art_02","#TONE_NOSE_ART_02",0
+"tone_nose_art_03","tone","rui/titan_loadout/nose_art/tone_nose_art_03","#TONE_NOSE_ART_03",0
+"tone_nose_art_04","tone","rui/titan_loadout/nose_art/tone_nose_art_04","#TONE_NOSE_ART_04",0
+"tone_nose_art_05","tone","rui/titan_loadout/nose_art/tone_nose_art_05","#TONE_NOSE_ART_05",0
+"tone_nose_art_06","tone","rui/titan_loadout/nose_art/tone_nose_art_06","#TONE_NOSE_ART_06",0
+"tone_nose_art_07","tone","rui/titan_loadout/nose_art/tone_nose_art_07","#TONE_NOSE_ART_07",0
+"tone_nose_art_08","tone","rui/titan_loadout/nose_art/tone_nose_art_08","#TONE_NOSE_ART_08",0
+"tone_nose_art_09","tone","rui/titan_loadout/nose_art/tone_nose_art_09","#TONE_NOSE_ART_09",0
+"tone_nose_art_10","tone","rui/titan_loadout/nose_art/tone_nose_art_10","#TONE_NOSE_ART_10",0
+"tone_nose_art_11","tone","rui/titan_loadout/nose_art/tone_nose_art_11","#TONE_NOSE_ART_11",300
+"tone_nose_art_12","tone","rui/titan_loadout/nose_art/tone_nose_art_12","#TONE_NOSE_ART_12",300
+"tone_nose_art_13","tone","rui/titan_loadout/nose_art/tone_nose_art_13","#TONE_NOSE_ART_13",0
+"tone_nose_art_14","tone","rui/titan_loadout/nose_art/tone_nose_art_14","#TONE_NOSE_ART_14",0
+"northstar_nose_art_none","northstar","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"northstar_nose_art_01","northstar","rui/titan_loadout/nose_art/northstar_nose_art_01","#NORTHSTAR_NOSE_ART_01",0
+"northstar_nose_art_02","northstar","rui/titan_loadout/nose_art/northstar_nose_art_02","#NORTHSTAR_NOSE_ART_02",0
+"northstar_nose_art_03","northstar","rui/titan_loadout/nose_art/northstar_nose_art_03","#NORTHSTAR_NOSE_ART_03",0
+"northstar_nose_art_04","northstar","rui/titan_loadout/nose_art/northstar_nose_art_04","#NORTHSTAR_NOSE_ART_04",0
+"northstar_nose_art_05","northstar","rui/titan_loadout/nose_art/northstar_nose_art_05","#NORTHSTAR_NOSE_ART_05",0
+"northstar_nose_art_06","northstar","rui/titan_loadout/nose_art/northstar_nose_art_06","#NORTHSTAR_NOSE_ART_06",0
+"northstar_nose_art_07","northstar","rui/titan_loadout/nose_art/northstar_nose_art_07","#NORTHSTAR_NOSE_ART_07",0
+"northstar_nose_art_08","northstar","rui/titan_loadout/nose_art/northstar_nose_art_08","#NORTHSTAR_NOSE_ART_08",0
+"northstar_nose_art_09","northstar","rui/titan_loadout/nose_art/northstar_nose_art_09","#NORTHSTAR_NOSE_ART_09",0
+"northstar_nose_art_10","northstar","rui/titan_loadout/nose_art/northstar_nose_art_10","#NORTHSTAR_NOSE_ART_10",0
+"northstar_nose_art_11","northstar","rui/titan_loadout/nose_art/northstar_nose_art_11","#NORTHSTAR_NOSE_ART_11",0
+"northstar_nose_art_12","northstar","rui/titan_loadout/nose_art/northstar_nose_art_12","#NORTHSTAR_NOSE_ART_12",300
+"northstar_nose_art_13","northstar","rui/titan_loadout/nose_art/northstar_nose_art_13","#NORTHSTAR_NOSE_ART_13",300
+"northstar_nose_art_14","northstar","rui/titan_loadout/nose_art/northstar_nose_art_14","#NORTHSTAR_NOSE_ART_14",0
+"legion_nose_art_none","legion","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"legion_nose_art_01","legion","rui/titan_loadout/nose_art/legion_nose_art_01","#LEGION_NOSE_ART_01",0
+"legion_nose_art_02","legion","rui/titan_loadout/nose_art/legion_nose_art_02","#LEGION_NOSE_ART_02",0
+"legion_nose_art_03","legion","rui/titan_loadout/nose_art/legion_nose_art_03","#LEGION_NOSE_ART_03",0
+"legion_nose_art_04","legion","rui/titan_loadout/nose_art/legion_nose_art_04","#LEGION_NOSE_ART_04",0
+"legion_nose_art_05","legion","rui/titan_loadout/nose_art/legion_nose_art_05","#LEGION_NOSE_ART_05",0
+"legion_nose_art_06","legion","rui/titan_loadout/nose_art/legion_nose_art_06","#LEGION_NOSE_ART_06",0
+"legion_nose_art_07","legion","rui/titan_loadout/nose_art/legion_nose_art_07","#LEGION_NOSE_ART_07",0
+"legion_nose_art_08","legion","rui/titan_loadout/nose_art/legion_nose_art_08","#LEGION_NOSE_ART_08",0
+"legion_nose_art_09","legion","rui/titan_loadout/nose_art/legion_nose_art_09","#LEGION_NOSE_ART_09",0
+"legion_nose_art_10","legion","rui/titan_loadout/nose_art/legion_nose_art_10","#LEGION_NOSE_ART_10",0
+"legion_nose_art_11","legion","rui/titan_loadout/nose_art/legion_nose_art_11","#LEGION_NOSE_ART_11",0
+"legion_nose_art_12","legion","rui/titan_loadout/nose_art/legion_nose_art_12","#LEGION_NOSE_ART_12",300
+"legion_nose_art_13","legion","rui/titan_loadout/nose_art/legion_nose_art_13","#LEGION_NOSE_ART_13",0
+"legion_nose_art_14","legion","rui/titan_loadout/nose_art/legion_nose_art_14","#LEGION_NOSE_ART_14",300
+"ion_nose_art_17","ion","rui/titan_loadout/nose_art/ion_nose_art_17","#ION_NOSE_ART_17",0
+"ion_nose_art_18","ion","rui/titan_loadout/nose_art/ion_nose_art_18","#ION_NOSE_ART_18",0
+"ion_nose_art_19","ion","rui/titan_loadout/nose_art/ion_nose_art_19","#ION_NOSE_ART_19",0
+"ion_nose_art_20","ion","rui/titan_loadout/nose_art/ion_nose_art_20","#ION_NOSE_ART_20",0
+"ion_nose_art_21","ion","rui/titan_loadout/nose_art/ion_nose_art_21","#ION_NOSE_ART_21",0
+"scorch_nose_art_15","scorch","rui/titan_loadout/nose_art/scorch_nose_art_15","#SCORCH_NOSE_ART_15",0
+"scorch_nose_art_16","scorch","rui/titan_loadout/nose_art/scorch_nose_art_16","#SCORCH_NOSE_ART_16",0
+"scorch_nose_art_17","scorch","rui/titan_loadout/nose_art/scorch_nose_art_17","#SCORCH_NOSE_ART_17",0
+"scorch_nose_art_18","scorch","rui/titan_loadout/nose_art/scorch_nose_art_18","#SCORCH_NOSE_ART_18",0
+"scorch_nose_art_19","scorch","rui/titan_loadout/nose_art/scorch_nose_art_19","#SCORCH_NOSE_ART_19",0
+"ronin_nose_art_16","ronin","rui/titan_loadout/nose_art/ronin_nose_art_16","#RONIN_NOSE_ART_16",0
+"ronin_nose_art_17","ronin","rui/titan_loadout/nose_art/ronin_nose_art_17","#RONIN_NOSE_ART_17",0
+"ronin_nose_art_18","ronin","rui/titan_loadout/nose_art/ronin_nose_art_18","#RONIN_NOSE_ART_18",0
+"ronin_nose_art_19","ronin","rui/titan_loadout/nose_art/ronin_nose_art_19","#RONIN_NOSE_ART_19",0
+"ronin_nose_art_20","ronin","rui/titan_loadout/nose_art/ronin_nose_art_20","#RONIN_NOSE_ART_20",0
+"tone_nose_art_17","tone","rui/titan_loadout/nose_art/tone_nose_art_17","#TONE_NOSE_ART_17",0
+"tone_nose_art_18","tone","rui/titan_loadout/nose_art/tone_nose_art_18","#TONE_NOSE_ART_18",0
+"tone_nose_art_19","tone","rui/titan_loadout/nose_art/tone_nose_art_19","#TONE_NOSE_ART_19",0
+"tone_nose_art_20","tone","rui/titan_loadout/nose_art/tone_nose_art_20","#TONE_NOSE_ART_20",0
+"tone_nose_art_21","tone","rui/titan_loadout/nose_art/tone_nose_art_21","#TONE_NOSE_ART_21",0
+"northstar_nose_art_18","northstar","rui/titan_loadout/nose_art/northstar_nose_art_18","#NORTHSTAR_NOSE_ART_18",0
+"northstar_nose_art_19","northstar","rui/titan_loadout/nose_art/northstar_nose_art_19","#NORTHSTAR_NOSE_ART_19",0
+"northstar_nose_art_20","northstar","rui/titan_loadout/nose_art/northstar_nose_art_20","#NORTHSTAR_NOSE_ART_20",0
+"northstar_nose_art_21","northstar","rui/titan_loadout/nose_art/northstar_nose_art_21","#NORTHSTAR_NOSE_ART_21",0
+"northstar_nose_art_22","northstar","rui/titan_loadout/nose_art/northstar_nose_art_22","#NORTHSTAR_NOSE_ART_22",0
+"legion_nose_art_17","legion","rui/titan_loadout/nose_art/legion_nose_art_17","#LEGION_NOSE_ART_17",0
+"legion_nose_art_18","legion","rui/titan_loadout/nose_art/legion_nose_art_18","#LEGION_NOSE_ART_18",0
+"legion_nose_art_19","legion","rui/titan_loadout/nose_art/legion_nose_art_19","#LEGION_NOSE_ART_19",0
+"legion_nose_art_20","legion","rui/titan_loadout/nose_art/legion_nose_art_20","#LEGION_NOSE_ART_20",0
+"legion_nose_art_21","legion","rui/titan_loadout/nose_art/legion_nose_art_21","#LEGION_NOSE_ART_21",0
+"ion_nose_art_22","ion","rui/titan_loadout/nose_art/ion_nose_art_22","#ION_NOSE_ART_22",0
+"ion_nose_art_23","ion","rui/titan_loadout/nose_art/ion_nose_art_23","#ION_NOSE_ART_23",0
+"ion_nose_art_24","ion","rui/titan_loadout/nose_art/ion_nose_art_24","#ION_NOSE_ART_24",0
+"ion_nose_art_25","ion","rui/titan_loadout/nose_art/ion_nose_art_25","#ION_NOSE_ART_25",0
+"ion_nose_art_26","ion","rui/titan_loadout/nose_art/ion_nose_art_26","#ION_NOSE_ART_26",0
+"scorch_nose_art_20","scorch","rui/titan_loadout/nose_art/scorch_nose_art_20","#SCORCH_NOSE_ART_20",0
+"scorch_nose_art_21","scorch","rui/titan_loadout/nose_art/scorch_nose_art_21","#SCORCH_NOSE_ART_21",0
+"scorch_nose_art_22","scorch","rui/titan_loadout/nose_art/scorch_nose_art_22","#SCORCH_NOSE_ART_22",0
+"scorch_nose_art_23","scorch","rui/titan_loadout/nose_art/scorch_nose_art_23","#SCORCH_NOSE_ART_23",0
+"scorch_nose_art_24","scorch","rui/titan_loadout/nose_art/scorch_nose_art_24","#SCORCH_NOSE_ART_24",0
+"ronin_nose_art_21","ronin","rui/titan_loadout/nose_art/ronin_nose_art_21","#RONIN_NOSE_ART_21",0
+"ronin_nose_art_22","ronin","rui/titan_loadout/nose_art/ronin_nose_art_22","#RONIN_NOSE_ART_22",0
+"ronin_nose_art_23","ronin","rui/titan_loadout/nose_art/ronin_nose_art_23","#RONIN_NOSE_ART_23",0
+"ronin_nose_art_24","ronin","rui/titan_loadout/nose_art/ronin_nose_art_24","#RONIN_NOSE_ART_24",0
+"ronin_nose_art_25","ronin","rui/titan_loadout/nose_art/ronin_nose_art_25","#RONIN_NOSE_ART_25",0
+"tone_nose_art_22","tone","rui/titan_loadout/nose_art/tone_nose_art_22","#TONE_NOSE_ART_22",0
+"tone_nose_art_23","tone","rui/titan_loadout/nose_art/tone_nose_art_23","#TONE_NOSE_ART_23",0
+"tone_nose_art_24","tone","rui/titan_loadout/nose_art/tone_nose_art_24","#TONE_NOSE_ART_24",0
+"tone_nose_art_25","tone","rui/titan_loadout/nose_art/tone_nose_art_25","#TONE_NOSE_ART_25",0
+"tone_nose_art_26","tone","rui/titan_loadout/nose_art/tone_nose_art_26","#TONE_NOSE_ART_26",0
+"northstar_nose_art_23","northstar","rui/titan_loadout/nose_art/northstar_nose_art_23","#NORTHSTAR_NOSE_ART_23",0
+"northstar_nose_art_24","northstar","rui/titan_loadout/nose_art/northstar_nose_art_24","#NORTHSTAR_NOSE_ART_24",0
+"northstar_nose_art_25","northstar","rui/titan_loadout/nose_art/northstar_nose_art_25","#NORTHSTAR_NOSE_ART_25",0
+"northstar_nose_art_26","northstar","rui/titan_loadout/nose_art/northstar_nose_art_26","#NORTHSTAR_NOSE_ART_26",0
+"northstar_nose_art_27","northstar","rui/titan_loadout/nose_art/northstar_nose_art_27","#NORTHSTAR_NOSE_ART_27",0
+"legion_nose_art_22","legion","rui/titan_loadout/nose_art/legion_nose_art_22","#LEGION_NOSE_ART_22",0
+"legion_nose_art_23","legion","rui/titan_loadout/nose_art/legion_nose_art_23","#LEGION_NOSE_ART_23",0
+"legion_nose_art_24","legion","rui/titan_loadout/nose_art/legion_nose_art_24","#LEGION_NOSE_ART_24",0
+"legion_nose_art_25","legion","rui/titan_loadout/nose_art/legion_nose_art_25","#LEGION_NOSE_ART_25",0
+"legion_nose_art_26","legion","rui/titan_loadout/nose_art/legion_nose_art_26","#LEGION_NOSE_ART_26",0
+"vanguard_nose_art_none","vanguard","rui/menu/common/no_art","#FACTORY_ISSUE_NAME",0
+"vanguard_nose_art_01","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_02","#VANGUARD_NOSE_ART_01",0
+"vanguard_nose_art_02","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_03","#VANGUARD_NOSE_ART_02",0
+"vanguard_nose_art_03","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_04","#VANGUARD_NOSE_ART_03",0
+"vanguard_nose_art_04","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_05","#VANGUARD_NOSE_ART_04",0
+"vanguard_nose_art_05","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_06","#VANGUARD_NOSE_ART_05",0
+"vanguard_nose_art_06","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_07","#VANGUARD_NOSE_ART_06",0
+"vanguard_nose_art_07","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_08","#VANGUARD_NOSE_ART_07",0
+"vanguard_nose_art_08","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_09","#VANGUARD_NOSE_ART_08",0
+"vanguard_nose_art_09","vanguard","rui/titan_loadout/nose_art/monarch_nose_art_10","#VANGUARD_NOSE_ART_09",0
+"ion_nose_art_27","ion","rui/titan_loadout/nose_art/ion_nose_art_27","#ION_NOSE_ART_27",0
+"ion_nose_art_28","ion","rui/titan_loadout/nose_art/ion_nose_art_28","#ION_NOSE_ART_28",0
+"ion_nose_art_29","ion","rui/titan_loadout/nose_art/ion_nose_art_29","#ION_NOSE_ART_29",0
+"ion_nose_art_30","ion","rui/titan_loadout/nose_art/ion_nose_art_30","#ION_NOSE_ART_30",0
+"ion_nose_art_31","ion","rui/titan_loadout/nose_art/ion_nose_art_31","#ION_NOSE_ART_31",0
+"scorch_nose_art_25","scorch","rui/titan_loadout/nose_art/scorch_nose_art_25","#SCORCH_NOSE_ART_25",0
+"scorch_nose_art_26","scorch","rui/titan_loadout/nose_art/scorch_nose_art_26","#SCORCH_NOSE_ART_26",0
+"scorch_nose_art_27","scorch","rui/titan_loadout/nose_art/scorch_nose_art_27","#SCORCH_NOSE_ART_27",0
+"scorch_nose_art_28","scorch","rui/titan_loadout/nose_art/scorch_nose_art_28","#SCORCH_NOSE_ART_28",0
+"scorch_nose_art_29","scorch","rui/titan_loadout/nose_art/scorch_nose_art_29","#SCORCH_NOSE_ART_29",0
+"ronin_nose_art_26","ronin","rui/titan_loadout/nose_art/ronin_nose_art_26","#RONIN_NOSE_ART_26",0
+"ronin_nose_art_27","ronin","rui/titan_loadout/nose_art/ronin_nose_art_27","#RONIN_NOSE_ART_27",0
+"ronin_nose_art_28","ronin","rui/titan_loadout/nose_art/ronin_nose_art_28","#RONIN_NOSE_ART_28",0
+"ronin_nose_art_29","ronin","rui/titan_loadout/nose_art/ronin_nose_art_29","#RONIN_NOSE_ART_29",0
+"ronin_nose_art_30","ronin","rui/titan_loadout/nose_art/ronin_nose_art_30","#RONIN_NOSE_ART_30",0
+"tone_nose_art_27","tone","rui/titan_loadout/nose_art/tone_nose_art_27","#TONE_NOSE_ART_27",0
+"tone_nose_art_28","tone","rui/titan_loadout/nose_art/tone_nose_art_28","#TONE_NOSE_ART_28",0
+"tone_nose_art_29","tone","rui/titan_loadout/nose_art/tone_nose_art_29","#TONE_NOSE_ART_29",0
+"tone_nose_art_30","tone","rui/titan_loadout/nose_art/tone_nose_art_30","#TONE_NOSE_ART_30",0
+"tone_nose_art_31","tone","rui/titan_loadout/nose_art/tone_nose_art_31","#TONE_NOSE_ART_31",0
+"northstar_nose_art_28","northstar","rui/titan_loadout/nose_art/northstar_nose_art_28","#NORTHSTAR_NOSE_ART_28",0
+"northstar_nose_art_29","northstar","rui/titan_loadout/nose_art/northstar_nose_art_29","#NORTHSTAR_NOSE_ART_29",0
+"northstar_nose_art_30","northstar","rui/titan_loadout/nose_art/northstar_nose_art_30","#NORTHSTAR_NOSE_ART_30",0
+"northstar_nose_art_31","northstar","rui/titan_loadout/nose_art/northstar_nose_art_31","#NORTHSTAR_NOSE_ART_31",0
+"northstar_nose_art_32","northstar","rui/titan_loadout/nose_art/northstar_nose_art_32","#NORTHSTAR_NOSE_ART_32",0
+"legion_nose_art_27","legion","rui/titan_loadout/nose_art/legion_nose_art_27","#LEGION_NOSE_ART_27",0
+"legion_nose_art_28","legion","rui/titan_loadout/nose_art/legion_nose_art_28","#LEGION_NOSE_ART_28",0
+"legion_nose_art_29","legion","rui/titan_loadout/nose_art/legion_nose_art_29","#LEGION_NOSE_ART_29",0
+"legion_nose_art_30","legion","rui/titan_loadout/nose_art/legion_nose_art_30","#LEGION_NOSE_ART_30",0
+"legion_nose_art_31","legion","rui/titan_loadout/nose_art/legion_nose_art_31","#LEGION_NOSE_ART_31",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_os_conversations.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_os_conversations.csv new file mode 100644 index 00000000..6d7a8623 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_os_conversations.csv @@ -0,0 +1,67 @@ +conversationname,priority,debounce
+"bettyAlarm",400,0.100000
+"warning",400,3.000000
+"caution",400,3.000000
+"multiTitanEngage",400,15.000000
+"outnumbered2to1",400,15.000000
+"outnumbered3to1",400,15.000000
+"outnumbered4to1",400,15.000000
+"embark",400,3.000000
+"disembark",400,3.000000
+"guard",2000,3.000000
+"follow",2000,3.000000
+"briefCriticalDamage",400,10.000000
+"manualEjectNotice",400,0.100000
+"autoEjectNotice",400,0.100000
+"doomState",400,0.100000
+"halfDoomState",400,0.100000
+"rodeoWarning",2000,3.000000
+"allyRodeoAttach",400,3.000000
+"allyRodeoDetach",400,3.000000
+"killEnemyRodeo",400,10.000000
+"warningEnemyPilot",400,10.000000
+"warningEnemyPilotMulti",400,10.000000
+"elimTarget",400,3.000000
+"elimEnemyPilot",400,3.000000
+"ejectedEnemy",400,3.000000
+"ejectedFriendly",400,3.000000
+"assistedByFriendlyTitan",400,10.000000
+"elimEnemyTitan",400,3.000000
+"elimFriendlyTitan",400,3.000000
+"assistedByFriendlyPilot",400,3.000000
+"hostileTitanInbound",2000,3.000000
+"friendlyRodeoOnEnemyTitan",400,3.000000
+"autoEngageGrunt",400,10.000000
+"autoEngagePilot",400,10.000000
+"autoEngageTitan",400,10.000000
+"autoEngageTitans",400,10.000000
+"killEnemyRodeoGnrc",400,10.000000
+"batteryGot",400,3.000000
+"predRangeLong",400,3.000000
+"predRangeShort",400,3.000000
+"smartCoreOnline",400,3.000000
+"smartCoreActivated",400,3.000000
+"smartCoreOffline",400,3.000000
+"flamewavecoreOnline",400,3.000000
+"flamewavecoreActivated",400,3.000000
+"hack_bt_workaround",400,3.000000
+"lasercoreOnline",400,3.000000
+"lasercoreActivated",400,3.000000
+"sonarPulse",400,3.000000
+"flightCoreOnline",400,3.000000
+"flightCoreActivated",400,3.000000
+"flightCoreOffline",400,3.000000
+"SalvocoreOnline",400,3.000000
+"SalvocoreActivated",400,3.000000
+"swordCoreOnline",400,3.000000
+"swordCoreActivated",400,3.000000
+"swordCoreOffline",400,3.000000
+"burstCoreOnline",400,3.000000
+"burstCoreActivated",400,3.000000
+"UpgradecoreOnline",400,3.000000
+"UpgradecoreActivated",400,3.000000
+"upgradeTo1",400,3.000000
+"upgradeTo2",400,3.000000
+"upgradeTo3",400,3.000000
+"upgradeToFin",400,3.000000
+"upgradeShieldReplenish",400,3.000000
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_passives.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_passives.csv new file mode 100644 index 00000000..79f093c2 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_passives.csv @@ -0,0 +1,52 @@ +passive,type,name,description,longdescription,image,hidden,cost
+"pas_build_up_nuclear_core","TITAN_GENERAL_PASSIVE","#GEAR_NUCLEAR_CORE","#GEAR_NUCLEAR_CORE_DESC","#GEAR_NUCLEAR_CORE_LONGDESC","rui/titan_loadout/passive/nuke_eject",0,5
+"pas_enhanced_titan_ai","TITAN_GENERAL_PASSIVE","#GEAR_ASSAULT_CHIP","#GEAR_ASSAULT_CHIP_DESC","#GEAR_ASSAULT_CHIP_LONGDESC","rui/titan_loadout/passive/assault_chip",0,25
+"pas_auto_eject","TITAN_GENERAL_PASSIVE","#GEAR_AUTO_EJECT","#GEAR_AUTO_EJECT_DESC","#GEAR_AUTO_EJECT_LONGDESC","rui/titan_loadout/passive/auto_eject",0,25
+"pas_hyper_core","TITAN_GENERAL_PASSIVE","#GEAR_CORE_HEADSTART","#GEAR_CORE_HEADSTART_DESC","#GEAR_CORE_HEADSTART_LONGDESC","rui/titan_loadout/passive/overcore",0,5
+"pas_anti_rodeo","TITAN_GENERAL_PASSIVE","#GEAR_ANTI_RODEO","#GEAR_ANTI_RODEO_DESC","#GEAR_ANTI_RODEO_LONGDESC","rui/titan_loadout/passive/improved_anti_rodeo",0,5
+"pas_mobility_dash_capacity","TITAN_GENERAL_PASSIVE","#GEAR_DASH_CAPACITY","#GEAR_DASH_CAPACITY_DESC","#GEAR_DASH_CAPACITY_LONGDESC","rui/titan_loadout/passive/dash_plus",0,5
+"pas_warpfall","TITAN_TITANFALL_PASSIVE","#GEAR_WARPFALL","#GEAR_WARPFALL_DESC","#GEAR_WARPFALL_LONGDESC","rui/titan_loadout/passive/titanfall_kit_warpfall",0,25
+"pas_bubbleshield","TITAN_TITANFALL_PASSIVE","#GEAR_BUBBLESHIELD","#GEAR_BUBBLESHIELD_DESC","#GEAR_BUBBLESHIELD_LONGDESC","rui/titan_loadout/passive/titanfall_kit_bubbleshield",0,14
+"pas_ronin_weapon","TITAN_RONIN_PASSIVE","#GEAR_RONIN_WEAPON","#GEAR_RONIN_WEAPON_DESC","#GEAR_RONIN_WEAPON_LONGDESC","rui/titan_loadout/passive/ronin_ricochet_round",0,25
+"pas_northstar_weapon","TITAN_NORTHSTAR_PASSIVE","#GEAR_NORTHSTAR_WEAPON","#GEAR_NORTHSTAR_WEAPON_DESC","#GEAR_NORTHSTAR_WEAPON_LONGDESC","rui/titan_loadout/passive/northstar_piercing_shot",0,25
+"pas_ion_weapon","TITAN_ION_PASSIVE","#GEAR_ION_WEAPON","#GEAR_ION_WEAPON_DESC","#GEAR_ION_WEAPON_LONGDESC","rui/titan_loadout/passive/ion_entangled_energy",0,25
+"pas_tone_weapon","TITAN_TONE_PASSIVE","#GEAR_TONE_WEAPON","#GEAR_TONE_WEAPON_DESC","#GEAR_TONE_WEAPON_LONGDESC","rui/titan_loadout/passive/tone_enhanced_tracker",0,25
+"pas_scorch_weapon","TITAN_SCORCH_PASSIVE","#GEAR_SCORCH_WEAPON","#GEAR_SCORCH_WEAPON_DESC","#GEAR_SCORCH_WEAPON_LONGDESC","rui/titan_loadout/passive/scorch_wildfire_launcher",0,25
+"pas_legion_weapon","TITAN_LEGION_PASSIVE","#GEAR_LEGION_WEAPON","#GEAR_LEGION_WEAPON_DESC","#GEAR_LEGION_WEAPON_LONGDESC","rui/titan_loadout/passive/legion_enhanced_ammo",0,25
+"pas_ion_tripwire","TITAN_ION_PASSIVE","#GEAR_ION_TRIPWIRE","#GEAR_ION_TRIPWIRE_DESC","#GEAR_ION_TRIPWIRE_LONGDESC","rui/titan_loadout/passive/ion_zero_point_tripwire",0,24
+"pas_ion_vortex","TITAN_ION_PASSIVE","#GEAR_ION_VORTEX","#GEAR_ION_VORTEX_DESC","#GEAR_ION_VORTEX_LONGDESC","rui/titan_loadout/passive/ion_vortex_amp",0,24
+"pas_ion_lasercannon","TITAN_ION_PASSIVE","#GEAR_ION_LASERCANNON","#GEAR_ION_LASERCANNON_DESC","#GEAR_ION_LASERCANNON_LONGDESC","rui/titan_loadout/passive/ion_grand_canon",0,24
+"pas_tone_rockets","TITAN_TONE_PASSIVE","#GEAR_TONE_ROCKETS","#GEAR_TONE_ROCKETS_DESC","#GEAR_TONE_ROCKETS_LONGDESC","rui/titan_loadout/passive/tone_rocket_barrage",0,24
+"pas_tone_sonar","TITAN_TONE_PASSIVE","#GEAR_TONE_SONAR","#GEAR_TONE_SONAR_DESC","#GEAR_TONE_SONAR_LONGDESC","rui/titan_loadout/passive/tone_pulse_echo",0,24
+"pas_tone_wall","TITAN_TONE_PASSIVE","#GEAR_TONE_WALL","#GEAR_TONE_WALL_DESC","#GEAR_TONE_WALL_LONGDESC","rui/titan_loadout/passive/tone_reinforced_partical_wall",0,24
+"pas_ronin_arcwave","TITAN_RONIN_PASSIVE","#GEAR_RONIN_ARCWAVE","#GEAR_RONIN_ARCWAVE_DESC","#GEAR_RONIN_ARCWAVE_LONGDESC","rui/titan_loadout/passive/ronin_thunderstorm",0,24
+"pas_ronin_phase","TITAN_RONIN_PASSIVE","#GEAR_RONIN_PHASE","#GEAR_RONIN_PHASE_DESC","#GEAR_RONIN_PHASE_LONGDESC","rui/titan_loadout/passive/ronin_temporal_anomaly",0,24
+"pas_ronin_swordcore","TITAN_RONIN_PASSIVE","#GEAR_RONIN_SWORDCORE","#GEAR_RONIN_SWORDCORE_DESC","#GEAR_RONIN_SWORDCORE_LONGDESC","rui/titan_loadout/passive/ronin_highlander",0,24
+"pas_northstar_cluster","TITAN_NORTHSTAR_PASSIVE","#GEAR_NORTHSTAR_CLUSTER","#GEAR_NORTHSTAR_CLUSTER_DESC","#GEAR_NORTHSTAR_CLUSTER_LONGDESC","rui/titan_loadout/passive/northstar_enhanced_payload",0,24
+"pas_northstar_trap","TITAN_NORTHSTAR_PASSIVE","#GEAR_NORTHSTAR_TRAP","#GEAR_NORTHSTAR_TRAP_DESC","#GEAR_NORTHSTAR_TRAP_LONGDESC","rui/titan_loadout/passive/northstar_twin_trap",0,24
+"pas_northstar_flightcore","TITAN_NORTHSTAR_PASSIVE","#GEAR_NORTHSTAR_FLIGHTCORE","#GEAR_NORTHSTAR_FLIGHTCORE_DESC","#GEAR_NORTHSTAR_FLIGHTCORE_LONGDESC","rui/titan_loadout/passive/northstar_viper_thrusters",0,24
+"pas_scorch_firewall","TITAN_SCORCH_PASSIVE","#GEAR_SCORCH_FIREWALL","#GEAR_SCORCH_FIREWALL_DESC","#GEAR_SCORCH_FIREWALL_LONGDESC","rui/titan_loadout/passive/scorch_fuel",0,24
+"pas_scorch_shield","TITAN_SCORCH_PASSIVE","#GEAR_SCORCH_SHIELD","#GEAR_SCORCH_SHIELD_DESC","#GEAR_SCORCH_SHIELD_LONGDESC","rui/titan_loadout/passive/scorch_inferno_shield",0,24
+"pas_scorch_selfdmg","TITAN_SCORCH_PASSIVE","#GEAR_SCORCH_SELFDMG","#GEAR_SCORCH_SELFDMG_DESC","#GEAR_SCORCH_SELFDMG_LONGDESC","rui/titan_loadout/passive/scorch_tempered_plating",0,24
+"pas_legion_spinup","TITAN_LEGION_PASSIVE","#GEAR_LEGION_SPINUP","#GEAR_LEGION_SPINUP_DESC","#GEAR_LEGION_SPINUP_LONGDESC","rui/titan_loadout/passive/legion_lightweight_alloys",0,24
+"pas_legion_gunshield","TITAN_LEGION_PASSIVE","#GEAR_LEGION_GUNSHIELD","#GEAR_LEGION_GUNSHIELD_DESC","#GEAR_LEGION_GUNSHIELD_LONGDESC","rui/titan_loadout/passive/legion_bulwark",0,24
+"pas_legion_smartcore","TITAN_LEGION_PASSIVE","#GEAR_LEGION_SMARTCORE","#GEAR_LEGION_SMARTCORE_DESC","#GEAR_LEGION_SMARTCORE_LONGDESC","rui/titan_loadout/passive/legion_sensor_array",0,24
+"pas_ion_weapon_ads","TITAN_ION_PASSIVE","#GEAR_ION_SPLIT","#GEAR_ION_SPLIT_DESC","#GEAR_ION_SPLIT_LONGDESC","rui/titan_loadout/passive/ion_diffraction_lens",0,24
+"pas_tone_burst","TITAN_TONE_PASSIVE","#GEAR_TONE_BURST","#GEAR_TONE_BURST_DESC","#GEAR_TONE_BURST_LONGDESC","rui/titan_loadout/passive/tone_40mm_burst",0,24
+"pas_legion_chargeshot","TITAN_LEGION_PASSIVE","#GEAR_LEGION_CHARGESHOT","#GEAR_LEGION_CHARGESHOT_DESC","#GEAR_LEGION_CHARGESHOT_LONGDESC","rui/titan_loadout/passive/legion_siege_mode",0,24
+"pas_ronin_autoshift","TITAN_RONIN_PASSIVE","#GEAR_RONIN_AUTOSHIFT","#GEAR_RONIN_AUTOSHIFT_DESC","#GEAR_RONIN_AUTOSHIFT_LONGDESC","rui/titan_loadout/passive/ronin_auto_shift",0,24
+"pas_northstar_optics","TITAN_NORTHSTAR_PASSIVE","#GEAR_NORTHSTAR_OPTICS","#GEAR_NORTHSTAR_OPTICS_DESC","#GEAR_NORTHSTAR_OPTICS_LONGDESC","rui/titan_loadout/passive/northstar_threat_optics",0,24
+"pas_scorch_flamecore","TITAN_SCORCH_PASSIVE","#GEAR_SCORCH_FLAMECORE","#GEAR_SCORCH_FLAMECORE_DESC","#GEAR_SCORCH_FLAMECORE_LONGDESC","rui/titan_loadout/passive/scorch_scorched_earth",0,24
+"pas_vanguard_coremeter","TITAN_VANGUARD_PASSIVE","#GEAR_VANGUARD_COREMETER","#GEAR_VANGUARD_COREMETER_DESC","#GEAR_VANGUARD_COREMETER_LONGDESC","rui/titan_loadout/passive/vanguard_siphon",0,24
+"pas_vanguard_shield","TITAN_VANGUARD_PASSIVE","#GEAR_VANGUARD_SHIELD","#GEAR_VANGUARD_SHIELD_DESC","#GEAR_VANGUARD_SHIELD_LONGDESC","rui/titan_loadout/passive/vanguard_survivor",0,24
+"pas_vanguard_rearm","TITAN_VANGUARD_PASSIVE","#GEAR_VANGUARD_REARM","#GEAR_VANGUARD_REARM_DESC","#GEAR_VANGUARD_REARM_LONGDESC","rui/titan_loadout/passive/vanguard_rearm",0,24
+"pas_vanguard_doom","TITAN_VANGUARD_PASSIVE","#GEAR_VANGUARD_DOOM","#GEAR_VANGUARD_DOOM_DESC","#GEAR_VANGUARD_DOOM_LONGDESC","rui/titan_loadout/passive/vanguard_fittest",0,24
+"pas_vanguard_core1","TITAN_UPGRADE1_PASSIVE","#GEAR_VANGUARD_CORE1","#GEAR_VANGUARD_CORE1_DESC","#GEAR_VANGUARD_CORE1_LONGDESC","rui/titan_loadout/passive/monarch_core_arc_rounds",0,24
+"pas_vanguard_core2","TITAN_UPGRADE1_PASSIVE","#GEAR_VANGUARD_CORE2","#GEAR_VANGUARD_CORE2_DESC","#GEAR_VANGUARD_CORE2_LONGDESC","rui/titan_loadout/passive/monarch_core_missile_racks",0,24
+"pas_vanguard_core3","TITAN_UPGRADE1_PASSIVE","#GEAR_VANGUARD_CORE3","#GEAR_VANGUARD_CORE3_DESC","#GEAR_VANGUARD_CORE3_LONGDESC","rui/titan_loadout/passive/monarch_core_energy_field",0,24
+"pas_vanguard_core4","TITAN_UPGRADE2_PASSIVE","#GEAR_VANGUARD_CORE4","#GEAR_VANGUARD_CORE4_DESC","#GEAR_VANGUARD_CORE4_LONGDESC","rui/titan_loadout/passive/monarch_core_swift_rearm",0,24
+"pas_vanguard_core5","TITAN_UPGRADE2_PASSIVE","#GEAR_VANGUARD_CORE5","#GEAR_VANGUARD_CORE5_DESC","#GEAR_VANGUARD_CORE5_LONGDESC","rui/titan_loadout/passive/monarch_core_maelstrom",0,24
+"pas_vanguard_core6","TITAN_UPGRADE2_PASSIVE","#GEAR_VANGUARD_CORE6","#GEAR_VANGUARD_CORE6_DESC","#GEAR_VANGUARD_CORE6_LONGDESC","rui/titan_loadout/passive/monarch_core_energy_transfer",0,24
+"pas_vanguard_core7","TITAN_UPGRADE3_PASSIVE","#GEAR_VANGUARD_CORE7","#GEAR_VANGUARD_CORE7_DESC","#GEAR_VANGUARD_CORE7_LONGDESC","rui/titan_loadout/passive/monarch_core_multi_target",0,24
+"pas_vanguard_core8","TITAN_UPGRADE3_PASSIVE","#GEAR_VANGUARD_CORE8","#GEAR_VANGUARD_CORE8_DESC","#GEAR_VANGUARD_CORE8_LONGDESC","rui/titan_loadout/passive/monarch_core_superior_chassis",0,24
+"pas_vanguard_core9","TITAN_UPGRADE3_PASSIVE","#GEAR_VANGUARD_CORE9","#GEAR_VANGUARD_CORE9_DESC","#GEAR_VANGUARD_CORE9_LONGDESC","rui/titan_loadout/passive/monarch_core_xo16",0,24
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_primary_mods.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_primary_mods.csv new file mode 100644 index 00000000..d25cc30d --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_primary_mods.csv @@ -0,0 +1 @@ +mod,weapon,statDamage,statAccuracy,statRange,statFireRate,statClipSize,hidden
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_primary_mods_common.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_primary_mods_common.csv new file mode 100644 index 00000000..e4659a7e --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_primary_mods_common.csv @@ -0,0 +1 @@ +mod,name,description,image
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_primary_weapons.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_primary_weapons.csv new file mode 100644 index 00000000..c617d653 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_primary_weapons.csv @@ -0,0 +1,10 @@ +itemRef,hidden,defaultMod2,hidden
+"mp_titanweapon_leadwall",0,"",0
+"mp_titanweapon_meteor",0,"",0
+"mp_titanweapon_particle_accelerator",0,"",0
+"mp_titanweapon_predator_cannon",0,"",0
+"mp_titanweapon_sniper",0,"",0
+"mp_titanweapon_sticky_40mm",0,"",0
+"mp_titanweapon_xo16_shorty",1,"",0
+"mp_titanweapon_rocketeer_rocketstream",1,"",0
+"mp_titanweapon_xo16_vanguard",0,"",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_properties.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_properties.csv new file mode 100644 index 00000000..4b9369ca --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_properties.csv @@ -0,0 +1,10 @@ +setFile,primeSetFile,titanRef,primeTitanRef,titanLoadoutInSP,mp_npcUseAllowed,difficulty,coreBuildingIcon,coreReadyIcon,hintIcon,loadoutIcon,loadoutIconFD,fdRole,desc,speedDisplay,damageDisplay,healthDisplay,dashDisplay,primary,melee,ordnance,special,antirodeo,coreAbility,passive1,passive2,passive3,passive4,passive5,passive6,titanExecution,bossCharacter,hidden,menuItem,menuTitle,menuSubTitle,menuLongDesc,menuFlavorText,dialogHint,weaponImage
+"titan_buddy","","bt","",1,0,1,"rui\titan_loadout\core\titan_core_burst_core","rui\titan_loadout\core\titan_core_burst_core","rui\menu\common\bulb_hint_icon","rui/menu/postgame/vanguard_icon","rui/menu/fd_menu/fd_icon_monarch","#FD_ROLE_MONARCH","#MP_TITAN_LOADOUT_DESC_XO16",2,1,2,2,"mp_titanweapon_xo16_shorty","melee_titan_punch","mp_titanweapon_shoulder_rockets","mp_titanweapon_vortex_shield","mp_titanability_smoke","mp_titancore_amp_core","TITAN_GENERAL_PASSIVE","TITAN_GENERAL_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","","",1,"#SP_TITAN_LOADOUT_MENUITEM_XO16","#SP_TITAN_LOADOUT_TITLE_XO16","#SP_TITAN_LOADOUT_SUBTITLE_XO16","#SP_TITAN_LOADOUT_DESC_XO16","#SP_TITAN_LOADOUT_FLAVOR_XO16","diag_sp_extra_GB101_47_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_x016_shorty"
+"titan_atlas_tracker","titan_atlas_tone_prime","tone","tone_prime",1,1,2,"rui\titan_loadout\core\titan_core_salvo","rui\titan_loadout\core\titan_core_salvo","rui\menu\common\bulb_hint_icon","rui/menu/postgame/tone_icon","rui/menu/fd_menu/fd_icon_tone","#FD_ROLE_TONE","#MP_TITAN_LOADOUT_DESC_TONE",2,2,2,1,"mp_titanweapon_sticky_40mm","melee_titan_punch_tone","mp_titanweapon_tracker_rockets","mp_titanability_particle_wall","mp_titanability_sonar_pulse","mp_titancore_salvo_core","TITAN_GENERAL_PASSIVE","TITAN_TONE_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_TONE_EXECUTION","Richter",0,"#SP_TITAN_LOADOUT_MENUITEM_TONE","#SP_TITAN_LOADOUT_TITLE_TONE","#SP_TITAN_LOADOUT_SUBTITLE_TONE","#SP_TITAN_LOADOUT_DESC_TONE","#SP_TITAN_LOADOUT_FLAVOR_TONE","diag_sp_extra_GB101_37_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_40mm"
+"titan_ogre_meteor","titan_ogre_scorch_prime","scorch","scorch_prime",1,1,3,"rui\titan_loadout\core\titan_core_flame_wave","rui\titan_loadout\core\titan_core_flame_wave","rui\menu\common\bulb_hint_icon","rui/menu/postgame/scorch_icon","rui/menu/fd_menu/fd_icon_scorch","#FD_ROLE_SCORCH","#MP_TITAN_LOADOUT_DESC_SCORCH",1,3,3,0,"mp_titanweapon_meteor","melee_titan_punch_scorch","mp_titanweapon_flame_wall","mp_titanweapon_heat_shield","mp_titanability_slow_trap","mp_titancore_flame_wave","TITAN_GENERAL_PASSIVE","TITAN_SCORCH_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_SCORCH_EXECUTION","Kane",0,"#SP_TITAN_LOADOUT_MENUITEM_SCORCH","#SP_TITAN_LOADOUT_TITLE_SCORCH","#SP_TITAN_LOADOUT_SUBTITLE_SCORCH","#SP_TITAN_LOADOUT_DESC_SCORCH","#SP_TITAN_LOADOUT_FLAVOR_SCORCH","diag_sp_extra_GB101_33_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_meteor"
+"titan_stryder_rocketeer","","brute4","",1,0,1,"rui\titan_loadout\core\titan_core_flight","rui\titan_loadout\core\titan_core_flight","rui\menu\common\bulb_hint_icon","rui/menu/postgame/northstar_icon","rui/menu/fd_menu/fd_icon_northstar","#FD_ROLE_NORTHSTAR","#MP_TITAN_LOADOUT_DESC_BRUTE",3,2,1,2,"mp_titanweapon_rocketeer_rocketstream","melee_titan_punch","mp_titanweapon_shoulder_rockets","mp_titanweapon_vortex_shield","mp_titanability_hover","mp_titancore_flight_core","TITAN_GENERAL_PASSIVE","TITAN_GENERAL_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","","",0,"#SP_TITAN_LOADOUT_MENUITEM_BRUTE","#SP_TITAN_LOADOUT_TITLE_BRUTE","#SP_TITAN_LOADOUT_SUBTITLE_BRUTE","#SP_TITAN_LOADOUT_DESC_BRUTE","#SP_TITAN_LOADOUT_FLAVOR_BRUTE","diag_sp_extra_GB101_47_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_rocketeer"
+"titan_atlas_stickybomb","titan_atlas_ion_prime","ion","ion_prime",1,1,1,"rui\titan_loadout\core\titan_core_laser","rui\titan_loadout\core\titan_core_laser","rui\menu\common\bulb_hint_icon","rui/menu/postgame/ion_icon","rui/menu/fd_menu/fd_icon_ion","#FD_ROLE_ION","#MP_TITAN_LOADOUT_DESC_ION",2,1,2,1,"mp_titanweapon_particle_accelerator","melee_titan_punch_ion","mp_titanweapon_laser_lite","mp_titanweapon_vortex_shield_ion","mp_titanability_laser_trip","mp_titancore_laser_cannon","TITAN_GENERAL_PASSIVE","TITAN_ION_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_ION_EXECUTION","Slone",0,"#SP_TITAN_LOADOUT_MENUITEM_ION","#SP_TITAN_LOADOUT_TITLE_ION","#SP_TITAN_LOADOUT_SUBTITLE_ION","#SP_TITAN_LOADOUT_DESC_ION","#SP_TITAN_LOADOUT_FLAVOR_ION","diag_sp_extra_GB101_34_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_particle_accelerator"
+"titan_stryder_leadwall","titan_stryder_ronin_prime","ronin","ronin_prime",1,1,3,"rui\titan_loadout\core\titan_core_sword","rui\titan_loadout\core\titan_core_sword","rui\menu\common\bulb_hint_icon","rui/menu/postgame/ronin_icon","rui/menu/fd_menu/fd_icon_ronin","#FD_ROLE_RONIN","#MP_TITAN_LOADOUT_DESC_RONIN",3,2,1,2,"mp_titanweapon_leadwall","melee_titan_sword","mp_titanweapon_arc_wave","mp_titanability_basic_block","mp_titanability_phase_dash","mp_titancore_shift_core","TITAN_GENERAL_PASSIVE","TITAN_RONIN_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_RONIN_EXECUTION","Ash",0,"#SP_TITAN_LOADOUT_MENUITEM_RONIN","#SP_TITAN_LOADOUT_TITLE_RONIN","#SP_TITAN_LOADOUT_SUBTITLE_RONIN","#SP_TITAN_LOADOUT_DESC_RONIN","#SP_TITAN_LOADOUT_FLAVOR_RONIN","diag_sp_extra_GB101_35_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_leadwall"
+"titan_stryder_sniper","titan_stryder_northstar_prime","northstar","northstar_prime",1,1,2,"rui\titan_loadout\core\titan_core_flight","rui\titan_loadout\core\titan_core_flight","rui\menu\common\bulb_hint_icon","rui/menu/postgame/northstar_icon","rui/menu/fd_menu/fd_icon_northstar","#FD_ROLE_NORTHSTAR","#MP_TITAN_LOADOUT_DESC_NORTHSTAR",3,3,1,2,"mp_titanweapon_sniper","melee_titan_punch_northstar","mp_titanweapon_dumbfire_rockets","mp_titanability_tether_trap","mp_titanability_hover","mp_titancore_flight_core","TITAN_GENERAL_PASSIVE","TITAN_NORTHSTAR_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_NORTHSTAR_EXECUTION","Viper",0,"#SP_TITAN_LOADOUT_MENUITEM_NORTHSTAR","#SP_TITAN_LOADOUT_TITLE_NORTHSTAR","#SP_TITAN_LOADOUT_SUBTITLE_NORTHSTAR","#SP_TITAN_LOADOUT_DESC_NORTHSTAR","#SP_TITAN_LOADOUT_FLAVOR_NORTHSTAR","diag_sp_extra_GB101_36_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_sniper"
+"titan_ogre_minigun","titan_ogre_legion_prime","legion","legion_prime",1,1,2,"rui\titan_loadout\core\titan_core_smart","rui\titan_loadout\core\titan_core_smart","rui\menu\common\bulb_hint_icon","rui/menu/postgame/legion_icon","rui/menu/fd_menu/fd_icon_legion","#FD_ROLE_LEGION","#MP_TITAN_LOADOUT_DESC_LEGION",1,3,3,0,"mp_titanweapon_predator_cannon","melee_titan_punch_legion","mp_titanability_power_shot","mp_titanability_gun_shield","mp_titanability_ammo_swap","mp_titancore_siege_mode","TITAN_GENERAL_PASSIVE","TITAN_LEGION_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_LEGION_EXECUTION","Blisk",0,"#SP_TITAN_LOADOUT_MENUITEM_LEGION","#SP_TITAN_LOADOUT_TITLE_LEGION","#SP_TITAN_LOADOUT_SUBTITLE_LEGION","#SP_TITAN_LOADOUT_DESC_LEGION","#SP_TITAN_LOADOUT_FLAVOR_LEGION","diag_sp_extra_GB101_32_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_predator"
+"titan_atlas_vanguard","","vanguard","vanguard_prime",0,1,3,"rui\titan_loadout\core\titan_core_smart","rui\titan_loadout\core\titan_core_smart","rui\menu\common\bulb_hint_icon","rui/menu/postgame/vanguard_icon","rui/menu/fd_menu/fd_icon_monarch","#FD_ROLE_MONARCH","#MP_TITAN_LOADOUT_DESC_VANGUARD",2,2,2,1,"mp_titanweapon_xo16_vanguard","melee_titan_punch_vanguard","mp_titanweapon_salvo_rockets","mp_titanweapon_stun_laser","mp_titanability_rearm","mp_titancore_upgrade","TITAN_GENERAL_PASSIVE","TITAN_VANGUARD_PASSIVE","TITAN_TITANFALL_PASSIVE","TITAN_UPGRADE1_PASSIVE","TITAN_UPGRADE2_PASSIVE","TITAN_UPGRADE3_PASSIVE","TITAN_VANGUARD_EXECUTION","Richter",0,"#SP_TITAN_LOADOUT_MENUITEM_TONE","#SP_TITAN_LOADOUT_TITLE_TONE","#SP_TITAN_LOADOUT_SUBTITLE_TONE","#SP_TITAN_LOADOUT_DESC_TONE","#SP_TITAN_LOADOUT_FLAVOR_TONE","diag_sp_extra_GB101_37_01_mcor_bt","rui\titan_loadout\loadout_select\ls_wep_ttn_40mm"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_skins.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_skins.csv new file mode 100644 index 00000000..da8b3172 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_skins.csv @@ -0,0 +1,56 @@ +ref,titanRef,image,name,cost,skinIndex
+"ion_skin_01","ion","rui/titan_loadout/skins/ion_skin_01","#ION_SKIN_01",0,1
+"ion_skin_02","ion","rui/titan_loadout/skins/ion_skin_02","#ION_SKIN_02",0,3
+"ion_skin_03","ion","rui/titan_loadout/skins/ion_skin_03","#ION_SKIN_03",500,4
+"ion_skin_04","ion","rui/titan_loadout/skins/ion_skin_04","#ION_SKIN_04",0,5
+"ion_skin_06","ion","rui/titan_loadout/skins/ion_skin_06","#ION_SKIN_06",0,6
+"scorch_skin_01","scorch","rui/titan_loadout/skins/scorch_skin_01","#SCORCH_SKIN_01",0,1
+"scorch_skin_02","scorch","rui/titan_loadout/skins/scorch_skin_02","#SCORCH_SKIN_02",0,3
+"scorch_skin_03","scorch","rui/titan_loadout/skins/scorch_skin_03","#SCORCH_SKIN_03",0,4
+"scorch_skin_04","scorch","rui/titan_loadout/skins/scorch_skin_04","#SCORCH_SKIN_04",0,5
+"ronin_skin_01","ronin","rui/titan_loadout/skins/ronin_skin_01","#RONIN_SKIN_01",0,1
+"ronin_skin_02","ronin","rui/titan_loadout/skins/ronin_skin_02","#RONIN_SKIN_02",0,3
+"ronin_skin_03","ronin","rui/titan_loadout/skins/ronin_skin_03","#RONIN_SKIN_03",0,4
+"ronin_skin_04","ronin","rui/titan_loadout/skins/ronin_skin_04","#RONIN_SKIN_04",0,5
+"tone_skin_01","tone","rui/titan_loadout/skins/tone_skin_01","#TONE_SKIN_01",0,1
+"tone_skin_02","tone","rui/titan_loadout/skins/tone_skin_02","#TONE_SKIN_02",0,3
+"tone_skin_03","tone","rui/titan_loadout/skins/tone_skin_03","#TONE_SKIN_03",0,4
+"tone_skin_04","tone","rui/titan_loadout/skins/tone_skin_04","#TONE_SKIN_04",0,5
+"northstar_skin_01","northstar","rui/titan_loadout/skins/northstar_skin_01","#NORTHSTAR_SKIN_01",0,1
+"northstar_skin_02","northstar","rui/titan_loadout/skins/northstar_skin_02","#NORTHSTAR_SKIN_02",0,3
+"northstar_skin_03","northstar","rui/titan_loadout/skins/northstar_skin_03","#NORTHSTAR_SKIN_03",0,4
+"northstar_skin_04","northstar","rui/titan_loadout/skins/northstar_skin_04","#NORTHSTAR_SKIN_04",0,5
+"legion_skin_01","legion","rui/titan_loadout/skins/legion_skin_01","#LEGION_SKIN_01",0,1
+"legion_skin_02","legion","rui/titan_loadout/skins/legion_skin_02","#LEGION_SKIN_02",0,3
+"legion_skin_03","legion","rui/titan_loadout/skins/legion_skin_03","#LEGION_SKIN_03",0,4
+"legion_skin_04","legion","rui/titan_loadout/skins/legion_skin_04","#LEGION_SKIN_04",0,5
+"ion_skin_10","ion","rui/titan_loadout/skins/ion_skin_10","#ION_SKIN_10",0,7
+"tone_skin_06","tone","rui/titan_loadout/skins/tone_skin_06","#TONE_SKIN_06",0,6
+"scorch_skin_07","scorch","rui/titan_loadout/skins/scorch_skin_07","#SCORCH_SKIN_07",0,6
+"ronin_skin_10","ronin","rui/titan_loadout/skins/ronin_skin_10","#RONIN_SKIN_10",0,6
+"northstar_skin_10","northstar","rui/titan_loadout/skins/northstar_skin_10","#NORTHSTAR_SKIN_10",0,6
+"legion_skin_07","legion","rui/titan_loadout/skins/legion_skin_07","#LEGION_SKIN_07",0,6
+"ion_skin_11","ion","rui/titan_loadout/skins/ion_skin_11","#ION_SKIN_11",0,8
+"tone_skin_07","tone","rui/titan_loadout/skins/tone_skin_07","#TONE_SKIN_07",0,7
+"scorch_skin_08","scorch","rui/titan_loadout/skins/scorch_skin_08","#SCORCH_SKIN_08",0,7
+"ronin_skin_11","ronin","rui/titan_loadout/skins/ronin_skin_11","#RONIN_SKIN_11",0,7
+"northstar_skin_11","northstar","rui/titan_loadout/skins/northstar_skin_11","#NORTHSTAR_SKIN_11",0,7
+"legion_skin_08","legion","rui/titan_loadout/skins/legion_skin_08","#LEGION_SKIN_08",0,7
+"vanguard_skin_01","vanguard","rui/titan_loadout/skins/legion_skin_01","#LEGION_SKIN_01",0,1
+"vanguard_skin_02","vanguard","rui/titan_loadout/skins/legion_skin_02","#LEGION_SKIN_02",0,3
+"vanguard_skin_03","vanguard","rui/titan_loadout/skins/legion_skin_03","#LEGION_SKIN_03",0,4
+"vanguard_skin_07","vanguard","rui/titan_loadout/skins/legion_skin_07","#LEGION_SKIN_07",0,6
+"vanguard_skin_08","vanguard","rui/titan_loadout/skins/legion_skin_08","#LEGION_SKIN_08",0,7
+"northstar_skin_06","northstar","rui/titan_loadout/skins/northstar_skin_06","#NORTHSTAR_SKIN_06",0,8
+"ronin_skin_07","ronin","rui/titan_loadout/skins/ronin_skin_07","#RONIN_SKIN_07",0,8
+"scorch_skin_06","scorch","rui/titan_loadout/skins/scorch_skin_06","#SCORCH_SKIN_06",0,8
+"ion_skin_07","ion","rui/titan_loadout/skins/ion_skin_07","#ION_SKIN_07",0,9
+"legion_skin_09","legion","rui/titan_loadout/skins/legion_skin_09","#LEGION_SKIN_09",0,8
+"tone_skin_08","tone","rui/titan_loadout/skins/tone_skin_08","#TONE_SKIN_08",0,8
+"northstar_skin_fd","northstar","rui/titan_loadout/skins/northstar_skin_fd","#NORTHSTAR_SKIN_FD",0,9
+"ronin_skin_fd","ronin","rui/titan_loadout/skins/ronin_skin_fd","#RONIN_SKIN_FD",0,9
+"scorch_skin_fd","scorch","rui/titan_loadout/skins/scorch_skin_fd","#SCORCH_SKIN_FD",0,9
+"ion_skin_fd","ion","rui/titan_loadout/skins/ion_skin_fd","#ION_SKIN_FD",0,10
+"legion_skin_fd","legion","rui/titan_loadout/skins/legion_skin_fd","#LEGION_SKIN_FD",0,9
+"tone_skin_fd","tone","rui/titan_loadout/skins/tone_skin_fd","#TONE_SKIN_FD",0,9
+"monarch_skin_fd","vanguard","rui/titan_loadout/skins/monarch_skin_fd","#MONARCH_SKIN_FD",0,3
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titan_voices.csv b/Northstar.CustomServers/mod/scripts/datatable/titan_voices.csv new file mode 100644 index 00000000..8a762f9b --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titan_voices.csv @@ -0,0 +1,9 @@ +weapon,name,description,image,hidden
+"titanos_bt","#TITAN_OS_BT_NAME","#TITAN_OS_BT_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_legion","#TITAN_OS_LEGION_NAME","#TITAN_OS_LEGION_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_scorch","#TITAN_OS_SCORCH_NAME","#TITAN_OS_SCORCH_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_ronin","#TITAN_OS_RONIN_NAME","#TITAN_OS_RONIN_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_northstar","#TITAN_OS_NORTHSTAR_NAME","#TITAN_NORTHSTAR_BETTY_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_ion","#TITAN_OS_ION_NAME","#TITAN_OS_ION_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_tone","#TITAN_OS_TONE_NAME","#TITAN_OS_TONE_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
+"titanos_vanguard","#TITAN_OS_VANGUARD_NAME","#TITAN_OS_VANGUARD_LONGDESC","material/ui/menu/voice_personality_icons/betty_voice_icon_gen.rpak",0
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/titans_mp.csv b/Northstar.CustomServers/mod/scripts/datatable/titans_mp.csv new file mode 100644 index 00000000..a0873690 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/titans_mp.csv @@ -0,0 +1,8 @@ +titanRef,cost,coreIcon,image
+"ion",5,"rui/titan_loadout/core/titan_core_laser","rui/menu/postgame/ion_icon"
+"scorch",5,"rui/titan_loadout/core/titan_core_flame_wave","rui/menu/postgame/scorch_icon"
+"northstar",5,"rui/titan_loadout/core/titan_core_flight","rui/menu/postgame/northstar_icon"
+"ronin",10,"rui/titan_loadout/core/titan_core_sword","rui/menu/postgame/ronin_icon"
+"tone",15,"rui/titan_loadout/core/titan_core_salvo","rui/menu/postgame/tone_icon"
+"legion",20,"rui/titan_loadout/core/titan_core_smart","rui/menu/postgame/legion_icon"
+"vanguard",200,"rui/titan_loadout/core/titan_core_vanguard","rui/menu/postgame/vanguard_icon"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/unlocks_faction_level.csv b/Northstar.CustomServers/mod/scripts/datatable/unlocks_faction_level.csv new file mode 100644 index 00000000..6f9fa4c1 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/unlocks_faction_level.csv @@ -0,0 +1,82 @@ +factionLevel,faction_apex,faction_64,faction_vinson,faction_marauder,faction_aces,faction_ares,faction_marvin
+0,"faction_apex","faction_64","faction_vinson","faction_marauder","faction_aces","faction_ares","faction_marvin"
+1,"","","","","","",""
+2,"gc_icon_dollarsign,random","gc_icon_fox,random ","gc_icon_gear,random ","gc_icon_prowler,random ","gc_icon_ace,random","gc_icon_radar,random","gc_icon_mrvn,random"
+3,"random,callsign_06_col","random,callsign_96_col","random,callsign_05_col","random,callsign_46_col","random,callsign_01_col","random,callsign_41_col","random,callsign_163_col"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random,callsign_06_col_fire","random,callsign_96_col_fire","random,callsign_05_col_fire","random,callsign_46_col_fire","random,callsign_01_col_fire","random,callsign_41_col_fire","random,callsign_163_col_fire"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random,callsign_06_col_gold","random,callsign_96_col_gold","random,callsign_05_col_gold","random,callsign_46_col_gold","random,callsign_01_col_gold","random,callsign_41_col_gold","random,callsign_163_col_gold"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random,callsign_163_col_prism"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random,callsign_164_col"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random,callsign_164_col_fire"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random,callsign_164_col_gold"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random,callsign_164_col_prism"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
+1,"random","random","random","random","random","random","random"
+2,"random","random","random","random","random","random","random"
+3,"random","random","random","random","random","random","random"
+4,"random","random","random","random","random","random","random"
+5,"random","random","random","random","random","random","random"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/unlocks_fd_titan_level.csv b/Northstar.CustomServers/mod/scripts/datatable/unlocks_fd_titan_level.csv new file mode 100644 index 00000000..957af6d6 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/unlocks_fd_titan_level.csv @@ -0,0 +1,26 @@ +titanLevel,ion,scorch,northstar,ronin,tone,legion,vanguard,end
+"","ion","scorch","northstar","ronin","tone","legion","vanguard","END"
+"1","","","","","","","",""
+"2","fd_upgrade_ion_weapon_tier_2","fd_upgrade_scorch_weapon_tier_1","fd_upgrade_northstar_utility_tier_1","fd_upgrade_ronin_weapon_tier_1","fd_upgrade_tone_weapon_tier_1","fd_upgrade_legion_weapon_tier_1","fd_upgrade_vanguard_utility_tier_1",""
+"3","random","random","random","random","random","random","random",""
+"4","random","random","random","random","random","random","random",""
+"5","fd_upgrade_ion_defense_tier_1","fd_upgrade_scorch_defense_tier_1","fd_upgrade_northstar_defense_tier_1","fd_upgrade_ronin_defense_tier_1","fd_upgrade_tone_defense_tier_1","fd_upgrade_legion_defense_tier_1","fd_upgrade_vanguard_defense_tier_1",""
+"6","random","random","random","random","random","random","random",""
+"7","random","random","random","random","random","random","random",""
+"8","fd_upgrade_ion_utility_tier_2","fd_upgrade_scorch_utility_tier_1","fd_upgrade_northstar_weapon_tier_1","fd_upgrade_ronin_utility_tier_1","fd_upgrade_tone_utility_tier_2","fd_upgrade_legion_utility_tier_1","fd_upgrade_vanguard_weapon_tier_1",""
+"9","random","random","random","random","random","random","random",""
+"10","random","random","random","random","random","random","random",""
+"11","fd_upgrade_ion_weapon_tier_1","fd_upgrade_scorch_utility_tier_2","fd_upgrade_northstar_utility_tier_2","fd_upgrade_ronin_weapon_tier_2","fd_upgrade_tone_weapon_tier_2","fd_upgrade_legion_weapon_tier_2","fd_upgrade_vanguard_utility_tier_2",""
+"12","random","random","random","random","random","random","random",""
+"13","random","random","random","random","random","random","random",""
+"14","fd_upgrade_ion_defense_tier_2","fd_upgrade_scorch_defense_tier_2","fd_upgrade_northstar_defense_tier_2","fd_upgrade_ronin_defense_tier_2","fd_upgrade_tone_defense_tier_2","fd_upgrade_legion_defense_tier_2","fd_upgrade_vanguard_defense_tier_2",""
+"15","random","random","random","random","random","random","random",""
+"16","random","random","random","random","random","random","random",""
+"17","fd_upgrade_ion_utility_tier_1","fd_upgrade_scorch_weapon_tier_2","fd_upgrade_northstar_weapon_tier_2","fd_upgrade_ronin_utility_tier_2","fd_upgrade_tone_utility_tier_1","fd_upgrade_legion_utility_tier_2","fd_upgrade_vanguard_weapon_tier_2",""
+"18","random","random","random","random","random","random","random",""
+"19","random","random","random","random","random","random","random",""
+"20","fd_upgrade_ion_ultimate","fd_upgrade_scorch_ultimate","fd_upgrade_northstar_ultimate","fd_upgrade_ronin_ultimate","fd_upgrade_tone_ultimate","fd_upgrade_legion_ultimate","fd_upgrade_vanguard_ultimate",""
+"21","random","random","random","random","random","random","random",""
+"22","random","random","random","random","random","random","random",""
+"23","random","random","random","random","random","random","random",""
+"24","callsign_24_col_prism","callsign_47_col_prism","callsign_36_col_prism","callsign_45_col_prism","callsign_68_col_prism","callsign_26_col_prism","callsign_165_col_prism",""
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/unlocks_player_level.csv b/Northstar.CustomServers/mod/scripts/datatable/unlocks_player_level.csv new file mode 100644 index 00000000..693bcc15 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/unlocks_player_level.csv @@ -0,0 +1,996 @@ +playerLevel,pilotWeapons,pilotOffhands,pilotKits,pilotTactical,titanChassis,burnCard,feature,callSign,callsignIcon,pilotExecutions,pilotCamo,factions,random
+1,"mp_weapon_rspn101_og, mp_weapon_rspn101,mp_weapon_car,mp_weapon_lmg,mp_weapon_shotgun,mp_weapon_sniper,mp_weapon_smr,mp_weapon_semipistol,mp_weapon_autopistol,mp_weapon_defender,mp_weapon_mgl,mp_weapon_wingman_n","mp_weapon_frag_grenade,mp_weapon_grenade_emp,mp_weapon_thermite_grenade","pas_enemy_death_icons,pas_wallhang,pas_fast_health_regen,pas_power_cell","mp_ability_grapple,mp_ability_cloak,mp_weapon_grenade_sonar,mp_ability_shifter_super,grapple,geist,medium","ion,scorch,northstar","burnmeter_amped_weapons","cp,ctf,lts,ffa,fw,ps,tdm,at,aitdm,lf,communities,happy_hour, pilot_loadout_1, pilot_loadout_2, pilot_loadout_3, pilot_loadout_4, pilot_loadout_5, pilot_loadout_6,hunted,mfd,fd_easy,fd_normal","callsign_16_col","gc_icon_titanfall","execution_neck_snap","pilot_camo_skin00","faction_marauder",""
+2,"mp_weapon_lstar","","","","","","","","","","","",""
+3,"","","","mp_ability_heal,nomad","","","","","","","","",""
+4,"","","","","","","coliseum","","","","","",""
+5,"mp_weapon_epg","","","","","","","callsign_53_col","","","","",""
+6,"","","","","","burnmeter_ticks","","","","","","",""
+7,"","","","","ronin","","","","","","","",""
+8,"mp_weapon_alternator_smg","","","","","","","","","","","",""
+9,"","mp_weapon_grenade_gravity","","","","","","","","","","",""
+10,"mp_weapon_shotgun_pistol","","","","","","","","","","pilot_camo_skin01","",""
+11,"","","","","tone","","","","","","","",""
+12,"","","","","","","","","","","","faction_apex",""
+13,"mp_weapon_hemlok","","","","","","","","","","","",""
+14,"","","","mp_weapon_deployable_cover,heavy","","","","","","","","",""
+15,"","","","","legion","","","callsign_67_col","","","","",""
+16,"mp_weapon_doubletake","","","","","","","","","","","",""
+17,"","","","","","burnmeter_ap_turret_weapon","","","","","","",""
+18,"","","pas_ordnance_pack","","","","","","","","","",""
+19,"mp_weapon_mastiff","","","","","","","","","","","",""
+20,"","","","","vanguard","","pilot_loadout_7","","","","pilot_camo_skin03","faction_vinson",""
+21,"mp_weapon_arc_launcher","","","","","","","","","","","",""
+22,"","mp_weapon_grenade_electric_smoke","","","","","","","","","","",""
+23,"","","","","","burnmeter_maphack","","","","","","",""
+24,"mp_weapon_esaw","","","","","","","","","","","",""
+25,"","","pas_ads_hover","","","","","callsign_100_col","","","","",""
+26,"","","","mp_ability_shifter,light","","","","","","","","",""
+27,"mp_weapon_hemlok_smg","","","","","","","","","","","",""
+28,"","","","","","burnmeter_emergency_battery","","","","","","",""
+29,"","","pas_fast_embark","","","","","","","","","",""
+30,"mp_weapon_softball","","","","","","pilot_loadout_8","","","","pilot_camo_skin02","",""
+31,"","","","","","burnmeter_radar_jammer","","","","","","",""
+32,"mp_weapon_wingman","","","","","","","","","","","",""
+33,"","","","","","","","","","","","faction_aces",""
+34,"","","","","","burnmeter_at_turret_weapon","","","","","","",""
+35,"mp_weapon_g2","","","","","","","callsign_09_col","","","","",""
+36,"","","","mp_ability_holopilot,stalker","","","","","","","","",""
+37,"","mp_weapon_satchel","","","","","","","","","","",""
+38,"mp_weapon_dmr","","","","","","","","","","","",""
+39,"","","","","","","","","","","","faction_64",""
+40,"","","pas_stealth_movement","","","","pilot_loadout_9","","","","pilot_camo_skin97","",""
+41,"mp_weapon_r97","","","","","","","","","","","",""
+42,"","","","","","burnmeter_smart_pistol","","","","","","",""
+43,"mp_weapon_rocket_launcher","","","","","","","","","","","",""
+44,"","","","","","burnmeter_phase_rewind","","","","","","",""
+45,"mp_weapon_pulse_lmg","","","","","","","callsign_70_col","","","","",""
+46,"","","","","","burnmeter_hard_cover","","","","","","",""
+47,"mp_weapon_vinson","","","","","","","","","","","",""
+48,"","","","","","burnmeter_holopilot_nova","","","","","","",""
+49,"","","pas_at_hunter","","","","","","","","","faction_ares",""
+50,"","","","","","burnmeter_random_foil","pilot_loadout_10","","gc_icon_gen0","","pilot_camo_skin24","faction_marvin",""
+1,"","","","","","","","callsign_35_col","gc_icon_gen1","","pilot_camo_skin16","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","callsign_53_col_fire","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","callsign_67_col_fire","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","callsign_100_col_fire","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","pilot_camo_skin25","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","callsign_09_col_fire","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","callsign_70_col_fire","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_07_col","gc_icon_gen2","","pilot_camo_skin14","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","callsign_53_col_gold","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","callsign_67_col_gold","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","callsign_100_col_gold","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","pilot_camo_skin26","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","callsign_09_col_gold","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","callsign_70_col_gold","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_34_col","gc_icon_gen3","","pilot_camo_skin83","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","pilot_camo_skin27","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_39_col","gc_icon_gen4","","pilot_camo_skin31","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","pilot_camo_skin19","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_16_col_fire","gc_icon_gen5","","pilot_camo_skin82","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_35_col_fire","gc_icon_sgt_major,gc_icon_gen6","","pilot_camo_skin15","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_07_col_fire","gc_icon_gen7","","pilot_camo_skin17","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_34_col_fire","gc_icon_gen8","","pilot_camo_skin81","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","callsign_39_col_fire","gc_icon_gen9","","pilot_camo_skin18","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","callsign_16_col_gold,callsign_35_col_gold,callsign_07_col_gold,callsign_34_col_gold,callsign_39_col_gold","","","pilot_camo_skin30","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
+46,"","","","","","","","","","","","",""
+47,"","","","","","","","","","","","",""
+48,"","","","","","","","","","","","",""
+49,"","","","","","","","","","","","",""
+50,"","","","","","","","","","","","",""
+1,"","","","","","","","","","","","",""
+2,"","","","","","","","","","","","",""
+3,"","","","","","","","","","","","",""
+4,"","","","","","","","","","","","",""
+5,"","","","","","","","","","","","","random"
+6,"","","","","","","","","","","","",""
+7,"","","","","","","","","","","","",""
+8,"","","","","","","","","","","","",""
+9,"","","","","","","","","","","","",""
+10,"","","","","","","","","","","","",""
+11,"","","","","","","","","","","","",""
+12,"","","","","","","","","","","","",""
+13,"","","","","","","","","","","","",""
+14,"","","","","","","","","","","","",""
+15,"","","","","","","","","","","","","random"
+16,"","","","","","","","","","","","",""
+17,"","","","","","","","","","","","",""
+18,"","","","","","","","","","","","",""
+19,"","","","","","","","","","","","",""
+20,"","","","","","","","","","","","",""
+21,"","","","","","","","","","","","",""
+22,"","","","","","","","","","","","",""
+23,"","","","","","","","","","","","",""
+24,"","","","","","","","","","","","",""
+25,"","","","","","","","","","","","","random"
+26,"","","","","","","","","","","","",""
+27,"","","","","","","","","","","","",""
+28,"","","","","","","","","","","","",""
+29,"","","","","","","","","","","","",""
+30,"","","","","","","","","","","","",""
+31,"","","","","","","","","","","","",""
+32,"","","","","","","","","","","","",""
+33,"","","","","","","","","","","","",""
+34,"","","","","","","","","","","","",""
+35,"","","","","","","","","","","","","random"
+36,"","","","","","","","","","","","",""
+37,"","","","","","","","","","","","",""
+38,"","","","","","","","","","","","",""
+39,"","","","","","","","","","","","",""
+40,"","","","","","","","","","","","",""
+41,"","","","","","","","","","","","",""
+42,"","","","","","","","","","","","",""
+43,"","","","","","","","","","","","",""
+44,"","","","","","","","","","","","",""
+45,"","","","","","","","","","","","","random"
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/unlocks_random.csv b/Northstar.CustomServers/mod/scripts/datatable/unlocks_random.csv new file mode 100644 index 00000000..b35f17af --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/unlocks_random.csv @@ -0,0 +1,359 @@ +ref,weight
+"callsign_02_col",15.000000
+"callsign_08_col",15.000000
+"callsign_10_col",15.000000
+"callsign_12_col",15.000000
+"callsign_17_col",15.000000
+"callsign_20_col",15.000000
+"callsign_25_col",15.000000
+"callsign_28_col",15.000000
+"callsign_32_col",15.000000
+"callsign_43_col",15.000000
+"callsign_44_col",15.000000
+"callsign_49_col",15.000000
+"callsign_50_col",15.000000
+"callsign_52_col",15.000000
+"callsign_54_col",15.000000
+"callsign_56_col",15.000000
+"callsign_58_col",15.000000
+"callsign_60_col",15.000000
+"callsign_61_col",15.000000
+"callsign_62_col",15.000000
+"callsign_63_col",15.000000
+"callsign_64_col",15.000000
+"callsign_71_col",15.000000
+"callsign_72_col",15.000000
+"callsign_73_col",15.000000
+"callsign_74_col",15.000000
+"callsign_77_col",15.000000
+"callsign_80_col",15.000000
+"callsign_81_col",15.000000
+"callsign_82_col",15.000000
+"callsign_83_col",15.000000
+"callsign_84_col",15.000000
+"callsign_85_col",15.000000
+"callsign_86_col",15.000000
+"callsign_87_col",15.000000
+"callsign_88_col",15.000000
+"callsign_89_col",15.000000
+"callsign_90_col",15.000000
+"callsign_91_col",15.000000
+"callsign_93_col",15.000000
+"callsign_95_col",15.000000
+"callsign_98_col",15.000000
+"callsign_101_col",15.000000
+"callsign_102_col",15.000000
+"callsign_02_col_prism",3.000000
+"callsign_08_col_prism",3.000000
+"callsign_10_col_prism",3.000000
+"callsign_12_col_prism",3.000000
+"callsign_17_col_prism",3.000000
+"callsign_20_col_prism",3.000000
+"callsign_25_col_prism",3.000000
+"callsign_28_col_prism",3.000000
+"callsign_32_col_prism",3.000000
+"callsign_43_col_prism",3.000000
+"callsign_44_col_prism",3.000000
+"callsign_49_col_prism",3.000000
+"callsign_50_col_prism",3.000000
+"callsign_52_col_prism",3.000000
+"callsign_54_col_prism",3.000000
+"callsign_56_col_prism",3.000000
+"callsign_58_col_prism",3.000000
+"callsign_60_col_prism",3.000000
+"callsign_61_col_prism",3.000000
+"callsign_62_col_prism",3.000000
+"callsign_63_col_prism",3.000000
+"callsign_64_col_prism",3.000000
+"callsign_71_col_prism",3.000000
+"callsign_72_col_prism",3.000000
+"callsign_73_col_prism",3.000000
+"callsign_74_col_prism",3.000000
+"callsign_77_col_prism",3.000000
+"callsign_80_col_prism",3.000000
+"callsign_81_col_prism",3.000000
+"callsign_82_col_prism",3.000000
+"callsign_83_col_prism",3.000000
+"callsign_84_col_prism",3.000000
+"callsign_85_col_prism",3.000000
+"callsign_86_col_prism",3.000000
+"callsign_87_col_prism",3.000000
+"callsign_88_col_prism",3.000000
+"callsign_89_col_prism",3.000000
+"callsign_90_col_prism",3.000000
+"callsign_91_col_prism",3.000000
+"callsign_93_col_prism",3.000000
+"callsign_95_col_prism",3.000000
+"callsign_98_col_prism",3.000000
+"callsign_101_col_prism",3.000000
+"callsign_102_col_prism",3.000000
+"execution_backshot",3.000000
+"execution_combo",3.000000
+"execution_knockout",3.000000
+"credit_award",50.000000
+"coliseum_ticket",35.000000
+"northstar.northstar_nose_art_12",5.000000
+"northstar.northstar_nose_art_13",5.000000
+"ronin.ronin_nose_art_08",5.000000
+"ronin.ronin_nose_art_12",5.000000
+"tone.tone_nose_art_11",5.000000
+"tone.tone_nose_art_12",5.000000
+"scorch.scorch_nose_art_12",5.000000
+"legion.legion_nose_art_12",5.000000
+"legion.legion_nose_art_14",5.000000
+"camo_skin04",5.000000
+"camo_skin05",5.000000
+"camo_skin06",5.000000
+"camo_skin11",5.000000
+"camo_skin12",5.000000
+"camo_skin20",5.000000
+"camo_skin21",5.000000
+"camo_skin22",5.000000
+"camo_skin23",5.000000
+"camo_skin28",5.000000
+"camo_skin29",5.000000
+"camo_skin32",5.000000
+"camo_skin33",5.000000
+"camo_skin34",5.000000
+"camo_skin35",5.000000
+"camo_skin36",5.000000
+"camo_skin37",5.000000
+"camo_skin38",5.000000
+"camo_skin39",5.000000
+"camo_skin40",5.000000
+"camo_skin41",5.000000
+"camo_skin42",5.000000
+"camo_skin43",5.000000
+"camo_skin44",5.000000
+"camo_skin45",5.000000
+"camo_skin46",5.000000
+"camo_skin47",5.000000
+"camo_skin48",5.000000
+"camo_skin49",5.000000
+"camo_skin50",5.000000
+"camo_skin51",5.000000
+"camo_skin52",5.000000
+"camo_skin53",5.000000
+"camo_skin54",5.000000
+"camo_skin68",5.000000
+"camo_skin69",5.000000
+"camo_skin70",5.000000
+"camo_skin71",5.000000
+"camo_skin72",5.000000
+"camo_skin73",5.000000
+"camo_skin74",5.000000
+"camo_skin75",5.000000
+"camo_skin76",5.000000
+"camo_skin77",5.000000
+"camo_skin78",5.000000
+"camo_skin79",5.000000
+"camo_skin80",5.000000
+"camo_skin84",5.000000
+"camo_skin86",5.000000
+"camo_skin88",5.000000
+"camo_skin89",5.000000
+"camo_skin90",5.000000
+"camo_skin95",5.000000
+"camo_skin96",5.000000
+"camo_skin98",5.000000
+"camo_skin99",5.000000
+"pilot_camo_skin04",10.000000
+"pilot_camo_skin05",10.000000
+"pilot_camo_skin06",10.000000
+"pilot_camo_skin11",10.000000
+"pilot_camo_skin12",10.000000
+"pilot_camo_skin20",10.000000
+"pilot_camo_skin21",10.000000
+"pilot_camo_skin22",10.000000
+"pilot_camo_skin23",10.000000
+"pilot_camo_skin28",10.000000
+"pilot_camo_skin29",10.000000
+"pilot_camo_skin32",10.000000
+"pilot_camo_skin33",10.000000
+"pilot_camo_skin34",10.000000
+"pilot_camo_skin35",10.000000
+"pilot_camo_skin36",10.000000
+"pilot_camo_skin37",10.000000
+"pilot_camo_skin38",10.000000
+"pilot_camo_skin39",10.000000
+"pilot_camo_skin40",10.000000
+"pilot_camo_skin41",10.000000
+"pilot_camo_skin42",10.000000
+"pilot_camo_skin43",10.000000
+"pilot_camo_skin44",10.000000
+"pilot_camo_skin45",10.000000
+"pilot_camo_skin46",10.000000
+"pilot_camo_skin47",10.000000
+"pilot_camo_skin48",10.000000
+"pilot_camo_skin49",10.000000
+"pilot_camo_skin50",10.000000
+"pilot_camo_skin51",10.000000
+"pilot_camo_skin52",10.000000
+"pilot_camo_skin53",10.000000
+"pilot_camo_skin54",10.000000
+"pilot_camo_skin68",10.000000
+"pilot_camo_skin69",10.000000
+"pilot_camo_skin70",10.000000
+"pilot_camo_skin71",10.000000
+"pilot_camo_skin72",10.000000
+"pilot_camo_skin73",10.000000
+"pilot_camo_skin74",10.000000
+"pilot_camo_skin75",10.000000
+"pilot_camo_skin76",10.000000
+"pilot_camo_skin77",10.000000
+"pilot_camo_skin78",10.000000
+"pilot_camo_skin79",10.000000
+"pilot_camo_skin80",10.000000
+"pilot_camo_skin84",10.000000
+"pilot_camo_skin86",10.000000
+"pilot_camo_skin88",10.000000
+"pilot_camo_skin89",10.000000
+"pilot_camo_skin90",10.000000
+"pilot_camo_skin95",10.000000
+"pilot_camo_skin96",10.000000
+"pilot_camo_skin98",10.000000
+"pilot_camo_skin99",10.000000
+"titan_camo_skin04",10.000000
+"titan_camo_skin05",10.000000
+"titan_camo_skin06",10.000000
+"titan_camo_skin11",10.000000
+"titan_camo_skin12",10.000000
+"titan_camo_skin20",10.000000
+"titan_camo_skin21",10.000000
+"titan_camo_skin22",10.000000
+"titan_camo_skin23",10.000000
+"titan_camo_skin28",10.000000
+"titan_camo_skin29",10.000000
+"titan_camo_skin32",10.000000
+"titan_camo_skin33",10.000000
+"titan_camo_skin34",10.000000
+"titan_camo_skin35",10.000000
+"titan_camo_skin36",10.000000
+"titan_camo_skin37",10.000000
+"titan_camo_skin38",10.000000
+"titan_camo_skin39",10.000000
+"titan_camo_skin40",10.000000
+"titan_camo_skin41",10.000000
+"titan_camo_skin42",10.000000
+"titan_camo_skin43",10.000000
+"titan_camo_skin44",10.000000
+"titan_camo_skin45",10.000000
+"titan_camo_skin46",10.000000
+"titan_camo_skin47",10.000000
+"titan_camo_skin48",10.000000
+"titan_camo_skin49",10.000000
+"titan_camo_skin50",10.000000
+"titan_camo_skin51",10.000000
+"titan_camo_skin52",10.000000
+"titan_camo_skin53",10.000000
+"titan_camo_skin54",10.000000
+"titan_camo_skin68",10.000000
+"titan_camo_skin69",10.000000
+"titan_camo_skin70",10.000000
+"titan_camo_skin71",10.000000
+"titan_camo_skin72",10.000000
+"titan_camo_skin73",10.000000
+"titan_camo_skin74",10.000000
+"titan_camo_skin75",10.000000
+"titan_camo_skin76",10.000000
+"titan_camo_skin77",10.000000
+"titan_camo_skin78",10.000000
+"titan_camo_skin79",10.000000
+"titan_camo_skin80",10.000000
+"titan_camo_skin84",10.000000
+"titan_camo_skin86",10.000000
+"titan_camo_skin88",10.000000
+"titan_camo_skin89",10.000000
+"titan_camo_skin90",10.000000
+"titan_camo_skin95",10.000000
+"titan_camo_skin96",10.000000
+"titan_camo_skin98",10.000000
+"titan_camo_skin99",10.000000
+"gc_icon_5star",15.000000
+"gc_icon_angryface",15.000000
+"gc_icon_bear",15.000000
+"gc_icon_bee",15.000000
+"gc_icon_bigcat",15.000000
+"gc_icon_bird",15.000000
+"gc_icon_bunnyskull",15.000000
+"gc_icon_chicken",15.000000
+"gc_icon_club",15.000000
+"gc_icon_corporal",15.000000
+"gc_icon_cow",15.000000
+"gc_icon_cupcake",15.000000
+"gc_icon_dataknife",15.000000
+"gc_icon_doublerainbow",15.000000
+"gc_icon_dragon",15.000000
+"gc_icon_earthworm",15.000000
+"gc_icon_fair_warning",15.000000
+"gc_icon_falcon",15.000000
+"gc_icon_fingerprint",15.000000
+"gc_icon_flying_skull",15.000000
+"gc_icon_ghostface",15.000000
+"gc_icon_hamburger",15.000000
+"gc_icon_hammer",15.000000
+"gc_icon_handprint",15.000000
+"gc_icon_hawkmoth",15.000000
+"gc_icon_heartless",15.000000
+"gc_icon_hvt",15.000000
+"gc_icon_jollyrgr",15.000000
+"gc_icon_knife",15.000000
+"gc_icon_lol",15.000000
+"gc_icon_mad_hat",15.000000
+"gc_icon_marksman",15.000000
+"gc_icon_omg",15.000000
+"gc_icon_ordnance",15.000000
+"gc_icon_pizza",15.000000
+"gc_icon_pvt",15.000000
+"gc_icon_question",15.000000
+"gc_icon_rainbow",15.000000
+"gc_icon_ram",15.000000
+"gc_icon_respawn",15.000000
+"gc_icon_saturn",15.000000
+"gc_icon_scorpion",15.000000
+"gc_icon_senior_sgt_e6",15.000000
+"gc_icon_senior_sgt",15.000000
+"gc_icon_sgt",15.000000
+"gc_icon_skull",15.000000
+"gc_icon_snake",15.000000
+"gc_icon_stab",15.000000
+"gc_icon_teabage",15.000000
+"gc_icon_widow",15.000000
+"gc_icon_witch_hat",15.000000
+"gc_icon_wizard_hat",15.000000
+"gc_icon_wraith",15.000000
+"gc_icon_wtf",15.000000
+"gc_icon_down",35.000000
+"gc_icon_joy",35.000000
+"execution_face_stab",1.000000
+"ion.ion_skin_03",1.000000
+"camo_skin08",1.000000
+"pilot_camo_skin08",1.000000
+"titan_camo_skin08",1.000000
+"ion.ion_nose_art_05",1.000000
+"callsign_tt_gameover",10.000000
+"callsign_tt_gameover_prism",1.000000
+"callsign_tt_guardtheflag",10.000000
+"callsign_tt_guardtheflag_prism",1.000000
+"callsign_tt_megamarvin",10.000000
+"callsign_tt_megamarvin_prism",1.000000
+"callsign_tt_nessievault",10.000000
+"callsign_tt_nessievault_prism",1.000000
+"callsign_tt_nsbt",10.000000
+"callsign_tt_nsbt_prism",1.000000
+"callsign_tt_protocol2",10.000000
+"callsign_tt_protocol2_prism",1.000000
+"callsign_tt_rekt",10.000000
+"callsign_tt_rekt_prism",1.000000
+"callsign_tt_titantoons",10.000000
+"callsign_tt_titantoons_prism",1.000000
+"callsign_eat_ion",1.000000
+"callsign_eat_legion",1.000000
+"callsign_eat_northstar",1.000000
+"callsign_eat_ronin",1.000000
+"callsign_eat_scorch",1.000000
+"callsign_eat_tone",1.000000
+"callsign_126_col_prism",1.000000
+"callsign_127_col_prism",1.000000
+"callsign_130_col_prism",1.000000
+"callsign_131_col_prism",1.000000
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/unlocks_titan_level.csv b/Northstar.CustomServers/mod/scripts/datatable/unlocks_titan_level.csv new file mode 100644 index 00000000..24f54fea --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/unlocks_titan_level.csv @@ -0,0 +1,402 @@ +titanLevel,ion,scorch,northstar,ronin,tone,legion,vanguard,end
+"","ion","scorch","northstar","ronin","tone","legion","vanguard","END"
+"1","pas_ion_weapon,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,titan_camo_skin00,camo_skin00,ion_nose_art_none,pas_vanguard_core1, pas_vanguard_core4,pas_vanguard_core7,execution_random_0,execution_ion,execution_ion_prime","pas_scorch_weapon,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,titan_camo_skin00,camo_skin00,scorch_nose_art_none,pas_vanguard_core1, pas_vanguard_core4,pas_vanguard_core7,execution_random_1,execution_scorch,execution_scorch_prime","pas_northstar_weapon,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,titan_camo_skin00,camo_skin00,northstar_nose_art_none,pas_vanguard_core1, pas_vanguard_core4,pas_vanguard_core7,execution_random_2,execution_northstar,execution_northstar_prime","pas_ronin_weapon,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,titan_camo_skin00,camo_skin00,ronin_nose_art_none,pas_vanguard_core1, pas_vanguard_core4,pas_vanguard_core7,execution_random_3,execution_ronin,execution_ronin_prime","pas_tone_weapon,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,titan_camo_skin00,camo_skin00,tone_nose_art_none,pas_vanguard_core1, pas_vanguard_core4,pas_vanguard_core7,execution_random_4,execution_tone,execution_tone_prime","pas_legion_weapon,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,titan_camo_skin00,camo_skin00,legion_nose_art_none,pas_vanguard_core1, pas_vanguard_core4,pas_vanguard_core7,execution_random_5,execution_legion,execution_legion_prime","pas_vanguard_shield,pas_mobility_dash_capacity,pas_enhanced_titan_ai,pas_auto_eject,pas_bubbleshield,pas_vanguard_core1,pas_vanguard_core4,pas_vanguard_core7,titan_camo_skin00,camo_skin00,vanguard_nose_art_none,execution_random_6,execution_vanguard",""
+"2","pas_hyper_core","pas_hyper_core","pas_hyper_core","pas_hyper_core","pas_hyper_core","pas_hyper_core","pas_hyper_core",""
+"3","pas_build_up_nuclear_core","pas_build_up_nuclear_core","pas_build_up_nuclear_core","pas_build_up_nuclear_core","pas_build_up_nuclear_core","pas_build_up_nuclear_core","pas_vanguard_core2,pas_build_up_nuclear_core",""
+"4","pas_anti_rodeo,ion_nose_art_14","pas_anti_rodeo,scorch_nose_art_11","pas_anti_rodeo,northstar_nose_art_11","pas_anti_rodeo,ronin_nose_art_14","pas_anti_rodeo,tone_nose_art_13","pas_anti_rodeo,legion_nose_art_13","pas_anti_rodeo,vanguard_nose_art_01",""
+"5","pas_warpfall,random","pas_warpfall,random","pas_warpfall,random","pas_warpfall,random","pas_warpfall,random","pas_warpfall,random","pas_warpfall,pas_vanguard_core5,random",""
+"6","pas_ion_tripwire,titan_camo_skin01","pas_scorch_selfdmg,titan_camo_skin01","pas_northstar_cluster,titan_camo_skin01","pas_ronin_arcwave,titan_camo_skin01","pas_tone_wall,titan_camo_skin01","pas_legion_smartcore,titan_camo_skin01","pas_vanguard_coremeter,titan_camo_skin01",""
+"7","pas_ion_vortex","pas_scorch_shield","pas_northstar_trap","pas_ronin_phase","pas_tone_sonar","pas_legion_gunshield","pas_vanguard_core8,pas_vanguard_rearm",""
+"8","pas_ion_lasercannon,camo_skin01","pas_scorch_firewall,camo_skin01","pas_northstar_flightcore,camo_skin01","pas_ronin_swordcore,camo_skin01","pas_tone_rockets,camo_skin01","pas_legion_spinup,camo_skin01","pas_vanguard_core3,pas_vanguard_doom,camo_skin01",""
+"9","titan_camo_skin03,pas_ion_weapon_ads","titan_camo_skin03,pas_scorch_flamecore","titan_camo_skin03,pas_northstar_optics","titan_camo_skin03,pas_ronin_autoshift","titan_camo_skin03,pas_tone_burst","titan_camo_skin03,pas_legion_chargeshot","titan_camo_skin03,pas_vanguard_core6",""
+"10","gc_icon_cateye,ion_nose_art_01","gc_icon_fireball,scorch_nose_art_02","gc_icon_stinger,northstar_nose_art_08","gc_icon_sword,ronin_nose_art_02","gc_icon_crosshair,tone_nose_art_14","gc_icon_bullet,legion_nose_art_09","gc_icon_monarch,vanguard_nose_art_02,pas_vanguard_core9",""
+"11","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03",""
+"12","titan_camo_skin02","titan_camo_skin02","titan_camo_skin02","titan_camo_skin02","titan_camo_skin02","titan_camo_skin02","titan_camo_skin02",""
+"13","","","","","","","",""
+"14","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02",""
+"15","titan_camo_skin97","titan_camo_skin97","titan_camo_skin97","titan_camo_skin97","titan_camo_skin97","titan_camo_skin97","titan_camo_skin97",""
+"16","","","","","","","",""
+"17","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97",""
+"18","titan_camo_skin24","titan_camo_skin24","titan_camo_skin24","titan_camo_skin24","titan_camo_skin24","titan_camo_skin24","titan_camo_skin24",""
+"19","","","","","","","",""
+"20","camo_skin24,ion_nose_art_08","camo_skin24,scorch_nose_art_03","camo_skin24,northstar_nose_art_06","camo_skin24,ronin_nose_art_11","camo_skin24,tone_nose_art_04","camo_skin24,legion_nose_art_06","camo_skin24,vanguard_nose_art_03",""
+"1","titan_camo_skin16,callsign_24_col","titan_camo_skin16,callsign_47_col","titan_camo_skin16,callsign_36_col","titan_camo_skin16,callsign_45_col","titan_camo_skin16,callsign_68_col","titan_camo_skin16,callsign_26_col","titan_camo_skin16,callsign_165_col",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","camo_skin16","camo_skin16","camo_skin16","camo_skin16","camo_skin16","camo_skin16","camo_skin16",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","titan_camo_skin25","titan_camo_skin25","titan_camo_skin25","titan_camo_skin25","titan_camo_skin25","titan_camo_skin25","titan_camo_skin25",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_04","scorch_nose_art_05","northstar_nose_art_04","ronin_nose_art_05","tone_nose_art_03","legion_nose_art_03","vanguard_nose_art_04",""
+"1","titan_camo_skin14,callsign_24_col_fire","titan_camo_skin14,callsign_47_col_fire","titan_camo_skin14,callsign_36_col_fire","titan_camo_skin14,callsign_45_col_fire","titan_camo_skin14,callsign_68_col_fire","titan_camo_skin14,callsign_26_col_fire","titan_camo_skin14,callsign_165_col_fire",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","titan_camo_skin26","titan_camo_skin26","titan_camo_skin26","titan_camo_skin26","titan_camo_skin26","titan_camo_skin26","titan_camo_skin26",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_03","scorch_nose_art_01","northstar_nose_art_01","ronin_nose_art_06","tone_nose_art_07","legion_nose_art_10","vanguard_nose_art_05",""
+"1","titan_camo_skin83,callsign_24_col_gold","titan_camo_skin83,callsign_47_col_gold","titan_camo_skin83,callsign_36_col_gold","titan_camo_skin83,callsign_45_col_gold","titan_camo_skin83,callsign_68_col_gold","titan_camo_skin83,callsign_26_col_gold","titan_camo_skin83,callsign_165_col_gold",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","titan_camo_skin27","titan_camo_skin27","titan_camo_skin27","titan_camo_skin27","titan_camo_skin27","titan_camo_skin27","titan_camo_skin27",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_12","scorch_nose_art_13","northstar_nose_art_09","ronin_nose_art_04","tone_nose_art_02","legion_nose_art_02","vanguard_nose_art_06",""
+"1","titan_camo_skin31","titan_camo_skin31","titan_camo_skin31","titan_camo_skin31","titan_camo_skin31","titan_camo_skin31","titan_camo_skin31",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","titan_camo_skin19","titan_camo_skin19","titan_camo_skin19","titan_camo_skin19","titan_camo_skin19","titan_camo_skin19","titan_camo_skin19",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_13","scorch_nose_art_10","northstar_nose_art_03","ronin_nose_art_09","tone_nose_art_09","legion_nose_art_01","vanguard_nose_art_07",""
+"1","titan_camo_skin82","titan_camo_skin82","titan_camo_skin82","titan_camo_skin82","titan_camo_skin82","titan_camo_skin82","titan_camo_skin82",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","titan_camo_skin15","titan_camo_skin15","titan_camo_skin15","titan_camo_skin15","titan_camo_skin15","titan_camo_skin15","titan_camo_skin15",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_02","scorch_nose_art_04","northstar_nose_art_02","ronin_nose_art_01","tone_nose_art_01","legion_nose_art_08","",""
+"1","titan_camo_skin17","titan_camo_skin17","titan_camo_skin17","titan_camo_skin17","titan_camo_skin17","titan_camo_skin17","titan_camo_skin17",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_06","scorch_nose_art_14","northstar_nose_art_10","ronin_nose_art_13","tone_nose_art_05","legion_nose_art_11","vanguard_nose_art_08",""
+"1","titan_camo_skin81","titan_camo_skin81","titan_camo_skin81","titan_camo_skin81","titan_camo_skin81","titan_camo_skin81","titan_camo_skin81",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_11","scorch_nose_art_09","northstar_nose_art_05","ronin_nose_art_10","tone_nose_art_08","legion_nose_art_04","",""
+"1","titan_camo_skin18","titan_camo_skin18","titan_camo_skin18","titan_camo_skin18","titan_camo_skin18","titan_camo_skin18","titan_camo_skin18",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_10","scorch_nose_art_08","northstar_nose_art_14","ronin_nose_art_03","tone_nose_art_06","legion_nose_art_05","vanguard_nose_art_09",""
+"1","titan_camo_skin30","titan_camo_skin30","titan_camo_skin30","titan_camo_skin30","titan_camo_skin30","titan_camo_skin30","titan_camo_skin30",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","ion_nose_art_09","","","","","","",""
+"1","","","","","","","",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
+"1","random","random","random","random","random","random","random",""
+"2","","","","","","","",""
+"3","","","","","","","",""
+"4","","","","","","","",""
+"5","","","","","","","",""
+"6","","","","","","","",""
+"7","","","","","","","",""
+"8","","","","","","","",""
+"9","","","","","","","",""
+"10","","","","","","","",""
+"11","","","","","","","",""
+"12","","","","","","","",""
+"13","","","","","","","",""
+"14","","","","","","","",""
+"15","","","","","","","",""
+"16","","","","","","","",""
+"17","","","","","","","",""
+"18","","","","","","","",""
+"19","","","","","","","",""
+"20","","","","","","","",""
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/unlocks_weapon_level_pilot.csv b/Northstar.CustomServers/mod/scripts/datatable/unlocks_weapon_level_pilot.csv new file mode 100644 index 00000000..5c881ac5 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/unlocks_weapon_level_pilot.csv @@ -0,0 +1,383 @@ +weaponLevel,weap1,weap2,weap3,weap4,weap5,weap6,weap7,weap8,weap9,weap10,weap11,weap12,weap13,weap14,weap15,weap16,weap17,weap18,weap19,weap20,weap21,weap22,weap23,weap24,weap25,weap26,weap27,weap28,weap29,weap30,end
+"","mp_weapon_alternator_smg","mp_weapon_arc_launcher","mp_weapon_autopistol","mp_weapon_car","mp_weapon_defender","mp_weapon_dmr","mp_weapon_doubletake","mp_weapon_epg","mp_weapon_esaw","mp_weapon_g2","mp_weapon_hemlok","mp_weapon_hemlok_smg","mp_weapon_lmg","mp_weapon_lstar","mp_weapon_mastiff","mp_weapon_mgl","mp_weapon_pulse_lmg","mp_weapon_r97","mp_weapon_rocket_launcher","mp_weapon_rspn101","mp_weapon_semipistol","mp_weapon_shotgun","mp_weapon_shotgun_pistol","mp_weapon_smr","mp_weapon_sniper","mp_weapon_softball","mp_weapon_vinson","mp_weapon_wingman","mp_weapon_wingman_n","mp_weapon_rspn101_og","END"
+"1","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen","camo_skin00, pro_screen",""
+"2","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo","extended_ammo",""
+"3","hcog","pas_fast_reload","silencer","holosight","quick_charge","scope_4x","scope_4x","pas_run_and_gun","aog","hcog","hcog","holosight","aog","aog","holosight","pas_fast_reload","pas_run_and_gun","holosight","pas_fast_reload","hcog","silencer","holosight","silencer","pas_run_and_gun","scope_4x","pas_run_and_gun","hcog","silencer","ricochet","hcog",""
+"4","pas_run_and_gun","pas_fast_ads","pas_run_and_gun","pas_run_and_gun","pas_fast_ads","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_fast_ads","pas_fast_reload","pas_run_and_gun","pas_fast_ads","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun","pas_run_and_gun",""
+"5","pas_fast_reload","pas_fast_swap","pas_fast_reload","pas_fast_reload","pas_fast_swap","pas_fast_ads","pas_fast_ads","pas_fast_ads","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_swap","pas_fast_ads","pas_fast_reload","pas_fast_swap","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_ads","pas_fast_ads","pas_fast_ads","pas_fast_reload","pas_fast_reload","pas_fast_reload","pas_fast_reload",""
+"6","redline_sight","secondarymod2","pas_fast_ads","redline_sight","secondarymod2","pas_fast_swap","pas_fast_swap","pas_fast_swap","redline_sight","redline_sight","redline_sight","redline_sight","redline_sight","redline_sight","redline_sight","secondarymod2","pas_fast_swap","redline_sight","secondarymod2","redline_sight","pas_fast_ads","redline_sight","pas_fast_ads","pas_fast_swap","pas_fast_swap","pas_fast_swap","redline_sight","pas_fast_ads","pas_fast_ads","redline_sight",""
+"7","pas_fast_ads","","tactical_cdr_on_kill","pas_fast_ads","","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","pas_fast_ads","pas_fast_ads","pas_fast_ads","pas_fast_ads","pas_fast_ads","pas_fast_ads","pas_fast_ads","","tactical_cdr_on_kill","pas_fast_ads","","pas_fast_ads","tactical_cdr_on_kill","pas_fast_ads","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","pas_fast_ads","tactical_cdr_on_kill","tactical_cdr_on_kill","pas_fast_ads",""
+"8","pas_fast_swap,random","random","secondarymod2,random","pas_fast_swap,random","random","threat_scope,random","threat_scope,random","random,primarymod2","pas_fast_swap,random","pas_fast_swap,random","pas_fast_swap,random","pas_fast_swap,random","pas_fast_swap,random","pas_fast_swap,random","pas_fast_swap,random","random","primarymod2,random","pas_fast_swap,random","random","pas_fast_swap,random","secondarymod2,random","pas_fast_swap,random","primarymod2,random","primarymod2,random","threat_scope,random","primarymod2,random","pas_fast_swap,random","secondarymod2,random","primarymod2,random","pas_fast_swap,random",""
+"9","tactical_cdr_on_kill","","","tactical_cdr_on_kill","","primarymod2","ricochet","","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","tactical_cdr_on_kill","","","tactical_cdr_on_kill","","tactical_cdr_on_kill","","tactical_cdr_on_kill","","","ricochet","","tactical_cdr_on_kill","","","tactical_cdr_on_kill",""
+"10","threat_scope,camo_skin01","camo_skin01","camo_skin01","threat_scope,camo_skin01","camo_skin01","camo_skin01","primarymod2,camo_skin01","camo_skin01","threat_scope,camo_skin01","threat_scope,camo_skin01","threat_scope,camo_skin01","threat_scope,camo_skin01","threat_scope,camo_skin01","threat_scope,camo_skin01","threat_scope,camo_skin01","camo_skin01","camo_skin01","threat_scope,camo_skin01","camo_skin01","threat_scope,camo_skin01","camo_skin01","threat_scope,camo_skin01","camo_skin01","camo_skin01","primarymod2,camo_skin01","camo_skin01","threat_scope,camo_skin01","camo_skin01","camo_skin01","threat_scope,camo_skin01",""
+"11","primarymod2","","","primarymod2","","","","","primarymod2","primarymod2","primarymod2","primarymod2","primarymod2","primarymod2","primarymod2","","","primarymod2","","primarymod2","","primarymod2","","","","","primarymod2","","","primarymod2",""
+"12","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03","camo_skin03",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02","camo_skin02",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97","camo_skin97",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24","camo_skin24",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","gc_icon_yuckface","gc_icon_raincloud","gc_icon_diamond","gc_icon_wasp","gc_icon_bullseye","gc_icon_fin","gc_icon_dice","gc_icon_comet","gc_icon_heart","gc_icon_ramskull","gc_icon_waves","gc_icon_lightning","gc_icon_hawk","gc_icon_star","gc_icon_paw","gc_icon_frag","gc_icon_moon","gc_icon_assault","gc_icon_rocket","gc_icon_atom","gc_icon_spade","gc_icon_8ball","gc_icon_clawmark","gc_icon_bomb_02","gc_icon_happyface","gc_icon_bomb_01","gc_icon_medic","gc_icon_dragonfly","gc_icon_b3_wing","gc_icon_mushroom",""
+"1","primarymod3,camo_skin16","secondarymod3,camo_skin16","secondarymod3,camo_skin16","primarymod3,camo_skin16","secondarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","secondarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","secondarymod3,camo_skin16","primarymod3,camo_skin16","secondarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16","secondarymod3,camo_skin16","primarymod3,camo_skin16","primarymod3,camo_skin16",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","callsign_13_col","callsign_76_col","callsign_29_col","callsign_55_col","callsign_66_col","callsign_30_col","callsign_21_col","callsign_94_col","callsign_15_col","callsign_31_col","callsign_40_col","callsign_18_col","callsign_27_col","callsign_22_col","callsign_48_col","callsign_42_col","callsign_78_col","callsign_75_col","callsign_92_col","callsign_03_col","callsign_37_col","callsign_79_col","callsign_51_col","callsign_11_col","callsign_57_col","callsign_59_col","callsign_69_col","callsign_19_col","callsign_139_col","callsign_128_col",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25","camo_skin25",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14","camo_skin14",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","callsign_13_col_fire","callsign_76_col_fire","callsign_29_col_fire","callsign_55_col_fire","callsign_66_col_fire","callsign_30_col_fire","callsign_21_col_fire","callsign_94_col_fire","callsign_15_col_fire","callsign_31_col_fire","callsign_40_col_fire","callsign_18_col_fire","callsign_27_col_fire","callsign_22_col_fire","callsign_48_col_fire","callsign_42_col_fire","callsign_78_col_fire","callsign_75_col_fire","callsign_92_col_fire","callsign_03_col_fire","callsign_37_col_fire","callsign_79_col_fire","callsign_51_col_fire","callsign_11_col_fire","callsign_57_col_fire","callsign_59_col_fire","callsign_69_col_fire","callsign_19_col_fire","callsign_139_col_fire","callsign_128_col_fire",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26","camo_skin26",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83","camo_skin83",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","callsign_13_col_gold","callsign_76_col_gold","callsign_29_col_gold","callsign_55_col_gold","callsign_66_col_gold","callsign_30_col_gold","callsign_21_col_gold","callsign_94_col_gold","callsign_15_col_gold","callsign_31_col_gold","callsign_40_col_gold","callsign_18_col_gold","callsign_27_col_gold","callsign_22_col_gold","callsign_48_col_gold","callsign_42_col_gold","callsign_78_col_gold","callsign_75_col_gold","callsign_92_col_gold","callsign_03_col_gold","callsign_37_col_gold","callsign_79_col_gold","callsign_51_col_gold","callsign_11_col_gold","callsign_57_col_gold","callsign_59_col_gold","callsign_69_col_gold","callsign_19_col_gold","callsign_139_col_gold","callsign_128_col_gold",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27","camo_skin27",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31","camo_skin31",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19","camo_skin19",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82","camo_skin82",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15","camo_skin15",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17","camo_skin17",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81","camo_skin81",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18","camo_skin18",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30","camo_skin30",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
+"2","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"3","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"4","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"5","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"6","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"7","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"8","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"9","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"10","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"11","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"12","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"13","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"14","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"15","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"16","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"17","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"18","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"19","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"20","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""
+"1","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random","random",""
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/weapon_skins.csv b/Northstar.CustomServers/mod/scripts/datatable/weapon_skins.csv new file mode 100644 index 00000000..0f074882 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/weapon_skins.csv @@ -0,0 +1,35 @@ +ref,weaponRef,image,name,cost,skinIndex,skinType
+"skin_rspn101_wasteland","mp_weapon_rspn101","rui/weapon_skin_swatches/swatch_wasteland","#SKIN_WASTELAND",0,8,1
+"skin_g2_masterwork","mp_weapon_g2","rui/weapon_skin_swatches/swatch_masterwork","#SKIN_MASTERWORK",0,6,1
+"skin_vinson_blue_fade","mp_weapon_vinson","rui/weapon_skin_swatches/swatch_blue_fade","#SKIN_BLUE_FADE",0,7,1
+"skin_car_crimson_fury","mp_weapon_car","rui/weapon_skin_swatches/swatch_crimson_fury","#SKIN_CRIMSON_FURY",0,6,1
+"skin_alternator_patriot","mp_weapon_alternator_smg","rui/weapon_skin_swatches/swatch_patriot","#SKIN_PATRIOT",0,2,1
+"skin_shotgun_badlands","mp_weapon_shotgun","rui/weapon_skin_swatches/swatch_badlands","#SKIN_BADLANDS",0,4,1
+"skin_wingman_aqua_fade","mp_weapon_wingman","rui/weapon_skin_swatches/swatch_aqua_fade","#SKIN_AQUA_FADE",0,7,1
+"skin_rocket_launcher_psych_spectre","mp_weapon_rocket_launcher","rui/weapon_skin_swatches/swatch_psych_spectre","#SKIN_PHANTOM",0,2,1
+"skin_rspn101_patriot","mp_weapon_rspn101","rui/weapon_skin_swatches/swatch_patriot","#SKIN_PATRIOT",0,9,1
+"skin_hemlok_mochi","mp_weapon_hemlok","rui/weapon_skin_swatches/swatch_mochi","#SKIN_MOCHI",0,5,1
+"skin_r97_purple_fade","mp_weapon_r97","rui/weapon_skin_swatches/swatch_purple_fade","#SKIN_PURPLE_FADE",0,7,1
+"skin_kraber_masterwork","mp_weapon_sniper","rui/weapon_skin_swatches/swatch_masterwork","#SKIN_MASTERWORK",0,2,1
+"skin_spitfire_lead_farmer","mp_weapon_lmg","rui/weapon_skin_swatches/swatch_lead_farmer","#SKIN_LEAD_FARMER",0,8,1
+"skin_devotion_rspn_customs","mp_weapon_esaw","rui/weapon_skin_swatches/swatch_rspn_customs","#SKIN_RSPN_CUSTOMS",0,8,1
+"skin_mozambique_crimson_fury","mp_weapon_shotgun_pistol","rui/weapon_skin_swatches/swatch_crimson_fury","#SKIN_CRIMSON_FURY",0,7,1
+"skin_thunderbolt_8bit","mp_weapon_arc_launcher","rui/weapon_skin_swatches/swatch_8_bit","#SKIN_8_BIT",0,2,1
+"skin_lstar_heatsink","mp_weapon_lstar","rui/weapon_skin_swatches/swatch_heatsink","#SKIN_HEAT_SINK",0,6,1
+"skin_mastiff_crimson_fury","mp_weapon_mastiff","rui/weapon_skin_swatches/swatch_crimson_fury","#SKIN_CRIMSON_FURY",0,7,1
+"skin_sidewinder_masterwork","mp_weapon_smr","rui/weapon_skin_swatches/swatch_masterwork","#SKIN_MASTERWORK",0,2,1
+"skin_rspn101_halloween","mp_weapon_rspn101","rui/weapon_skin_swatches/swatch_rspn101_halloween","#SKIN_HALLOWEEN",0,10,1
+"skin_car_halloween","mp_weapon_car","rui/weapon_skin_swatches/swatch_car_halloween","#SKIN_HALLOWEEN",0,8,1
+"skin_spitfire_halloween","mp_weapon_lmg","rui/weapon_skin_swatches/swatch_spitfire_halloween","#SKIN_HALLOWEEN",0,9,1
+"skin_rspn101_og_blue_fade","mp_weapon_rspn101_og","rui/weapon_skin_swatches/swatch_blue_fade","#SKIN_BLUE_FADE",0,7,1
+"skin_vinson_badlands","mp_weapon_vinson","rui/weapon_skin_swatches/swatch_badlands_flatline","#SKIN_BADLANDS",0,8,1
+"skin_volt_heatsink","mp_weapon_hemlok_smg","rui/weapon_skin_swatches/swatch_heatsink","#SKIN_HEAT_SINK",0,6,1
+"skin_alternator_headhunter","mp_weapon_alternator_smg","rui/weapon_skin_swatches/swatch_headhunter","#SKIN_HEADHUNTER",0,5,1
+"skin_softball_masterwork","mp_weapon_softball","rui/weapon_skin_swatches/swatch_masterwork","#SKIN_MASTERWORK",0,2,1
+"skin_epg_mrvn","mp_weapon_epg","rui/weapon_skin_swatches/swatch_mrvn","#SKIN_MRVN",0,5,1
+"skin_dmr_phantom","mp_weapon_dmr","rui/weapon_skin_swatches/swatch_psych_spectre","#SKIN_PHANTOM",0,3,1
+"skin_doubletake_masterwork","mp_weapon_doubletake","rui/weapon_skin_swatches/swatch_masterwork","#SKIN_MASTERWORK",0,2,1
+"skin_g2_purple_fade","mp_weapon_g2","rui/weapon_skin_swatches/swatch_purple_fade","#SKIN_PURPLE_FADE",0,7,1
+"skin_coldwar_heatsink","mp_weapon_pulse_lmg","rui/weapon_skin_swatches/swatch_heatsink","#SKIN_HEAT_SINK",0,6,1
+"skin_r97_sky","mp_weapon_r97","rui/weapon_skin_swatches/swatch_sky","#SKIN_SKY",0,5,1
+"skin_rspn101_crimson_fury","mp_weapon_rspn101","rui/weapon_skin_swatches/swatch_crimson_fury","#SKIN_CRIMSON_FURY",0,7,1
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/xp_per_faction_level.csv b/Northstar.CustomServers/mod/scripts/datatable/xp_per_faction_level.csv new file mode 100644 index 00000000..e28cf8c0 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/xp_per_faction_level.csv @@ -0,0 +1,6 @@ +level,xpPerLevel
+1,2
+2,3
+3,4
+4,5
+5,5
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/xp_per_fd_titan_level.csv b/Northstar.CustomServers/mod/scripts/datatable/xp_per_fd_titan_level.csv new file mode 100644 index 00000000..28c33f5e --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/xp_per_fd_titan_level.csv @@ -0,0 +1,25 @@ +level,xpPerLevel
+1,12
+2,12
+3,14
+4,14
+5,16
+6,16
+7,18
+8,18
+9,20
+10,20
+11,20
+12,20
+13,20
+14,20
+15,20
+16,20
+17,20
+18,20
+19,20
+20,20
+21,20
+22,20
+23,20
+24,20
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/xp_per_player_level.csv b/Northstar.CustomServers/mod/scripts/datatable/xp_per_player_level.csv new file mode 100644 index 00000000..36e52bc8 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/xp_per_player_level.csv @@ -0,0 +1,51 @@ +level,xpPerLevel
+1,3
+2,4
+3,5
+4,6
+5,7
+6,8
+7,9
+8,10
+9,10
+10,10
+11,10
+12,10
+13,10
+14,10
+15,10
+16,10
+17,10
+18,10
+19,10
+20,10
+21,10
+22,10
+23,10
+24,10
+25,10
+26,10
+27,10
+28,10
+29,10
+30,10
+31,10
+32,10
+33,10
+34,10
+35,10
+36,10
+37,10
+38,10
+39,10
+40,10
+41,10
+42,10
+43,10
+44,10
+45,10
+46,10
+47,10
+48,10
+49,10
+50,10
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/xp_per_titan_level.csv b/Northstar.CustomServers/mod/scripts/datatable/xp_per_titan_level.csv new file mode 100644 index 00000000..d607f589 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/xp_per_titan_level.csv @@ -0,0 +1,21 @@ +level,xpPerLevel
+1,3
+2,5
+3,7
+4,10
+5,10
+6,10
+7,10
+8,10
+9,10
+10,10
+11,10
+12,10
+13,10
+14,10
+15,10
+16,10
+17,10
+18,10
+19,10
+20,10
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/datatable/xp_per_weapon_level.csv b/Northstar.CustomServers/mod/scripts/datatable/xp_per_weapon_level.csv new file mode 100644 index 00000000..a6859594 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/datatable/xp_per_weapon_level.csv @@ -0,0 +1,21 @@ +level,default,sniper,pistol,antititan
+1,3,2,2,2
+2,5,3,3,3
+3,7,4,4,4
+4,10,5,5,4
+5,10,5,5,4
+6,10,5,5,4
+7,10,5,5,4
+8,10,5,5,4
+9,10,5,5,4
+10,10,5,5,4
+11,10,5,5,4
+12,10,5,5,4
+13,10,5,5,4
+14,10,5,5,4
+15,10,5,5,4
+16,10,5,5,4
+17,10,5,5,4
+18,10,5,5,4
+19,10,5,5,4
+20,10,5,5,4
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut index 30758bec..f09ef957 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut @@ -223,6 +223,7 @@ entity function CreateBubbleShieldWithSettings( int team, vector origin, vector entity neutralColoredFX = StartParticleEffectInWorld_ReturnEntity( BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX, coloredFXOrigin, <0, 0, 0> ) SetTeam( neutralColoredFX, team ) bubbleShieldDotS.neutralColoredFX <- neutralColoredFX + neutralColoredFX.DisableHibernation() bubbleShieldFXs.append( neutralColoredFX ) } else @@ -232,11 +233,13 @@ entity function CreateBubbleShieldWithSettings( int team, vector origin, vector SetTeam( friendlyColoredFX, team ) friendlyColoredFX.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY EffectSetControlPointVector( friendlyColoredFX, 1, FRIENDLY_COLOR_FX ) + friendlyColoredFX.DisableHibernation() entity enemyColoredFX = StartParticleEffectInWorld_ReturnEntity( BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX, coloredFXOrigin, <0, 0, 0> ) SetTeam( enemyColoredFX, team ) enemyColoredFX.kv.VisibilityFlags = ENTITY_VISIBLE_TO_ENEMY EffectSetControlPointVector( enemyColoredFX, 1, ENEMY_COLOR_FX ) + enemyColoredFX.DisableHibernation() bubbleShieldDotS.friendlyColoredFX <- friendlyColoredFX bubbleShieldDotS.enemyColoredFX <- enemyColoredFX diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_chat.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_chat.gnut index 97ed959c..44836bc9 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_chat.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_chat.gnut @@ -25,26 +25,26 @@ void function Chat_PrivateMessage(entity fromPlayer, entity toPlayer, string tex } // Broadcasts a message from the server to all players. -void function Chat_ServerBroadcast(string text) +void function Chat_ServerBroadcast(string text, bool withServerTag = true) { NSBroadcastMessage( -1, -1, text, - false, + !withServerTag, false, eChatMessageType.CHAT ) } // Sends a message from the server to one player. Will be shown as a whisper if whisper is set. -void function Chat_ServerPrivateMessage(entity toPlayer, string text, bool whisper) +void function Chat_ServerPrivateMessage(entity toPlayer, string text, bool whisper, bool withServerTag = true) { NSBroadcastMessage( -1, toPlayer.GetPlayerIndex(), text, - false, + !withServerTag, false, whisper ? eChatMessageType.WHISPER : eChatMessageType.CHAT ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut index d2621db3..3704b5cc 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut @@ -46,6 +46,8 @@ global function CodeCallback_OnEntityChangedTeam global function AddEntityCallback_OnDamaged global function RemoveEntityCallback_OnDamaged +global function AddEntityCallback_OnFinalDamaged +global function RemoveEntityCallback_OnFinalDamaged global function AddEntityCallback_OnPostDamaged global function RemoveEntityCallback_OnPostDamaged global function AddEntityCallback_OnKilled @@ -121,6 +123,13 @@ void function CodeCallback_DamageEntity( entity ent, var damageInfo ) printt( " after class damage final callbacks:", DamageInfo_GetDamage( damageInfo ) ) #endif + foreach ( callbackFunc in ent.e.entFinalDamageCallbacks ) + callbackFunc( ent, damageInfo ) + + #if VERBOSE_DAMAGE_PRINTOUTS + printt( " after AddEntityCallback_OnFinalDamaged callbacks:", DamageInfo_GetDamage( damageInfo ) ) + #endif + // make destructible vehicles take more damage from DF_EXPLOSION damage type if ( "isDestructibleVehicle" in ent.s && DamageInfo_GetCustomDamageType( damageInfo ) & DF_EXPLOSION ) { @@ -566,7 +575,23 @@ void function RemoveEntityCallback_OnDamaged( entity ent, void functionref( enti Assert( index != -1, "Requested DamageCallback " + string( callbackFunc ) + " to be removed not found! " ) ent.e.entDamageCallbacks.fastremove( index ) - if ( ent.e.entDamageCallbacks.len() == 0 && ent.e.entPostDamageCallbacks.len() == 0 ) + if ( ent.e.entDamageCallbacks.len() == 0 && ent.e.entFinalDamageCallbacks.len() == 0 && ent.e.entPostDamageCallbacks.len() == 0 ) + ent.SetDamageNotifications( false ) +} + +void function AddEntityCallback_OnFinalDamaged( entity ent, void functionref( entity ent, var damageInfo ) callbackFunc ) +{ + Assert( !ent.e.entFinalDamageCallbacks.contains( callbackFunc ), "Already added " + string( callbackFunc ) + " to entity" ) + + ent.SetDamageNotifications( true ) + ent.e.entFinalDamageCallbacks.append( callbackFunc ) +} + +void function RemoveEntityCallback_OnFinalDamaged( entity ent, void functionref( entity ent, var damageInfo ) callbackFunc ) +{ + ent.e.entFinalDamageCallbacks.fastremovebyvalue( callbackFunc ) + + if ( ent.e.entFinalDamageCallbacks.len() == 0 && ent.e.entPostDamageCallbacks.len() == 0 && ent.e.entDamageCallbacks.len() == 0 ) ent.SetDamageNotifications( false ) } @@ -585,7 +610,7 @@ void function RemoveEntityCallback_OnPostDamaged( entity ent, void functionref( Assert( index != -1, "Requested PostDamageCallback " + string( callbackFunc ) + " to be removed not found! " ) ent.e.entPostDamageCallbacks.fastremove( index ) - if ( ent.e.entPostDamageCallbacks.len() == 0 && ent.e.entDamageCallbacks.len() == 0 ) + if ( ent.e.entPostDamageCallbacks.len() == 0 && ent.e.entDamageCallbacks.len() == 0 && ent.e.entFinalDamageCallbacks.len() == 0 ) ent.SetDamageNotifications( false ) } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_custom_codecallbacks.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_custom_codecallbacks.gnut index 4a7f8189..ee21116d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_custom_codecallbacks.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_custom_codecallbacks.gnut @@ -1,7 +1,10 @@ untyped global function AddCallback_OnReceivedSayTextMessage -global function NSSetupChathooksServer + +// this is global due to squirrel bridge v3 making native not be able to find non-global funcs properly +// temp fix (surely it will get replaced), do not use this function please +global function CServerGameDLL_ProcessMessageStartThread global struct ClServer_MessageStruct { string message @@ -53,7 +56,3 @@ void function AddCallback_OnReceivedSayTextMessage( ClServer_MessageStruct funct { NsCustomCallbacks.OnReceivedSayTextMessageCallbacks.append(callbackFunc) } - -void function NSSetupChathooksServer() { - getroottable().rawset("CServerGameDLL_ProcessMessageStartThread", CServerGameDLL_ProcessMessageStartThread) -} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut index 378ceae3..9dadea15 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut @@ -232,6 +232,7 @@ global struct ServerEntityStruct SpawnPointData spawnPointData array<void functionref( entity ent, var damageInfo )> entDamageCallbacks + array<void functionref( entity ent, var damageInfo )> entFinalDamageCallbacks array<void functionref( entity ent, var damageInfo )> entPostDamageCallbacks array<void functionref( entity titan, entity attacker )> entSegmentLostCallbacks array<void functionref( entity ent, var damageInfo, float actualShieldDamage )> entPostShieldDamageCallbacks diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut index 37b89169..3bdb1d8a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut @@ -1 +1,72 @@ -//fuck
\ No newline at end of file +global function SpawnHarvester +global function generateBeamFX +global function generateShieldFX + +global struct HarvesterStruct { + entity harvester + entity particleBeam + entity particleShield + entity rings + float lastDamage + bool shieldBoost + bool harvesterShieldDown + float harvesterDamageTaken + bool havesterWasDamaged + +} + +HarvesterStruct function SpawnHarvester( vector origin, vector angles, int health, int shieldHealth, int team ) +{ + entity harvester = CreateEntity( "prop_script" ) + harvester.SetValueForModelKey( $"models/props/generator_coop/generator_coop.mdl" ) + harvester.SetOrigin( origin ) + harvester.SetAngles( angles ) + harvester.kv.solid = SOLID_VPHYSICS + + harvester.SetMaxHealth( health ) + harvester.SetHealth( health ) + harvester.SetShieldHealthMax( shieldHealth ) + harvester.SetShieldHealth( shieldHealth ) + harvester.EnableAttackableByAI( 30, 0, AI_AP_FLAG_NONE ) + SetCustomSmartAmmoTarget( harvester, true ) + SetObjectCanBeMeleed( harvester, true ) + SetVisibleEntitiesInConeQueriableEnabled( harvester, true ) + SetTeam(harvester,team) + + DispatchSpawn( harvester ) + + + entity blackbox = CreatePropDynamic( MODEL_HARVESTER_TOWER_COLLISION, origin, angles, 0 ) + blackbox.Hide() + blackbox.Solid() + // blackbox.kv.CollisionGroup = TRACE_COLLISION_GROUP_PLAYER + + entity rings = CreatePropDynamic( MODEL_HARVESTER_TOWER_RINGS, origin, angles, 6 ) + thread PlayAnim( rings, "generator_cycle_fast" ) + + + + HarvesterStruct ret + ret.harvester = harvester + ret.lastDamage = Time() + ret.rings = rings + + return ret +} + +HarvesterStruct function generateBeamFX( HarvesterStruct harvester ) +{ + entity Harvester_Beam = StartParticleEffectOnEntity_ReturnEntity( harvester.harvester, GetParticleSystemIndex( FX_HARVESTER_BEAM ), FX_PATTACH_ABSORIGIN_FOLLOW ,0 ) + EffectSetControlPointVector( Harvester_Beam, 1, GetShieldTriLerpColor( 0.0 ) ) + harvester.particleBeam = Harvester_Beam + Harvester_Beam.DisableHibernation() + return harvester +} + +HarvesterStruct function generateShieldFX( HarvesterStruct harvester ) +{ + entity Harvester_Shield = StartParticleEffectOnEntity_ReturnEntity( harvester.harvester, GetParticleSystemIndex( FX_HARVESTER_OVERSHIELD ), FX_PATTACH_ABSORIGIN_FOLLOW, 0 ) + EffectSetControlPointVector( Harvester_Shield, 1, GetShieldTriLerpColor( 0.0 ) ) + harvester.particleShield = Harvester_Shield + return harvester +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_items.nut b/Northstar.CustomServers/mod/scripts/vscripts/_items.nut index 539b72bc..96623086 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_items.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_items.nut @@ -5698,7 +5698,13 @@ bool function IsUnlockValid( string ref, string parentRef = "" ) bool function IsSubItemLocked( entity player, string ref, string parentRef ) { - if ( DevEverythingUnlocked() ) + if ( DevEverythingUnlocked( player ) ) + return false + + if ( IsItemPurchasableEntitlement( ref, parentRef ) ) + return false + + if ( GetItemType( ref ) == eItemTypes.PRIME_TITAN || GetSubitemType( parentRef, ref ) == eItemTypes.PRIME_TITAN ) return false if ( IsItemInEntitlementUnlock( ref, parentRef ) ) @@ -5817,7 +5823,13 @@ bool function IsSubItemLocked( entity player, string ref, string parentRef ) bool function IsItemLocked( entity player, string ref ) { - if ( DevEverythingUnlocked() ) + if ( DevEverythingUnlocked( player ) ) + return false + + if ( IsItemPurchasableEntitlement( ref ) ) + return false + + if ( GetItemType( ref ) == eItemTypes.PRIME_TITAN ) return false if ( IsItemInEntitlementUnlock( ref ) ) @@ -5906,7 +5918,7 @@ bool function IsItemLockedForEntitlement( entity player, string ref, string pare bool function IsSubItemOwned( entity player, string ref, string parentRef ) { - if ( DevEverythingUnlocked() ) + if ( DevEverythingUnlocked( player ) ) return false Assert( IsValid( player ) ) @@ -5990,7 +6002,7 @@ bool function IsSubItemOwned( entity player, string ref, string parentRef ) bool function IsItemOwned( entity player, string ref ) { - if ( DevEverythingUnlocked() ) + if ( DevEverythingUnlocked( player ) ) return false Assert( IsValid( player ) ) @@ -10082,7 +10094,7 @@ void function InitUnlockAsEntitlement( string itemRef, string parentRef, int ent unlock = file.entitlementUnlocks[fullRef] } - unlock.entitlementIds.append( entitlementId ) + unlock.entitlementIds.append( 1 ) // Using `1` here instead of the huge DLC check I did previously. Having the `1` seems to keep all paid cosmetics unlocked with progression enabled. } array<int> function GetEntitlementIds( string itemRef, string parentRef = "" ) @@ -10219,6 +10231,10 @@ void function StatUnlock_Unlocked( entity player, string itemRef, string parentR if ( IsItemNew( player, itemRef, parentRef ) ) return + // early out if the player has progression disabled + if ( !ProgressionEnabledForPlayer( player ) ) + return + int refGuid = file.itemRefToGuid[itemRef] int parentRefGuid = parentRef == "" ? 0 : file.itemRefToGuid[parentRef] diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut index 3e8ac9ea..141cfe15 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut @@ -51,8 +51,6 @@ void function SvLoadoutsMP_Init() AddClientCommandCallback( "InGameMPMenuClosed", ClientCommandCallback_InGameMPMenuClosed ) AddClientCommandCallback( "LoadoutMenuClosed", ClientCommandCallback_LoadoutMenuClosed ) } - - AddCallback_OnPlayerKilled( DestroyDroppedWeapon ) } void function SetLoadoutGracePeriodEnabled( bool enabled ) @@ -62,20 +60,10 @@ void function SetLoadoutGracePeriodEnabled( bool enabled ) void function SetWeaponDropsEnabled( bool enabled ) { - file.weaponDropsEnabled = enabled -} - -void function DestroyDroppedWeapon( entity victim, entity attacker, var damageInfo ) -{ - if ( !file.weaponDropsEnabled && IsValid( victim.GetActiveWeapon() ) ) - thread DelayDestroyDroppedWeapon( victim.GetActiveWeapon() ) -} - -void function DelayDestroyDroppedWeapon( entity weapon ) -{ - WaitEndFrame() - if ( IsValid( weapon ) ) - weapon.Destroy() + if( enabled ) + FlagSet( "WeaponDropsAllowed" ) + else + FlagClear( "WeaponDropsAllowed" ) } void function AddCallback_OnTryGetTitanLoadout( TryGetTitanLoadoutCallbackType callback ) @@ -179,6 +167,8 @@ bool function ClientCommandCallback_SetPersistentLoadoutValue( entity player, ar if ( args[0] == "pilot" ) SetPlayerLoadoutDirty( player ) + UnlockAchievement( player, achievements.CUSTOMIZE_LOADOUT ) + return true } @@ -191,6 +181,10 @@ bool function ClientCommandCallback_SwapSecondaryAndWeapon3PersistentLoadoutData // get loadout int index = args[0].tointeger() + + if ( !IsValidPilotLoadoutIndex(index) ) + return false + PilotLoadoutDef loadout = GetPilotLoadoutFromPersistentData( player, index ) // swap loadouts @@ -222,7 +216,6 @@ bool function ClientCommandCallback_SetBurnCardPersistenceSlot( entity player, a print( player + " SetBurnCardPersistenceSlot " + args[0] ) - // insecure, could be used to set invalid burnmeterslot potentially if ( IsRefValidAndOfType( args[0], eItemTypes.BURN_METER_REWARD ) ) player.SetPersistentVar( "burnmeterSlot", BurnReward_GetByRef( args[0] ).id ) else diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut index 02be47a4..6499faa2 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut @@ -9,7 +9,7 @@ void function MenuCallbacks_Init() bool function ClientCommandCallback_LeaveMatch( entity player, array<string> args ) { // note: this is imperfect if we have multiple people of the same uid on a server, but that's only a thing in testing - if ( NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) + if ( NSIsPlayerLocalPlayer( player ) ) { if ( GetConVarBool( "ns_should_return_to_lobby" ) && GetMapName() != "mp_lobby" ) { @@ -41,9 +41,11 @@ void function WritePersistenceAndLeaveForLocalPlayerOnly( entity player ) void function WritePersistenceAndLeave( entity player ) { + player.EndSignal( "OnDestroy" ) + // write player persistence before we leave, since leaving player might load local lobby before server writes persistence, so they won't get newest // not super essential, but a nice qol thing - NSEarlyWritePlayerIndexPersistenceForLeave( player.GetPlayerIndex() ) + NSEarlyWritePlayerPersistenceForLeave( player ) while ( NSIsWritingPlayerPersistence() ) WaitFrame() @@ -63,6 +65,8 @@ bool function ClientCommandCallback_GenUp( entity player, array<string> args ) player.GenChanged() player.XPChanged() } + + RegenPersistentLoadouts(player) return true }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_northstar_cheatcommands.nut b/Northstar.CustomServers/mod/scripts/vscripts/_northstar_cheatcommands.nut index c79265ac..af3dfea5 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_northstar_cheatcommands.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_northstar_cheatcommands.nut @@ -14,6 +14,11 @@ bool function ClientCommandCallbackToggleNoclip( entity player, array<string> ar { if ( !GetConVarBool( "sv_cheats" ) ) return true + if( player.GetParent() ) // change movetype while setparented will crash the server + { + print( player + " failed noclipping because the entity is parented" ) + return true + } print( player + " TOGGLED NOCLIP" ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut index c0e69ba5..4e5c5aa9 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut @@ -2127,8 +2127,13 @@ void function EntityDemigod_TryAdjustDamageInfo( entity ent, var damageInfo ) return int bottomLimit = 5 + // Set it up so that you at least take 1 damage, for hit indicators etc to trigger if ( ent.GetHealth() <= bottomLimit ) - ent.SetHealth( bottomLimit + 1 ) //Set it up so that you at least take 1 damage, for hit indicators etc to trigger + { + // Prevent going over max health to avoid a server crash. + int newHealth = bottomLimit + 1 + ent.SetHealth( ent.GetMaxHealth() < newHealth ? ent.GetMaxHealth() : newHealth ) + } int health = ent.GetHealth() @@ -4012,7 +4017,7 @@ int function GameTime_TimeLeftMinutes() if ( GetGameState() == eGameState.Prematch ) return int( ( expect float( GetServerVar( "gameStartTime" ) ) - Time()) / 60.0 ) - return floor( GameTime_TimeLimitMinutes() - GameTime_PlayingTime() / 60 ).tointeger() + return floor( GameTime_PlayingTime() / 60 ).tointeger() } int function GameTime_TimeLeftSeconds() @@ -4020,30 +4025,25 @@ int function GameTime_TimeLeftSeconds() if ( GetGameState() == eGameState.Prematch ) return int( expect float( GetServerVar( "gameStartTime" ) ) - Time() ) - return floor( GameTime_TimeLimitSeconds() - GameTime_PlayingTime() ).tointeger() + return GameTime_PlayingTime().tointeger() } +// WARN: this function includes WaitingForPlayers and Prematch duration! int function GameTime_Seconds() { return floor( Time() ).tointeger() } +// WARN: this function includes WaitingForPlayers Prematch duration! int function GameTime_Minutes() { return int( floor( GameTime_Seconds() / 60 ) ) } +// this function only counts the time limit during eGameState.Playing float function GameTime_PlayingTime() { - return GameTime_PlayingTimeSince( Time() ) -} - -float function GameTime_PlayingTimeSince( float sinceTime ) -{ int gameState = GetGameState() - - // temp fix because i have no fucking clue why this crashes - if ( gameState < eGameState.Playing ) return 0 @@ -4052,17 +4052,15 @@ float function GameTime_PlayingTimeSince( float sinceTime ) if ( gameState > eGameState.SuddenDeath ) return (expect float( GetServerVar( "roundEndTime" ) ) - expect float( GetServerVar( "roundStartTime" ) ) ) else - return sinceTime - expect float( GetServerVar( "roundStartTime" ) ) - + return floor( expect float( GetServerVar( "roundEndTime" ) ) - Time() ) } else { if ( gameState > eGameState.SuddenDeath ) return (expect float( GetServerVar( "gameEndTime" ) ) - expect float( GetServerVar( "gameStartTime" ) ) ) else - return sinceTime - expect float( GetServerVar( "gameStartTime" ) ) + return floor( expect float( GetServerVar( "gameEndTime" ) ) - Time() ) } - unreachable } @@ -4406,4 +4404,4 @@ bool function PlayerHasTitan( entity player ) return true return false -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut b/Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut index c5887f2b..47dd9294 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut @@ -1601,6 +1601,9 @@ float function GetPulseFrac( rate = 1, startTime = 0 ) bool function IsPetTitan( titan ) { Assert( titan.IsTitan() ) + + if ( !titan.GetTitanSoul() ) + return false return titan.GetTitanSoul().GetBossPlayer() != null } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut index 6f044b7a..97d993e6 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut @@ -1,6 +1,7 @@ global function SvXP_Init global function PlayerProgressionAllowed global function HandleXPGainForScoreEvent +global function AddXP void function SvXP_Init() { @@ -15,7 +16,10 @@ void function SetupPlayerPreviousXPValues( entity player ) player.SetPersistentVar( "previousFactionXP[" + xpFaction + "]", FactionGetXP( player, xpFaction ) ) foreach ( string xpTitan in shTitanXP.titanClasses ) + { player.SetPersistentVar( "previousTitanXP[" + xpTitan + "]", TitanGetXP( player, xpTitan ) ) + player.SetPersistentVar( "fdPreviousTitanXP[" + xpTitan + "]", FD_TitanGetXP( player, xpTitan ) ) + } foreach ( string xpWeapon in shWeaponXP.weaponClassNames ) player.SetPersistentVar( GetItemPersistenceStruct( xpWeapon ) + ".previousWeaponXP", WeaponGetXP( player, xpWeapon ) ) @@ -29,46 +33,51 @@ bool function PlayerProgressionAllowed( entity player ) void function HandleXPGainForScoreEvent( entity player, ScoreEvent event ) { // note: obviously all xp stuff can be cheated in if people want to on customs, this is mainly just here for fun for those who want it and feature completeness - // most score events don't have this, so we'll set this to the xp value of other categories later if needed + int xpValue = ScoreEvent_GetXPValue( event ) int weaponXp = ScoreEvent_GetXPValueWeapon( event ) int titanXp = ScoreEvent_GetXPValueTitan( event ) - - if ( xpValue < weaponXp ) - xpValue = weaponXp - else if ( xpValue < titanXp ) - xpValue = titanXp + int factionXp = ScoreEvent_GetXPValueFaction( event ) + + if ( player.GetPlayerNetInt( "xpMultiplier" ) > 0 || GetCurrentPlaylistVarInt( "double_xp_enabled", 0 ) == 1 ) + { + xpValue *= 2 + weaponXp *= 2 + titanXp *= 2 + factionXp *= 2 + } entity weapon = player.GetActiveWeapon() - if ( IsValid( weapon ) && ShouldTrackXPForWeapon( weapon.GetWeaponClassName() ) ) - AddWeaponXP( player, xpValue ) + if ( IsValid( weapon ) && ShouldTrackXPForWeapon( weapon.GetWeaponClassName() ) && weaponXp != 0 ) + AddWeaponXP( player, weaponXp ) // if we specifically gain titan xp, then give titan xp no matter what, otherwise only give it when we're in a titan - if ( titanXp != 0 || player.IsTitan() ) - AddTitanXP( player, xpValue ) - - // most events don't have faction xp but almost everything should give it - int factionXp = ScoreEvent_GetXPValueFaction( event ) - if ( xpValue > factionXp ) - factionXp = xpValue - else if ( xpValue < factionXp ) - xpValue = factionXp + if ( titanXp != 0 ) + AddTitanXP( player, titanXp ) if ( factionXp != 0 ) AddFactionXP( player, factionXp ) - if ( xpValue == 0 ) - return - // global xp + if ( xpValue != 0 ) + AddXP( player, xpValue ) +} + +void function AddXP( entity player, int amount ) +{ int oldXp = player.GetPersistentVarAsInt( "xp" ) - if(oldXp<0) oldXp = 0 + if( oldXp < 0 ) oldXp = 0 int oldLevel = GetLevelForXP( oldXp ) - player.SetPersistentVar( "xp", min( oldXp + xpValue, PlayerGetMaxXPPerGen() ) ) + player.SetPersistentVar( "xp", min( oldXp + amount, PlayerGetMaxXPPerGen() ) ) player.XPChanged() // network xp change to client, gen can't change here int newXp = player.GetPersistentVarAsInt( "xp" ) int newLevel = GetLevelForXP( newXp ) if ( newLevel != oldLevel ) + { Remote_CallFunction_NonReplay( player, "ServerCallback_PlayerLeveledUp", player.GetPersistentVarAsInt( "gen" ), newLevel ) -}
\ No newline at end of file + + if( ProgressionEnabledForPlayer( player ) ) + AwardRandomItemsForPlayerLevels( player, player.GetPersistentVarAsInt( "gen" ), newLevel ) + } +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut index 9717c76d..89fb7a82 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut @@ -60,6 +60,19 @@ function AiSoldiers_Init() level.COOP_AT_WEAPON_RATES[ "mp_weapon_smr" ] <- 0.4 level.COOP_AT_WEAPON_RATES[ "mp_weapon_mgl" ] <- 0.1 + // add stub death callback, because in _codecallbacks_common.gnut there is + // CodeCallback_OnEntityKilled which is only called when an entity is being tracked. An + // entity is set to be tracked if it has a death callback for it's class, unfortunately this + // is then relayed to clients and used for client side death callbacks. The end result of + // not having this function called is that clients become completely unaware of any grunt + // deaths. A noticeable difference here is that grunts do not play the kill confirmed audio + // except on War Games, which does register a callback for grunt deaths to make them dissolve. + // + // Whilst this may seem like a bit of a hacky solution, it is generally better than simply + // tracking all entities. If a different callback is created in the future for grunt deaths + // that is not specific to a gamemode, map, etc. then this could be removed + AddDeathCallback( "npc_soldier", void function( entity guy, var damageInfo ){} ) + PrecacheSprite( $"sprites/glow_05.vmt" ) FlagInit( "disable_npcs" ) FlagInit( "Disable_IMC" ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut index afa8ff3d..107a3f7f 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut @@ -15,8 +15,10 @@ global function InitBurnMeterPersistentData const float PHASE_REWIND_LENGTH = 2.0
// taken from wraith portal in apex, assuming it's the same as tf2's
-const float PHASE_REWIND_PATH_SNAPSHOT_INTERVAL = 0.1
-const int PHASE_REWIND_MAX_SNAPSHOTS = int( PHASE_REWIND_LENGTH / PHASE_REWIND_PATH_SNAPSHOT_INTERVAL )
+// 0.1 can be too fast for ttf2 scripts
+const float PHASE_REWIND_PATH_SNAPSHOT_INTERVAL = 0.2 // mainly controlled by this const, the higher the rewind path will be longer, assuming this one is like vanilla's
+const int PHASE_REWIND_MAX_SNAPSHOTS = int( PHASE_REWIND_LENGTH / PHASE_REWIND_PATH_SNAPSHOT_INTERVAL ) - 1
+const int PHASE_REWIND_DATA_MAX_POSITIONS = int( PHASE_REWIND_LENGTH * 10 ) + 1 // hardcoded but maybe good
const float AMPED_WEAPONS_LENGTH = 30.0
@@ -216,18 +218,18 @@ void function PhaseRewindLifetime( entity player ) {
PhaseRewindData rewindData
rewindData.origin = player.GetOrigin()
- rewindData.angles = player.GetAngles()
+ rewindData.angles = < 0, player.EyeAngles().y, 0 >
rewindData.velocity = player.GetVelocity()
rewindData.wasInContextAction = player.ContextAction_IsActive()
rewindData.wasCrouched = player.IsCrouched()
- if ( player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions.len() >= PHASE_REWIND_MAX_SNAPSHOTS )
+ if ( player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions.len() >= PHASE_REWIND_DATA_MAX_POSITIONS )
{
// shift all snapshots left
- for ( int i = 0; i < PHASE_REWIND_MAX_SNAPSHOTS - 1; i++ )
+ for ( int i = 0; i < PHASE_REWIND_DATA_MAX_POSITIONS - 1; i++ )
player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ i ] = player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ i + 1 ]
- player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ PHASE_REWIND_MAX_SNAPSHOTS - 1 ] = rewindData
+ player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions[ PHASE_REWIND_DATA_MAX_POSITIONS - 1 ] = rewindData
}
else
player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions.append( rewindData )
@@ -257,7 +259,9 @@ void function UseBurnCardWeapon( entity weapon, entity player ) if ( PlayerEarnMeter_IsRewardAvailable( player ) )
PlayerEarnMeter_SetRewardUsed( player )
- PlayerInventory_PopInventoryItem( player )
+ thread PlayerInventory_PopInventoryItem( player )
+
+ UpdatePlayerStat( player, "misc_stats", "boostsActivated" )
}
void function UseBurnCardWeaponInCriticalSection( entity weapon, entity ownerPlayer )
@@ -287,10 +291,14 @@ void function InitBurnMeterPersistentData( entity player ) void function PlayerUsesAmpedWeaponsBurncard( entity player )
{
thread PlayerUsesAmpedWeaponsBurncardThreaded( player )
+
}
void function PlayerUsesAmpedWeaponsBurncardThreaded( entity player )
{
+ player.Signal( "StopAmpedWeapons" )
+ player.EndSignal("StopAmpedWeapons")
+
array<entity> weapons = player.GetMainWeapons()
//weapons.extend( player.GetOffhandWeapons() ) // idk? unsure of vanilla behaviour here
foreach ( entity weapon in weapons )
@@ -403,6 +411,10 @@ void function PlayerUsesMaphackBurncardThreaded( entity player ) entities.extend( GetPlayerDecoyArray() )
IncrementSonarPerTeam( playerTeam )
+
+ if ( IsAlive( player ) ) // only owner can see the pulse
+ Remote_CallFunction_Replay( player, "ServerCallback_SonarPulseFromPosition", player.GetOrigin().x, player.GetOrigin().y, player.GetOrigin().z, SONAR_GRENADE_RADIUS )
+
foreach ( entity ent in entities )
{
if ( !IsValid( ent ) ) // Not sure why we can get invalid entities at this point
@@ -410,9 +422,6 @@ void function PlayerUsesMaphackBurncardThreaded( entity player ) if ( ent.IsPlayer() )
{
- if ( IsAlive( player ) )
- Remote_CallFunction_Replay( ent, "ServerCallback_SonarPulseFromPosition", player.GetOrigin().x, player.GetOrigin().y, player.GetOrigin().z, SONAR_GRENADE_RADIUS )
-
// Map Hack also gives radar on enemies for longer than the sonar duration.
if ( ent.GetTeam() == playerTeam )
thread ScanMinimap( ent, false, MAPHACK_PULSE_DELAY - 0.2 )
@@ -466,18 +475,65 @@ void function PlayerUsesPhaseRewindBurncardThreaded( entity player ) array<PhaseRewindData> positions = clone player.p.burnCardPhaseRewindStruct.phaseRetreatSavedPositions
+ array<PhaseRewindData> tempArray
+ int segment = positions.len() / PHASE_REWIND_MAX_SNAPSHOTS
+ for( int i = 0; i < PHASE_REWIND_MAX_SNAPSHOTS; i++ )
+ {
+ if( positions.len() <= segment * i )
+ break
+ tempArray.append( positions[ segment * i ] )
+ }
+ positions = tempArray
+
+ vector startOrigin = player.GetOrigin()
ViewConeZero( player )
player.HolsterWeapon()
player.SetPredictionEnabled( false )
PhaseShift( player, 0.0, positions.len() * PHASE_REWIND_PATH_SNAPSHOT_INTERVAL * 1.5 )
+ EmitSoundOnEntityOnlyToPlayer( player, player, "pilot_phaserewind_1p" )
+ EmitSoundOnEntityExceptToPlayer( player, player, "pilot_phaserewind_3p" )
for ( int i = positions.len() - 1; i > -1; i-- )
{
- mover.NonPhysicsMoveTo( positions[ i ].origin, PHASE_REWIND_PATH_SNAPSHOT_INTERVAL, 0, 0 )
- mover.NonPhysicsRotateTo( positions[ i ].angles, PHASE_REWIND_PATH_SNAPSHOT_INTERVAL, 0, 0 )
+ // should looks better?
+ float moveTime = PHASE_REWIND_PATH_SNAPSHOT_INTERVAL + 0.1
+ player.SetVelocity( -positions[ i ].velocity )
+ mover.NonPhysicsMoveTo( positions[ i ].origin, moveTime, 0, 0 )
+ mover.NonPhysicsRotateTo( positions[ i ].angles, moveTime, 0, 0 )
wait PHASE_REWIND_PATH_SNAPSHOT_INTERVAL
}
player.SetVelocity( <0, 0, 0> )
+ if( positions[0].wasCrouched )
+ player.SetOrigin( player.GetOrigin() + < 0, 0, 20 > )
+
+ // fix position after rewind
+ PutPhaseRewindedPlayerInSafeSpot( player, 1 )
+}
+
+void function PutPhaseRewindedPlayerInSafeSpot( entity player, int severity )
+{
+ vector baseOrigin = player.GetOrigin()
+
+ if ( PutEntityInSafeSpot( player, player, null, < baseOrigin.x, baseOrigin.y + severity, baseOrigin.z >, baseOrigin ) )
+ return
+
+ if ( PutEntityInSafeSpot( player, player, null, < baseOrigin.x, baseOrigin.y - severity, baseOrigin.z >, baseOrigin ) )
+ return
+
+ if ( PutEntityInSafeSpot( player, player, null, < baseOrigin.x + severity, baseOrigin.y, baseOrigin.z >, baseOrigin ) )
+ return
+
+ if ( PutEntityInSafeSpot( player, player, null, < baseOrigin.x - severity, baseOrigin.y, baseOrigin.z >, baseOrigin ) )
+ return
+
+ if ( PutEntityInSafeSpot( player, player, null, < baseOrigin.x, baseOrigin.y, baseOrigin.z + severity >, baseOrigin ) )
+ return
+
+ if ( PutEntityInSafeSpot( player, player, null, < baseOrigin.x, baseOrigin.y, baseOrigin.z - severity >, baseOrigin ) )
+ return
+
+ return PutPhaseRewindedPlayerInSafeSpot( player, severity + 5 )
+
}
void function PlayerUsesNukeTitanBurncard( entity player )
@@ -559,4 +615,4 @@ void function PlayerUsesReaperfallBurncard( entity player ) DispatchSpawn( reaper )
thread SuperSpectre_WarpFall( reaper )
-}
\ No newline at end of file +}
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut index b9f8f7eb..19c6b6df 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut @@ -328,6 +328,26 @@ function CodeCallback_RegisterClass_CPlayer() } } } + + function CPlayer::GetUserInfoString( key, defaultValue = "" ) + { + return GetUserInfoKVString_Internal( this, key, defaultValue ) + } + + function CPlayer::GetUserInfoInt( key, defaultValue = 0 ) + { + return GetUserInfoKVInt_Internal( this, key, defaultValue ) + } + + function CPlayer::GetUserInfoFloat( key, defaultValue = 0 ) + { + return GetUserInfoKVFloat_Internal( this, key, defaultValue ) + } + + function CPlayer::GetUserInfoBool( key, defaultValue = false ) + { + return GetUserInfoKVBool_Internal( this, key, defaultValue ) + } } void function PlayerDropsScriptedItems( entity player ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut index 1a70c289..4eb423fd 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut @@ -1,11 +1,33 @@ global function GruntChatter_MP_Init global function PlayGruntChatterMPLine +const float CHATTER_FRIENDLY_GRUNT_DOWN_DIST_MAX = 1100.0 +const float CHATTER_SQUAD_DEPLETED_FRIENDLY_NEARBY_DIST = 650.0 // if any other friendly grunt is within this dist, squad deplete chatter won't play +const float CHATTER_ENEMY_TITAN_DOWN_DIST_MAX = 1500.0 +const float CHATTER_NEARBY_GRUNT_TRACEFRAC_MIN = 0.95 // for when we need "LOS" trace + void function GruntChatter_MP_Init() { - //ShGruntChatter_MP_Init() + Assert( IsMultiplayer(), "MP Grunt chatter is restricted to Multiplayer only." ) + + AddCallback_OnPlayerKilled( GruntChatter_OnPlayerOrNPCKilled ) + AddCallback_OnNPCKilled( GruntChatter_OnPlayerOrNPCKilled ) } + + + +/*===================================================================================================================================================== + _____ _ _____ _ _ _ __ __ _ _ _ _ + / ____| | | / ____|| | | | | | | \/ | | || | (_) | | + | | __ _ __ _ _ _ __ | |_ | | | |__ __ _ | |_ | |_ ___ _ __ | \ / | _ _ | || |_ _ _ __ | | __ _ _ _ ___ _ __ + | | |_ || '__|| | | || '_ \ | __| | | | '_ \ / _` || __|| __|/ _ \| '__| | |\/| || | | || || __|| || '_ \ | | / _` || | | | / _ \| '__| + | |__| || | | |_| || | | || |_ | |____ | | | || (_| || |_ | |_| __/| | | | | || |_| || || |_ | || |_) || || (_| || |_| || __/| | + \_____||_| \__,_||_| |_| \__| \_____||_| |_| \__,_| \__| \__|\___||_| |_| |_| \__,_||_| \__||_|| .__/ |_| \__,_| \__, | \___||_| + | | __/ | + |_| |___/ +/*===================================================================================================================================================*/ + void function PlayGruntChatterMPLine( entity grunt, string conversationType ) { #if !GRUNT_CHATTER_MP_ENABLED @@ -15,4 +37,175 @@ void function PlayGruntChatterMPLine( entity grunt, string conversationType ) foreach ( entity player in GetPlayerArray() ) if ( ShouldPlayGruntChatterMPLine( conversationType, player, grunt ) ) Remote_CallFunction_Replay( player, "ServerCallback_PlayGruntChatterMP", GetConversationIndex( conversationType ), grunt.GetEncodedEHandle() ) +} + +void function GruntChatter_OnPlayerOrNPCKilled( entity deadGuy, entity attacker, var damageInfo ) +{ + if ( !IsValid( deadGuy ) || !IsValid( attacker ) ) + return + + if( IsGrunt( attacker ) && IsPilot( deadGuy ) ) + PlayGruntChatterMPLine( attacker, "bc_killenemypilot" ) + else + GruntChatter_TryEnemyTitanDown( deadGuy ) + + if ( IsGrunt( deadGuy ) ) + { + GruntChatter_TryFriendlyDown( deadGuy ) + GruntChatter_TrySquadDepleted( deadGuy ) + } +} + +void function GruntChatter_TryFriendlyDown( entity deadGuy ) +{ + entity closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( deadGuy.GetOrigin(), deadGuy.GetTeam(), CHATTER_FRIENDLY_GRUNT_DOWN_DIST_MAX ) + if ( !closestGrunt ) + return + + if ( !GruntChatter_CanGruntChatterNow( closestGrunt ) ) + return + + PlayGruntChatterMPLine( closestGrunt, "bc_allygruntdown" ) +} + +void function GruntChatter_TrySquadDepleted( entity deadGuy ) +{ + string deadGuySquadName = expect string( deadGuy.kv.squadname ) + if ( deadGuySquadName == "" ) + return + + array<entity> squad = GetNPCArrayBySquad( deadGuySquadName ) + entity lastSquadMember + if ( squad.len() == 1 ) + lastSquadMember = squad[0] + + if ( !GruntChatter_CanGruntChatterNow( lastSquadMember ) ) + return + + if ( lastSquadMember.GetNPCState() == "idle" ) + return + + // if another grunt from another squad is nearby, don't chatter about being alone + array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( lastSquadMember.GetOrigin(), lastSquadMember.GetTeam(), CHATTER_SQUAD_DEPLETED_FRIENDLY_NEARBY_DIST ) + nearbyGrunts.fastremovebyvalue( lastSquadMember ) + if ( nearbyGrunts.len() ) + return + + PlayGruntChatterMPLine( lastSquadMember, "bc_squaddeplete" ) +} + +void function GruntChatter_TryEnemyTitanDown( entity deadGuy ) +{ + if ( deadGuy.IsTitan() ) + { + entity closestGrunt = GruntChatter_FindClosestEnemyHumanGrunt_LOS( deadGuy.GetOrigin(), deadGuy.GetTeam(), CHATTER_ENEMY_TITAN_DOWN_DIST_MAX ) + if ( !closestGrunt ) + return + + PlayGruntChatterMPLine( closestGrunt, "bc_enemytitandown" ) + } +} + +entity function GruntChatter_FindClosestEnemyHumanGrunt_LOS( vector searchOrigin, int enemyTeam, float searchDist ) +{ + array<entity> humanGrunts = GetNearbyEnemyHumanGrunts( searchOrigin, enemyTeam, searchDist ) + return GruntChatter_GetClosestGrunt_LOS( humanGrunts, searchOrigin ) +} + +entity function GruntChatter_FindClosestFriendlyHumanGrunt_LOS( vector searchOrigin, int friendlyTeam, float searchDist ) +{ + array<entity> humanGrunts = GetNearbyFriendlyHumanGrunts( searchOrigin, friendlyTeam, searchDist ) + return GruntChatter_GetClosestGrunt_LOS( humanGrunts, searchOrigin ) +} + +entity function GruntChatter_GetClosestGrunt_LOS( array<entity> nearbyGrunts, vector searchOrigin ) +{ + entity closestGrunt = null + float closestDist = 10000 + + foreach ( grunt in nearbyGrunts ) + { + vector gruntOrigin = grunt.GetOrigin() + + // CanSee doesn't return true if the target is dead + if ( !GruntChatter_CanGruntTraceToLocation( grunt, searchOrigin ) ) + continue + + if ( !closestGrunt ) + { + closestGrunt = grunt + continue + } + + float distFromSearchOrigin = Distance( grunt.GetOrigin(), searchOrigin ) + + if ( closestDist > distFromSearchOrigin ) + continue + + closestGrunt = grunt + closestDist = distFromSearchOrigin + } + + return closestGrunt +} + +bool function GruntChatter_CanGruntTraceToLocation( entity grunt, vector traceEnd ) +{ + float traceFrac = TraceLineSimple( grunt.GetOrigin(), traceEnd, grunt ) + return traceFrac > CHATTER_NEARBY_GRUNT_TRACEFRAC_MIN +} + +array<entity> function GetNearbyFriendlyHumanGrunts( vector searchOrigin, int friendlyTeam, float ornull searchRange = null ) +{ + array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( searchOrigin, friendlyTeam, searchRange ) + array<entity> humanGrunts = [] + foreach ( grunt in nearbyGrunts ) + { + if ( grunt.IsMechanical() ) + continue + + humanGrunts.append( grunt ) + } + + return humanGrunts +} + +array<entity> function GetNearbyEnemyHumanGrunts( vector searchOrigin, int enemyTeam, float ornull searchRange = null ) +{ + array<entity> nearbyGrunts = GetNearbyEnemyGrunts( searchOrigin, enemyTeam, searchRange ) + array<entity> humanGrunts = [] + foreach ( grunt in nearbyGrunts ) + { + if ( grunt.IsMechanical() ) + continue + + humanGrunts.append( grunt ) + } + + return humanGrunts +} + +bool function GruntChatter_CanGruntChatterNow( entity grunt ) +{ + if ( !IsAlive( grunt ) ) + return false + + if ( !GruntChatter_IsGruntTypeEligibleForChatter( grunt ) ) + return false + + if ( grunt.ContextAction_IsMeleeExecution() ) + return false + + string squadname = expect string( grunt.kv.squadname ) + // we only care about this because the grunt conversation system wants it + return squadname != "" +} + +bool function GruntChatter_IsGruntTypeEligibleForChatter( entity grunt ) +{ + if ( !IsGrunt( grunt ) ) + return false + + // mechanical grunts don't chatter + return !grunt.IsMechanical() }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut index dda84976..b4e77375 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut @@ -315,12 +315,12 @@ void function PlayerEarnMeter_Empty( entity player ) PlayerEarnMeter_SetRewardFrac( player, 0.0 ) } - void function EarnMeterDecayThink( entity player ) { player.EndSignal( "OnDeath" ) player.Signal( "EarnMeterDecayThink" ) player.EndSignal( "EarnMeterDecayThink" ) + thread OverDriveClearOnDeath( player ) if ( EarnMeter_DecayHold() < 0 ) return @@ -348,6 +348,12 @@ void function EarnMeterDecayThink( entity player ) } } +void function OverDriveClearOnDeath( entity player ) +{ + player.EndSignal( "OnDestroy" ) + player.WaitSignal( "OnDeath" ) + PlayerEarnMeter_SetEarnedFrac( player, PlayerEarnMeter_GetOwnedFrac( player ) ) +} bool function PlayerEarnMeter_TryMakeGoalAvailable( entity player ) { diff --git a/Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut b/Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut index bce8b4c7..760daef0 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut @@ -69,11 +69,21 @@ struct { entity evacIcon } file +struct EvacShipSetting +{ + asset shipModel + string flyinSound + string hoverSound + string flyoutSound +} + void function Evac_Init() { EvacShared_Init() RegisterSignal( "EvacShipLeaves" ) RegisterSignal( "EvacOver" ) + + PrecacheParticleSystem( FX_EVAC_MARKER ) } void function AddEvacNode( entity evacNode ) @@ -100,7 +110,7 @@ void function EvacEpilogueSetup() void function EvacEpilogue() { - int winner = GetWinningTeam() + int winner = GetWinningTeam() // make sure we don't run evac if it won't be supported for current map/gamestate bool canRunEvac = GetCurrentPlaylistVarInt( "max_teams", 2 ) == 2 && @@ -110,6 +120,10 @@ void function EvacEpilogue() if ( canRunEvac ) { thread SetRespawnAndWait( false ) + + // no players can evac? end match + thread CheckIfAnyPlayerLeft( GetOtherTeam( winner ) ) + thread Evac( GetOtherTeam( winner ), EVAC_INITIAL_WAIT, EVAC_ARRIVAL_TIME, EVAC_WAIT_TIME, EvacEpiloguePlayerCanBoard, EvacEpilogueShouldLeaveEarly, EvacEpilogueCompleted ) } else @@ -139,6 +153,10 @@ void function SetRespawnAndWait( bool mode ) { wait GAME_EPILOGUE_PLAYER_RESPAWN_LEEWAY SetRespawnsEnabled( mode ) + + // clear any respawn availablity, or players are able to save there respawn for whenever they want + foreach( entity player in GetPlayerArray() ) + ClearRespawnAvailable( player ) } bool function EvacEpiloguePlayerCanBoard( entity dropship, entity player ) @@ -174,12 +192,16 @@ void function EvacEpilogueCompleted( entity dropship ) ScreenFadeToBlackForever( player, 2.0 ) wait 2.0 - SetGameState( eGameState.Postmatch ) + if( GetGameState() != eGameState.Postmatch ) + SetGameState( eGameState.Postmatch ) } // global evac func, anything can call this, it's not necessarily an epilogue thing void function Evac( int evacTeam, float initialWait, float arrivalTime, float waitTime, bool functionref( entity, entity ) canBoardCallback, bool functionref( entity ) shouldLeaveEarlyCallback, void functionref( entity ) completionCallback, entity customEvacNode = null ) { + // get evac ship sound and model for specific team + EvacShipSetting evacShip = GetEvacShipSettingByTeam( evacTeam ) + wait initialWait // setup evac nodes if not manually registered @@ -212,23 +234,39 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa DispatchSpawn( file.evacIcon ) file.evacIcon.DisableHibernation() + // start evac beam + int index = GetParticleSystemIndex( FX_EVAC_MARKER ) + + entity effectFriendly = StartParticleEffectInWorld_ReturnEntity( index, evacNode.GetOrigin(), < 0,0,0 > ) + SetTeam( effectFriendly, evacTeam ) + effectFriendly.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY + wait 0.5 // need to wait here, or the target won't appear on clients for some reason // eta until arrive SetTeamActiveObjective( evacTeam, "EG_DropshipExtract", Time() + arrivalTime, file.evacIcon ) SetTeamActiveObjective( GetOtherTeam( evacTeam ), "EG_StopExtract", Time() + arrivalTime, file.evacIcon ) + foreach( entity player in GetPlayerArrayOfTeam( evacTeam ) ) //Show the Evac Match Goal for players of the team that lost the match + Remote_CallFunction_UI( player, "SCB_SetEvacMeritState", 0 ) + // would've liked to use cd_dropship_rescue_side_start length here, but can't since this is done before dropship spawn, can't wait arrivalTime - 4.33333 entity dropship = CreateDropship( evacTeam, evacNode.GetOrigin(), evacNode.GetAngles() ) - dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) - dropship.SetValueForModelKey( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + + thread DropShipTempHide( dropship ) // prevent showing model and health bar on spawn + dropship.SetModel( evacShip.shipModel ) + dropship.SetValueForModelKey( evacShip.shipModel ) + dropship.SetMaxHealth( EVAC_SHIP_HEALTH ) dropship.SetHealth( EVAC_SHIP_HEALTH ) dropship.SetShieldHealth( EVAC_SHIP_SHIELDS ) SetTargetName( dropship, "#NPC_EVAC_DROPSHIP" ) DispatchSpawn( dropship ) - dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + + // reduce nuclear core's damage + AddEntityCallback_OnDamaged( dropship, EvacDropshipDamaged ) + AddEntityCallback_OnKilled( dropship, EvacDropshipKilled ) dropship.s.evacSlots <- [ null, null, null, null, null, null, null, null ] @@ -241,9 +279,15 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa dropship.s.evacTrigger.Destroy() // this should be for both teams - SetTeamActiveObjective( evacTeam, "EG_DropshipExtractDropshipDestroyed" ) - SetTeamActiveObjective( GetOtherTeam( evacTeam ), "EG_DropshipExtractDropshipDestroyed" ) - + if( !IsValid( dropship ) ) + { + SetTeamActiveObjective( evacTeam, "EG_DropshipExtractDropshipDestroyed" ) + SetTeamActiveObjective( GetOtherTeam( evacTeam ), "EG_DropshipExtractDropshipDestroyed" ) + + foreach( entity player in GetPlayerArrayOfTeam( evacTeam ) ) + SetPlayerChallengeEvacState( player, 0 ) + } + foreach ( entity player in dropship.s.evacSlots ) { if ( !IsValid( player ) ) @@ -255,10 +299,14 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa // this is called whether dropship is destroyed or evac finishes, callback can handle this itself thread completionCallback( dropship ) }) - + // flyin Spectator_SetCustomSpectatorFunc( EvacSpectatorFunc ) thread PlayAnim( dropship, "cd_dropship_rescue_side_start", evacNode ) + + // fly in sound and effect + EmitSoundOnEntity( dropship, evacShip.flyinSound ) + thread WarpInEffectEvacShip( dropship ) // calculate time until idle start float sequenceDuration = dropship.GetSequenceDuration( "cd_dropship_rescue_side_start" ) @@ -266,11 +314,22 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa wait sequenceDuration * cycleFrac thread PlayAnim( dropship, "cd_dropship_rescue_side_idle", evacNode ) + + // hover sound + EmitSoundOnEntity( dropship, evacShip.hoverSound ) // eta until leave - SetTeamActiveObjective( evacTeam, "EG_DropshipExtract2", Time() + EVAC_WAIT_TIME, file.evacIcon ) - SetTeamActiveObjective( GetOtherTeam( evacTeam ), "EG_StopExtract2", Time() + EVAC_WAIT_TIME, file.evacIcon ) + SetTeamActiveObjective( evacTeam, "EG_DropshipExtract2", Time() + waitTime, file.evacIcon ) + SetTeamActiveObjective( GetOtherTeam( evacTeam ), "EG_StopExtract2", Time() + waitTime, file.evacIcon ) + // dialogue + PlayFactionDialogueToTeam( "mp_evacGo", evacTeam ) + PlayFactionDialogueToTeam( "mp_evacStop", GetOtherTeam( evacTeam ) ) + + // stop evac beam + if( IsValid( effectFriendly ) ) + EffectStop( effectFriendly ) + // setup evac trigger entity trigger = CreateEntity( "trigger_cylinder" ) trigger.SetRadius( 150 ) @@ -298,6 +357,10 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa WaitFrame() } + + // fly out sound + StopSoundOnEntity( dropship, evacShip.hoverSound ) + EmitSoundOnEntity( dropship, evacShip.flyoutSound ) // holster all weapons foreach ( entity player in dropship.s.evacSlots ) @@ -320,6 +383,12 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa Remote_CallFunction_NonReplay( player, "ServerCallback_PlayScreenFXWarpJump" ) wait WARPINFXTIME + + dropship.kv.VisibilityFlags = 0 // prevent jetpack trails being like "dive" into ground + WaitFrame() // better wait because we are server + if( !IsValid( dropship ) ) + return + thread __WarpOutEffectShared( dropship ) // go to space @@ -339,24 +408,64 @@ void function Evac( int evacTeam, float initialWait, float arrivalTime, float wa if ( !PlayerInDropship( player, dropship ) ) { if ( player.GetTeam() == dropship.GetTeam() ) + { SetPlayerActiveObjective( player, "EG_DropshipExtractFailedEscape" ) + SetPlayerChallengeEvacState( player, 2 ) + } continue } SetPlayerActiveObjective( player, "EG_DropshipExtractSuccessfulEscape" ) + + // let evacing team able to see the ship again + dropship.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY // skybox player.SetSkyCamera( GetEnt( SKYBOXSPACE ) ) Remote_CallFunction_NonReplay( player, "ServerCallback_DisableHudForEvac" ) Remote_CallFunction_NonReplay( player, "ServerCallback_SetClassicSkyScale", dropship.GetEncodedEHandle(), 0.7 ) Remote_CallFunction_NonReplay( player, "ServerCallback_SetMapSettings", 4.0, false, 0.4, 0.125 ) + SetPlayerChallengeEvacState( player, 1 ) // display player [Evacuated] in killfeed foreach ( entity otherPlayer in GetPlayerArray() ) Remote_CallFunction_NonReplay( otherPlayer, "ServerCallback_EvacObit", player.GetEncodedEHandle() ) } - + + // award player score to evacing team + int evacCount = 0 + array<entity> evacingPlayers = GetPlayerArrayOfTeam( dropship.GetTeam() ) // all players that are supposed to evac in the dropship + + // count how many players are in the dropship + foreach ( entity player in evacingPlayers ) + { + if ( !PlayerInDropship( player, dropship ) ) + continue + + evacCount++ + } + + bool allEvac = evacCount == evacingPlayers.len() + + foreach(entity player in evacingPlayers) + { + if ( !PlayerInDropship( player, dropship ) ) + continue + + AddPlayerScore( player, "HotZoneExtract" ) + UpdatePlayerStat( player, "misc_stats", "evacsSurvived" ) + + if ( allEvac ) + AddPlayerScore( player, "TeamBonusFullEvac" ) + } + + // sole survivor (but not the only one on the team) + if ( evacCount == 1 && !allEvac ) + { + // we can assume there is one player in the array because otherwise evacCount wouldn't be 1 + AddPlayerScore( evacingPlayers[0], "SoleSurvivor" ) + } } void function AddPlayerToEvacDropship( entity dropship, entity player ) @@ -376,7 +485,12 @@ void function AddPlayerToEvacDropship( entity dropship, entity player ) // no slots available if ( !PlayerInDropship( player, dropship ) ) return - + + UpdatePlayerStat( player, "misc_stats", "evacsAttempted" ) + + // need to cancel if the dropship dies + dropship.EndSignal( "OnDeath", "OnDestroy" ) + player.SetInvulnerable() player.UnforceCrouch() player.ForceStand() @@ -391,7 +505,7 @@ void function AddPlayerToEvacDropship( entity dropship, entity player ) EmitSoundOnEntityOnlyToPlayer( player, player, SHIFTER_START_SOUND_3P ) // should play SHIFTER_START_SOUND_1P when they actually arrive in the ship i think, unsure how this is supposed to be done PlayPhaseShiftDisappearFX( player ) - waitthread FirstPersonSequence( fp, player, dropship ) + FirstPersonSequence( fp, player, dropship ) FirstPersonSequenceStruct idleFp idleFp.firstPersonAnimIdle = EVAC_IDLE_ANIMS_1P[ slot ] @@ -426,3 +540,97 @@ void function EvacDropshipKilled( entity dropship, var damageInfo ) } } } + +// if there's no player left in evacing team, we end this match +void function CheckIfAnyPlayerLeft( int evacTeam ) +{ + wait GAME_EPILOGUE_PLAYER_RESPAWN_LEEWAY + float startTime = Time() + + OnThreadEnd( + function() : ( evacTeam ) + { + SetTeamActiveObjective( evacTeam, "EG_DropshipExtractEvacPlayersKilled" ) + SetTeamActiveObjective( GetOtherTeam( evacTeam ), "EG_StopExtractEvacPlayersKilled" ) + thread EvacEpilogueCompleted( null ) + + // score for killing the entire evacing team + foreach ( entity player in GetPlayerArray() ) + { + if ( player.GetTeam() == evacTeam ) + continue + + AddPlayerScore( player, "TeamBonusKilledAll") + } + } + ) + while( true ) + { + if( GetPlayerArrayOfTeam_Alive( evacTeam ).len() == 0 ) + break + if( GetGameState() == eGameState.Postmatch ) + return + WaitFrame() + } +} + +void function DropShipTempHide( entity dropship ) +{ + dropship.kv.VisibilityFlags = 0 // or it will still shows the jetpack fxs + HideName( dropship ) + wait 0.46 + if( IsValid( dropship ) ) + { + dropship.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE + ShowName( dropship ) + } +} + +EvacShipSetting function GetEvacShipSettingByTeam( int team ) +{ + EvacShipSetting tempSetting + tempSetting.shipModel = $"models/vehicle/goblin_dropship/goblin_dropship_hero.mdl" + tempSetting.flyinSound = "Goblin_IMC_Evac_Flyin" + tempSetting.hoverSound = "Goblin_IMC_Evac_Hover" + tempSetting.flyoutSound = "Goblin_IMC_Evac_FlyOut" + + if( team == TEAM_MILITIA ) + { + tempSetting.shipModel = $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" + tempSetting.flyinSound = "Crow_MCOR_Evac_Flyin" + tempSetting.hoverSound = "Crow_MCOR_Evac_Hover" + tempSetting.flyoutSound = "Crow_MCOR_Evac_Flyout" + } + return tempSetting +} + +void function EvacDropshipDamaged( entity evacShip, var damageInfo ) +{ + int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + if( damageSourceID == damagedef_nuclear_core ) + DamageInfo_SetDamage( damageInfo, DamageInfo_GetDamage( damageInfo ) * EVAC_SHIP_DAMAGE_MULTIPLIER_AGAINST_NUCLEAR_CORE ) +} + +void function WarpInEffectEvacShip( entity dropship ) +{ + dropship.EndSignal( "OnDestroy" ) + float sfxWait = 0.1 + float totalTime = WARPINFXTIME + float preWaitTime = 0.16 // give it some time so it's actually playing anim, and we can get it's "origin" attatch for playing warp in effect + string sfx = "dropship_warpin" + + wait preWaitTime + + int attach = dropship.LookupAttachment( "origin" ) + vector origin = dropship.GetAttachmentOrigin( attach ) + vector angles = dropship.GetAttachmentAngles( attach ) + + entity fx = PlayFX( FX_GUNSHIP_CRASH_EXPLOSION_ENTRANCE, origin, angles ) + fx.FXEnableRenderAlways() + fx.DisableHibernation() + + wait sfxWait + EmitSoundAtPosition( TEAM_UNASSIGNED, origin, sfx ) + + wait totalTime - sfxWait +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut index 5fd7d101..5aee1104 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut @@ -3,8 +3,20 @@ global function AddFactionXP void function AddFactionXP( entity player, int amount ) { string faction = GetFactionChoice( player ) + int oldLevel = FactionGetLevel( player, faction ) + int FactionXPMatch = player.GetPersistentVarAsInt( "xp_match[" + XP_TYPE.FACTION_LEVELED + "]" ) + // increment xp player.SetPersistentVar( "factionXP[" + faction + "]", min( FactionGetXP( player, faction ) + amount, FactionGetMaxXP( faction ) ) ) // note: no notif for faction level up + if ( FactionGetLevel( player, faction ) != oldLevel ) + { + AddPlayerScore( player, "FactionLevelUp" ) + IncrementPlayerChallengeFactionLeveledUp( player ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.FACTION_LEVELED + "]", FactionXPMatch + 1 ) + + if( ProgressionEnabledForPlayer( player ) ) + AwardRandomItemsForFactionLevels( player, faction, oldLevel, FactionGetLevel( player, faction ) ) + } }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut index d6d578bb..4ed7ee4a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut @@ -1,7 +1,6 @@ global function AiGameModes_Init -global function AiGameModes_SetGruntWeapons -global function AiGameModes_SetSpectreWeapons +global function AiGameModes_SetNPCWeapons global function AiGameModes_SpawnDropShip global function AiGameModes_SpawnDropPod @@ -15,25 +14,20 @@ const INTRO_DROPSHIP_CUTOFF = 2000 struct { - array< string > gruntWeapons = [ "mp_weapon_rspn101" ] - array< string > spectreWeapons = [ "mp_weapon_hemlok_smg" ] + table< string, array<string> > npcWeaponsTable // npcs have their default weapon in aisettings file } file void function AiGameModes_Init() { - } //------------------------------------------------------ -void function AiGameModes_SetGruntWeapons( array< string > weapons ) -{ - file.gruntWeapons = weapons -} - -void function AiGameModes_SetSpectreWeapons( array< string > weapons ) +void function AiGameModes_SetNPCWeapons( string npcClass, array<string> weapons ) { - file.spectreWeapons = weapons + if ( !( npcClass in file.npcWeaponsTable ) ) + file.npcWeaponsTable[ npcClass ] <- [] + file.npcWeaponsTable[ npcClass ] = weapons } //------------------------------------------------------ @@ -59,7 +53,7 @@ void function AiGameModes_SpawnDropShip( vector pos, vector rot, int team, int c foreach ( guy in guys ) { - ReplaceWeapon( guy, file.gruntWeapons[ RandomInt( file.gruntWeapons.len() ) ], [] ) + SetUpNPCWeapons( guy ) guy.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) } @@ -68,31 +62,23 @@ void function AiGameModes_SpawnDropShip( vector pos, vector rot, int team, int c } -void function AiGameModes_SpawnDropPod( vector pos, vector rot, int team, string content /*( ͡° ͜ʖ ͡°)*/, void functionref( array<entity> guys ) squadHandler = null ) +void function AiGameModes_SpawnDropPod( vector pos, vector rot, int team, string content /*( ͡° ͜ʖ ͡°)*/, void functionref( array<entity> guys ) squadHandler = null, int flags = 0 ) { - string squadName = MakeSquadName( team, UniqueString( "" ) ) - array<entity> guys - entity pod = CreateDropPod( pos, <0,0,0> ) - InitFireteamDropPod( pod ) - + InitFireteamDropPod( pod, flags ) + + waitthread LaunchAnimDropPod( pod, "pod_testpath", pos, rot ) + + string squadName = MakeSquadName( team, UniqueString( "" ) ) + array<entity> guys for ( int i = 0; i < 4 ;i++ ) { entity npc = CreateNPC( content, team, pos,<0,0,0> ) DispatchSpawn( npc ) SetSquad( npc, squadName ) - switch ( content ) - { - case "npc_soldier": - ReplaceWeapon( npc, file.gruntWeapons[ RandomInt( file.gruntWeapons.len() ) ], [] ) - break - - case "npc_spectre": - ReplaceWeapon( npc, file.spectreWeapons[ RandomInt( file.spectreWeapons.len() ) ], [] ) - break - } + SetUpNPCWeapons( npc ) npc.SetParent( pod, "ATTACH", true ) @@ -100,37 +86,100 @@ void function AiGameModes_SpawnDropPod( vector pos, vector rot, int team, string guys.append( npc ) } - // The order here is different so we can show on minimap while were still falling + ActivateFireteamDropPod( pod, guys ) + + // start searching for enemies if ( squadHandler != null ) thread squadHandler( guys ) - - waitthread LaunchAnimDropPod( pod, "pod_testpath", pos, rot ) - - ActivateFireteamDropPod( pod, guys ) } +const float REAPER_WARPFALL_DELAY = 4.7 // same as fd does void function AiGameModes_SpawnReaper( vector pos, vector rot, int team, string aiSettings = "", void functionref( entity reaper ) reaperHandler = null ) { + float reaperLandTime = REAPER_WARPFALL_DELAY + 1.2 // reaper takes ~1.2s to warpfall + thread HotDrop_Spawnpoint( pos, team, reaperLandTime, false, damagedef_reaper_fall ) + + wait REAPER_WARPFALL_DELAY entity reaper = CreateSuperSpectre( team, pos, rot ) + reaper.EndSignal( "OnDestroy" ) + // reaper highlight + Highlight_SetFriendlyHighlight( reaper, "sp_enemy_pilot" ) + reaper.Highlight_SetParam( 1, 0, < 1,1,1 > ) + SetDefaultMPEnemyHighlight( reaper ) + Highlight_SetEnemyHighlight( reaper, "enemy_titan" ) + SetSpawnOption_Titanfall( reaper ) SetSpawnOption_Warpfall( reaper ) if ( aiSettings != "" ) SetSpawnOption_AISettings( reaper, aiSettings ) + HideName( reaper ) // prevent flash a name onto it DispatchSpawn( reaper ) - + + reaper.WaitSignal( "WarpfallComplete" ) + ShowName( reaper ) // show name again after drop if ( reaperHandler != null ) thread reaperHandler( reaper ) } +// copied from cl_replacement_titan_hud.gnut +void function HotDrop_Spawnpoint( vector origin, int team, float impactTime, bool hasFriendlyWarning = false, int damageDef = -1 ) +{ + array<entity> targetEffects = [] + vector surfaceNormal = < 0, 0, 1 > + + int index = GetParticleSystemIndex( $"P_ar_titan_droppoint" ) + + if( hasFriendlyWarning ) + { + entity effectFriendly = StartParticleEffectInWorld_ReturnEntity( index, origin, surfaceNormal ) + SetTeam( effectFriendly, team ) + EffectSetControlPointVector( effectFriendly, 1, FRIENDLY_COLOR_FX ) + effectFriendly.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY + effectFriendly.DisableHibernation() // prevent it from fading out + targetEffects.append( effectFriendly ) + } + + entity effectEnemy = StartParticleEffectInWorld_ReturnEntity( index, origin, surfaceNormal ) + SetTeam( effectEnemy, team ) + EffectSetControlPointVector( effectEnemy, 1, ENEMY_COLOR_FX ) + effectEnemy.kv.VisibilityFlags = ENTITY_VISIBLE_TO_ENEMY + effectEnemy.DisableHibernation() // prevent it from fading out + targetEffects.append( effectEnemy ) + + // so enemy npcs will mostly avoid them + entity damageAreaInfo + if ( damageDef > -1 ) + { + damageAreaInfo = CreateEntity( "info_target" ) + DispatchSpawn( damageAreaInfo ) + AI_CreateDangerousArea_DamageDef( damageDef, damageAreaInfo, team, true, true ) + } + + wait impactTime + + // clean up + foreach( entity targetEffect in targetEffects ) + { + if ( IsValid( targetEffect ) ) + EffectStop( targetEffect ) + } + if ( IsValid( damageAreaInfo ) ) + damageAreaInfo.Destroy() +} + // including aisettings stuff specifically for at bounty titans +const float TITANFALL_WARNING_DURATION = 5.0 void function AiGameModes_SpawnTitan( vector pos, vector rot, int team, string setFile, string aiSettings = "", void functionref( entity titan ) titanHandler = null ) { entity titan = CreateNPCTitan( setFile, TEAM_BOTH, pos, rot ) SetSpawnOption_Titanfall( titan ) SetSpawnOption_Warpfall( titan ) + + // modified: do a hotdrop spawnpoint warning + thread HotDrop_Spawnpoint( pos, team, TITANFALL_WARNING_DURATION, false, damagedef_titan_fall ) if ( aiSettings != "" ) SetSpawnOption_AISettings( titan, aiSettings ) @@ -141,12 +190,27 @@ void function AiGameModes_SpawnTitan( vector pos, vector rot, int team, string s thread titanHandler( titan ) } -// entity.ReplaceActiveWeapon gave grunts archers sometimes, this is my replacement for it -void function ReplaceWeapon( entity guy, string weapon, array<string> mods ) +void function SetUpNPCWeapons( entity guy ) { - guy.TakeActiveWeapon() - guy.GiveWeapon( weapon, mods ) - guy.SetActiveWeaponByName( weapon ) + string className = guy.GetClassName() + + array<string> mainWeapons + if ( className in file.npcWeaponsTable ) + mainWeapons = file.npcWeaponsTable[ className ] + + if ( mainWeapons.len() == 0 ) // no valid weapons + return + + // take off existing main weapons, or sometimes they'll have a archer by default + foreach ( entity weapon in guy.GetMainWeapons() ) + guy.TakeWeapon( weapon.GetWeaponClassName() ) + + if ( mainWeapons.len() > 0 ) + { + string weaponName = mainWeapons[ RandomInt( mainWeapons.len() ) ] + guy.GiveWeapon( weaponName ) + guy.SetActiveWeaponByName( weaponName ) + } } // Checks if we can spawn a dropship at a node, this should guarantee dropship ziplines diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut index 9a94b848..7d73c926 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut @@ -1,22 +1,36 @@ untyped global function GamemodeAITdm_Init -const SQUADS_PER_TEAM = 3 +// these are now default settings +const int SQUADS_PER_TEAM = 4 -const REAPERS_PER_TEAM = 2 +const int REAPERS_PER_TEAM = 2 -const LEVEL_SPECTRES = 125 -const LEVEL_STALKERS = 380 -const LEVEL_REAPERS = 500 +const int LEVEL_SPECTRES = 125 +const int LEVEL_STALKERS = 380 +const int LEVEL_REAPERS = 500 + +// add settings +global function AITdm_SetSquadsPerTeam +global function AITdm_SetReapersPerTeam +global function AITdm_SetLevelSpectres +global function AITdm_SetLevelStalkers +global function AITdm_SetLevelReapers struct { // Due to team based escalation everything is an array - array< int > levels = [ LEVEL_SPECTRES, LEVEL_SPECTRES ] + array< int > levels = [] // Initilazed in `Spawner_Threaded` array< array< string > > podEntities = [ [ "npc_soldier" ], [ "npc_soldier" ] ] array< bool > reapers = [ false, false ] -} file + // default settings + int squadsPerTeam = SQUADS_PER_TEAM + int reapersPerTeam = REAPERS_PER_TEAM + int levelSpectres = LEVEL_SPECTRES + int levelStalkers = LEVEL_STALKERS + int levelReapers = LEVEL_REAPERS +} file void function GamemodeAITdm_Init() { @@ -34,18 +48,48 @@ void function GamemodeAITdm_Init() if ( GetCurrentPlaylistVarInt( "aitdm_archer_grunts", 0 ) == 0 ) { - AiGameModes_SetGruntWeapons( [ "mp_weapon_rspn101", "mp_weapon_dmr", "mp_weapon_r97", "mp_weapon_lmg" ] ) - AiGameModes_SetSpectreWeapons( [ "mp_weapon_hemlok_smg", "mp_weapon_doubletake", "mp_weapon_mastiff" ] ) + AiGameModes_SetNPCWeapons( "npc_soldier", [ "mp_weapon_rspn101", "mp_weapon_dmr", "mp_weapon_r97", "mp_weapon_lmg" ] ) + AiGameModes_SetNPCWeapons( "npc_spectre", [ "mp_weapon_hemlok_smg", "mp_weapon_doubletake", "mp_weapon_mastiff" ] ) + AiGameModes_SetNPCWeapons( "npc_stalker", [ "mp_weapon_hemlok_smg", "mp_weapon_lstar", "mp_weapon_mastiff" ] ) } else { - AiGameModes_SetGruntWeapons( [ "mp_weapon_rocket_launcher" ] ) - AiGameModes_SetSpectreWeapons( [ "mp_weapon_rocket_launcher" ] ) + AiGameModes_SetNPCWeapons( "npc_soldier", [ "mp_weapon_rocket_launcher" ] ) + AiGameModes_SetNPCWeapons( "npc_spectre", [ "mp_weapon_rocket_launcher" ] ) + AiGameModes_SetNPCWeapons( "npc_stalker", [ "mp_weapon_rocket_launcher" ] ) } ScoreEvent_SetupEarnMeterValuesForMixedModes() + SetupGenericTDMChallenge() } +// add settings +void function AITdm_SetSquadsPerTeam( int squads ) +{ + file.squadsPerTeam = squads +} + +void function AITdm_SetReapersPerTeam( int reapers ) +{ + file.reapersPerTeam = reapers +} + +void function AITdm_SetLevelSpectres( int level ) +{ + file.levelSpectres = level +} + +void function AITdm_SetLevelStalkers( int level ) +{ + file.levelStalkers = level +} + +void function AITdm_SetLevelReapers( int level ) +{ + file.levelReapers = level +} +// + // Starts skyshow, this also requiers AINs but doesn't crash if they're missing void function OnPrematchStart() { @@ -74,10 +118,12 @@ void function HandleScoreEvent( entity victim, entity attacker, var damageInfo ) // Basic checks if ( victim == attacker || !( attacker.IsPlayer() || attacker.IsTitan() ) || GetGameState() != eGameState.Playing ) return - // Hacked spectre filter if ( victim.GetOwner() == attacker ) return + // NPC titans without an owner player will not count towards any team's score + if ( attacker.IsNPC() && attacker.IsTitan() && !IsValid( GetPetTitanOwner( attacker ) ) ) + return // Split score so we can check if we are over the score max // without showing the wrong value on client @@ -189,7 +235,7 @@ void function SpawnIntroBatch_Threaded( int team ) int ships = shipNodes.len() - for ( int i = 0; i < SQUADS_PER_TEAM; i++ ) + for ( int i = 0; i < file.squadsPerTeam; i++ ) { if ( pods != 0 || ships == 0 ) { @@ -234,6 +280,7 @@ void function Spawner_Threaded( int team ) // used to index into escalation arrays int index = team == TEAM_MILITIA ? 0 : 1 + file.levels = [ file.levelSpectres, file.levelSpectres ] // due we added settings, should init levels here! while( true ) { @@ -248,7 +295,7 @@ void function Spawner_Threaded( int team ) if ( file.reapers[ index ] ) { array< entity > points = SpawnPoints_GetDropPod() - if ( reaperCount < REAPERS_PER_TEAM ) + if ( reaperCount < file.reapersPerTeam ) { entity node = points[ GetSpawnPointIndex( points, team ) ] waitthread AiGameModes_SpawnReaper( node.GetOrigin(), node.GetAngles(), team, "npc_super_spectre_aitdm", ReaperHandler ) @@ -256,7 +303,7 @@ void function Spawner_Threaded( int team ) } // NORMAL SPAWNS - if ( count < SQUADS_PER_TEAM * 4 - 2 ) + if ( count < file.squadsPerTeam * 4 - 2 ) { string ent = file.podEntities[ index ][ RandomInt( file.podEntities[ index ].len() ) ] @@ -302,19 +349,19 @@ void function Escalate( int team ) // Based on score escalate a team switch ( file.levels[ index ] ) { - case LEVEL_SPECTRES: - file.levels[ index ] = LEVEL_STALKERS + case file.levelSpectres: + file.levels[ index ] = file.levelStalkers file.podEntities[ index ].append( "npc_spectre" ) SetGlobalNetInt( defcon, 2 ) return - case LEVEL_STALKERS: - file.levels[ index ] = LEVEL_REAPERS + case file.levelStalkers: + file.levels[ index ] = file.levelReapers file.podEntities[ index ].append( "npc_stalker" ) SetGlobalNetInt( defcon, 3 ) return - case LEVEL_REAPERS: + case file.levelReapers: file.reapers[ index ] = true SetGlobalNetInt( defcon, 4 ) return @@ -351,30 +398,47 @@ int function GetSpawnPointIndex( array< entity > points, int team ) // AI can also flee deeper into their zone suggesting someone spent way too much time on this void function SquadHandler( array<entity> guys ) { + int team = guys[0].GetTeam() + // show the squad enemy radar + array<entity> players = GetPlayerArrayOfEnemies( team ) + foreach ( entity guy in guys ) + { + if ( IsAlive( guy ) ) + { + foreach ( player in players ) + guy.Minimap_AlwaysShow( 0, player ) + } + } + // Not all maps have assaultpoints / have weird assault points ( looking at you ac ) // So we use enemies with a large radius - array< entity > points = GetNPCArrayOfEnemies( guys[0].GetTeam() ) - - if ( points.len() == 0 ) + while ( GetNPCArrayOfEnemies( team ).len() == 0 ) // if we can't find any enemy npcs, keep waiting + WaitFrame() + + // our waiting is end, check if any soldiers left + bool squadAlive = false + foreach ( entity guy in guys ) + { + if ( IsAlive( guy ) ) + squadAlive = true + else + guys.removebyvalue( guy ) + } + if ( !squadAlive ) return + + array<entity> points = GetNPCArrayOfEnemies( team ) vector point point = points[ RandomInt( points.len() ) ].GetOrigin() - array<entity> players = GetPlayerArrayOfEnemies( guys[0].GetTeam() ) - - // Setup AI + // Setup AI, first assault point foreach ( guy in guys ) { guy.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) guy.AssaultPoint( point ) guy.AssaultSetGoalRadius( 1600 ) // 1600 is minimum for npc_stalker, works fine for others - - // show on enemy radar - foreach ( player in players ) - guy.Minimap_AlwaysShow( 0, player ) - - + //thread AITdm_CleanupBoredNPCThread( guy ) } @@ -392,16 +456,32 @@ void function SquadHandler( array<entity> guys ) // Stop func if our squad has been killed off if ( guys.len() == 0 ) return + } + + // Get point and send our whole squad to it + points = GetNPCArrayOfEnemies( team ) + if ( points.len() == 0 ) // can't find any points here + { + // Have to wait some amount of time before continuing + // because if we don't the server will continue checking this + // forever, aren't loops fun? + // This definitely didn't waste ~8 hours of my time reverting various + // launcher PRs before finding this mods PR that caused servers to + // freeze forever before having their process killed by the dedi watchdog + // without any logging. If anyone reads this, PLEASE add logging to your scripts + // for when weird edge cases happen, it can literally only help debugging. -Spoon + WaitFrame() + continue + } - // Get point and send guy to it - points = GetNPCArrayOfEnemies( guy.GetTeam() ) - if ( points.len() == 0 ) - continue - - point = points[ RandomInt( points.len() ) ].GetOrigin() - - guy.AssaultPoint( point ) + point = points[ RandomInt( points.len() ) ].GetOrigin() + + foreach ( guy in guys ) + { + if ( IsAlive( guy ) ) + guy.AssaultPoint( point ) } + wait RandomFloatRange(5.0,15.0) } } @@ -507,4 +587,4 @@ void function AITdm_CleanupBoredNPCThread( entity guy ) print( "cleaning up bored npc: " + guy + " from team " + guy.GetTeam() ) guy.Destroy() -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut index 915e03e0..9cf0021d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut @@ -1,12 +1,54 @@ +untyped // AddCallback_OnUseEntity() needs this global function GamemodeAt_Init global function RateSpawnpoints_AT -const int BH_AI_TEAM = TEAM_BOTH -const int BOUNTY_TITAN_DAMAGE_POOL = 400 // Rewarded for damage -const int BOUNTY_TITAN_KILL_REWARD = 100 // Rewarded for kill -const float WAVE_STATE_TRANSITION_TIME = 5.0 +// Old bobr note which still applies after a year :) +// IMPLEMENTATION NOTES: +// bounty hunt is a mode that was clearly pretty heavily developed, and had alot of scrapped concepts (i.e. most wanted player bounties, turret bounties, collectable blackbox objectives) +// in the interest of time, this script isn't gonna support any of that atm +// alot of the remote functions also take parameters that aren't used, i'm not gonna populate these and just use default values for now instead +// however, if you do want to mess with this stuff, almost all the remote functions for this stuff are still present in cl_gamemode_at, and should work fine with minimal fuckery in my experience + + +// Bank settings +const float AT_BANKS_OPEN_DURATION = 45.0 // Bank open time +const int AT_BANK_DEPOSIT_RATE = 10 // Amount deposited per second +const int AT_BANK_DEPOSIT_RADIUS = 256 // bank radius for depositing +const float AT_BANK_FORCE_CLOSE_DELAY = 4.0 // If all bonus money has been deposited close the banks after this constant early + +// TODO: The reference function no longer exists, check if this still holds true +// VoyageDB: HACK score events... respawn made things in AT_SetScoreEventOverride() really messed up, have to do some hack here +const array<string> AT_ENABLE_SCOREEVENTS = +[ + // these are disabled in AT_SetScoreEventOverride(), but related scoreEvents are not implemented into gamemode + // needs to re-enable them + "DoomTitan", + "DoomAutoTitan" +] +const array<string> AT_DISABLE_SCOREEVENTS = +[ + // these are missed in AT_SetScoreEventOverride(), but game actually used them + // needs to disable them + "KillStalker" +] + +// Wave settings +// General +const int AT_AI_TEAM = TEAM_BOTH // Allow AI to attack and be attacked by both player teams +const float AT_FIRST_WAVE_START_DELAY = 10.0 // First wave has an extra delay before begining +const float AT_WAVE_TRANSITION_DELAY = 5.0 // Time between each wave and banks opening/closing +const float AT_WAVE_END_ANNOUNCEMENT_DELAY = 1.0 // Extra wait before announcing wave cleaned + +// Squad settings +const int AT_DROPPOD_SQUADS_ALLOWED_ON_FIELD = 4 // default is 4 droppod squads on field, won't use if AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK turns on // TODO: verify this -const array<string> VALID_BOUNTY_TITAN_SETTINGS = [ +// Titan bounty settings +const float AT_BOUNTY_TITAN_CHECK_DELAY = 10.0 // wait for bounty titans landing before we start checking their life state +const float AT_BOUNTY_TITAN_HEALTH_MULTIPLIER = 3 // TODO: Verify this + +// Titan boss settings, check sh_gamemode_at.nut for more info +const array<string> AT_BOUNTY_TITANS_AI_SETTINGS = +[ "npc_titan_atlas_stickybomb_bounty", "npc_titan_atlas_tracker_bounty", "npc_titan_ogre_minigun_bounty", @@ -16,102 +58,582 @@ const array<string> VALID_BOUNTY_TITAN_SETTINGS = [ "npc_titan_atlas_vanguard_bounty" ] +// Extra +// Respawn didn't use the "totalAllowedOnField" for npc spawning, they only allow 1 squad to be on field for each type of npc. enabling this might cause too much npcs spawning and crash the game +const bool AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK = false -// IMPLEMENTATION NOTES: -// bounty hunt is a mode that was clearly pretty heavily developed, and had alot of scrapped concepts (i.e. most wanted player bounties, turret bounties, collectable blackbox objectives) -// in the interest of time, this script isn't gonna support any of that atm -// alot of the remote functions also take parameters that aren't used, i'm not gonna populate these and just use default values for now instead -// however, if you do want to mess with this stuff, almost all the remote functions for this stuff are still present in cl_gamemode_at, and should work fine with minimal fuckery in my experience +// Objectives +const int AT_OBJECTIVE_EMPTY = -1 // Remove objective +const int AT_OBJECTIVE_KILL_DZ = 104 // #AT_OBJECTIVE_KILL_DZ +const int AT_OBJECTIVE_KILL_DZ_MULTI = 105 // #AT_OBJECTIVE_KILL_DZ_MULTI +const int AT_OBJECTIVE_KILL_BOSS = 106 // #AT_OBJECTIVE_KILL_BOSS +const int AT_OBJECTIVE_KILL_BOSS_MULTI = 107 // #AT_OBJECTIVE_KILL_BOSS_MULTI +const int AT_OBJECTIVE_BANK_OPEN = 109 // #AT_BANK_OPEN_OBJECTIVE -struct { - array<entity> campsToRegisterOnEntitiesDidLoad +// When a player tries to deposit when they have 0 bonus money +// we show a help mesage, this is the ratelimit for that message +// so that we dont spam it too much +const float AT_PLAYER_HUD_MESSAGE_COOLDOWN = 2.5 +// Due to bad navmeshes NPCs may wonder off to bumfuck nowhere or the game +// might teleport them into the map while trying to correct their position +// This obviously breaks bounty hunt where the objective is to kill ALL ai +// so we try to cleanup the camps after a set amount of time of inactivity +const int AT_CAMP_BORED_NPCS_LEFT_TO_START_CLEANUP = 3 +const float AT_CAMP_BORED_CLEANUP_WAIT = 60.0 +struct +{ array<entity> banks array<AT_WaveOrigin> camps + + // Used to track ScriptmanagedEntArrays of ai squads + table< int, array<int> > campScriptEntArrays - table< int, table< string, int > > trackedCampNPCSpawns + table< entity, bool > titanIsBountyBoss + table< entity, int > bountyTitanRewards + table< entity, int > npcStolenBonus + table< entity, bool > playerBankUploading + table< entity, table<entity, int> > playerSavedBountyDamage + table< entity, float > playerHudMessageAllowedTime } file void function GamemodeAt_Init() { - AddCallback_GameStateEnter( eGameState.Playing, RunATGame ) - + // wave + RegisterSignal( "ATWaveEnd" ) + // camp + RegisterSignal( "ATCampClean" ) + RegisterSignal( "ATAllCampsClean" ) + + // Set-up score callbacks + ScoreEvent_SetupEarnMeterValuesForMixedModes() + AddCallback_OnPlayerKilled( AT_PlayerOrNPCKilledScoreEvent ) + AddCallback_OnNPCKilled( AT_PlayerOrNPCKilledScoreEvent ) + + // Set npc weapons + AiGameModes_SetNPCWeapons( "npc_soldier", [ "mp_weapon_rspn101", "mp_weapon_dmr", "mp_weapon_r97", "mp_weapon_lmg" ] ) + AiGameModes_SetNPCWeapons( "npc_spectre", [ "mp_weapon_hemlok_smg", "mp_weapon_doubletake", "mp_weapon_mastiff" ] ) + AiGameModes_SetNPCWeapons( "npc_stalker", [ "mp_weapon_hemlok_smg", "mp_weapon_lstar", "mp_weapon_mastiff" ] ) + + // Gamestate callbacks + AddCallback_GameStateEnter( eGameState.Prematch, OnATGamePrematch ) + AddCallback_GameStateEnter( eGameState.Playing, OnATGamePlaying ) + + // Initilaze player AddCallback_OnClientConnected( InitialiseATPlayer ) - AddSpawnCallbackEditorClass( "info_target", "info_attrition_bank", CreateATBank ) - AddSpawnCallbackEditorClass( "info_target", "info_attrition_camp", CreateATCamp ) - AddCallback_EntitiesDidLoad( CreateATCamps_Delayed ) + // Initilaze gamemode entities + AddCallback_EntitiesDidLoad( OnEntitiesDidLoad ) } void function RateSpawnpoints_AT( int checkclass, array<entity> spawnpoints, int team, entity player ) { - RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) // temp + RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) } -// world and player inits + + +//////////////////////////////////////// +///// GAMESTATE CALLBACK FUNCTIONS ///// +//////////////////////////////////////// + +void function OnATGamePrematch() +{ + AT_ScoreEventsValueSetUp() +} + +void function OnATGamePlaying() +{ + thread AT_GameLoop_Threaded() +} + +//////////////////////////////////////////// +///// GAMESTATE CALLBACK FUNCTIONS END ///// +//////////////////////////////////////////// + + + +//////////////////////////// +///// PLAYER FUNCTIONS ///// +//////////////////////////// void function InitialiseATPlayer( entity player ) { Remote_CallFunction_NonReplay( player, "ServerCallback_AT_OnPlayerConnected" ) + player.SetPlayerNetInt( "AT_bonusPointMult", 1 ) + file.playerBankUploading[ player ] <- false + file.playerSavedBountyDamage[ player ] <- {} + file.playerHudMessageAllowedTime[ player ] <- 0.0 + thread AT_PlayerTitleThink( player ) + thread AT_PlayerObjectiveThink( player ) } -void function CreateATBank( entity spawnpoint ) +void function AT_PlayerTitleThink( entity player ) { - entity bank = CreatePropDynamic( spawnpoint.GetModelName(), spawnpoint.GetOrigin(), spawnpoint.GetAngles(), SOLID_VPHYSICS ) - bank.SetScriptName( "AT_Bank" ) - - // create tracker ent - // we don't need to store these at all, client just needs to get them - DispatchSpawn( GetAvailableBankTracker( bank ) ) + player.EndSignal( "OnDestroy" ) + + while ( true ) + { + if ( GetGameState() == eGameState.Playing ) + { + // Set player money count + player.SetTitle( "$" + string( AT_GetPlayerBonusPoints( player ) ) ) + + if( AT_GetPlayerBonusPoints( player ) >= 600 && !HasPlayerCompletedMeritScore( player ) ) //Challenge is: "Earn $600." + { + AddPlayerScore( player, "ChallengeATAssault" ) + SetPlayerChallengeMeritScore( player ) + } + } + else if ( GetGameState() >= eGameState.WinnerDetermined ) + { + if ( player.IsTitan() ) + player.SetTitle( GetTitanPlayerTitle( player ) ) + else + player.SetTitle( "" ) + + return + } + + WaitFrame() + } +} + +string function GetTitanPlayerTitle( entity player ) +{ + entity soul = player.GetTitanSoul() + + if ( !IsValid( soul ) ) + return "" - thread PlayAnim( bank, "mh_inactive_idle" ) + string settings = GetSoulPlayerSettings( soul ) + var title = GetPlayerSettingsFieldForClassName( settings, "printname" ) + + if ( title == null ) + return "" - file.banks.append( bank ) + return expect string( title ) +} + +void function AT_PlayerObjectiveThink( entity player ) +{ + player.EndSignal( "OnDestroy" ) + + int curObjective = AT_OBJECTIVE_EMPTY + while ( true ) + { + // game entered other state + if ( GetGameState() >= eGameState.WinnerDetermined ) + { + player.SetPlayerNetInt( "gameInfoStatusText", AT_OBJECTIVE_EMPTY ) + return + } + + int nextObjective = AT_OBJECTIVE_EMPTY + + // Determine objective text for player + if ( !IsAlive( player ) ) // Don't show objective to dead players + { + nextObjective = AT_OBJECTIVE_EMPTY + } + else // We're still alive + { + if ( GetGlobalNetBool( "banksOpen" ) ) + { + nextObjective = AT_OBJECTIVE_BANK_OPEN + } + else if ( GetGlobalNetBool( "preBankPhase" ) ) + { + nextObjective = AT_OBJECTIVE_EMPTY + } + else + { + // No checks have passed, try to do a "Kill all x near the marked dropzone" objective + int dropZoneActiveCount = 0 + int bossAliveCount = 0 + array<entity> campEnts + campEnts.append( GetGlobalNetEnt( "camp1Ent" ) ) + campEnts.append( GetGlobalNetEnt( "camp2Ent" ) ) + + foreach ( entity ent in campEnts ) + { + if ( IsValid( ent ) ) + { + if ( ent.IsTitan() ) + bossAliveCount += 1 + else + dropZoneActiveCount += 1 + } + } + + switch( dropZoneActiveCount ) + { + case 1: + nextObjective = AT_OBJECTIVE_KILL_DZ + break + case 2: + nextObjective = AT_OBJECTIVE_KILL_DZ_MULTI + break + } + + switch( bossAliveCount ) + { + case 1: + nextObjective = AT_OBJECTIVE_KILL_BOSS + break + case 2: + nextObjective = AT_OBJECTIVE_KILL_BOSS_MULTI + break + } + + // We couldn't get an objective, set it to empty + if ( dropZoneActiveCount == 0 && bossAliveCount == 0 ) + nextObjective = AT_OBJECTIVE_EMPTY + } + } + + // Set the objective when changed + if ( curObjective != nextObjective ) + { + player.SetPlayerNetInt( "gameInfoStatusText", nextObjective ) + curObjective = nextObjective + } + + WaitFrame() + } } -void function CreateATCamp( entity spawnpoint ) +//////////////////////////////// +///// PLAYER FUNCTIONS END ///// +//////////////////////////////// + + + +//////////////////////////////////////// +///// GAMEMODE INITILAZE FUNCTIONS ///// +//////////////////////////////////////// + +void function OnEntitiesDidLoad() { - // delay this so we don't do stuff before all spawns are initialised and that - file.campsToRegisterOnEntitiesDidLoad.append( spawnpoint ) + foreach ( entity info_target in GetEntArrayByClass_Expensive( "info_target" ) ) + { + if( info_target.HasKey( "editorclass" ) ) + { + switch( info_target.kv.editorclass ) + { + case "info_attrition_bank": + entity bank = CreateEntity( "prop_script" ) + bank.SetScriptName( "AT_Bank" ) // VoyageDB: don't know how to make client able to track it + bank.SetOrigin( info_target.GetOrigin() ) + bank.SetAngles( info_target.GetAngles() ) + DispatchSpawn( bank ) + bank.kv.solid = SOLID_VPHYSICS + bank.SetModel( info_target.GetModelName() ) + + // Minimap icon init + bank.Minimap_SetCustomState( eMinimapObject_prop_script.AT_BANK ) + bank.Minimap_SetAlignUpright( true ) + bank.Minimap_SetZOrder( MINIMAP_Z_OBJECT ) + bank.Minimap_Hide( TEAM_IMC, null ) + bank.Minimap_Hide( TEAM_MILITIA, null ) + + // Create tracker ent + // we don't need to store these at all, client just needs to get them + DispatchSpawn( GetAvailableBankTracker( bank ) ) + + // Make sure the bank is in it's disabled pose + thread PlayAnim( bank, "mh_inactive_idle" ) + // Set the bank usable + AddCallback_OnUseEntity( bank, OnPlayerUseBank ) + bank.SetUsable() + bank.SetUsePrompts( "#AT_USE_BANK_CLOSED", "#AT_USE_BANK_CLOSED" ) + + file.banks.append( bank ) + break; + case "info_attrition_camp": + AT_WaveOrigin campStruct + campStruct.ent = info_target + campStruct.origin = info_target.GetOrigin() + campStruct.radius = expect string( info_target.kv.radius ).tofloat() + campStruct.height = expect string( info_target.kv.height ).tofloat() + + // Assumes every info_attrition_camp will have all 9 phases, possibly not a good idea? + // TODO: verify this on all vanilla maps before release + for ( int i = 0; i < 9; i++ ) + campStruct.phaseAllowed.append( expect string( info_target.kv[ "phase_" + ( i + 1 ) ] ) == "1" ) + + // Get droppod spawns within the camp + foreach ( entity spawnpoint in SpawnPoints_GetDropPod() ) + { + vector campPos = info_target.GetOrigin() + vector spawnPos = spawnpoint.GetOrigin() + if ( Distance( campPos, spawnPos ) < campStruct.radius ) + campStruct.dropPodSpawnPoints.append( spawnpoint ) + } + + // Get titan spawns within the camp + foreach ( entity spawnpoint in SpawnPoints_GetTitan() ) + { + vector campPos = info_target.GetOrigin() + vector spawnPos = spawnpoint.GetOrigin() + if ( Distance( campPos, spawnPos ) < campStruct.radius ) + campStruct.titanSpawnPoints.append( spawnpoint ) + } + + file.camps.append( campStruct ) + break; + } + } + } +} + +//////////////////////////////////////////// +///// GAMEMODE INITILAZE FUNCTIONS END ///// +//////////////////////////////////////////// + + + +///////////////////////////// +///// SCORING FUNCTIONS ///// +///////////////////////////// + +// TODO: Don't reward in postmatch +// TODO: Dropping a titan on a bounty with it's dome-shield still up rewards you the bonus, but +// it doesn't actually damage the bounty titan + +void function AT_ScoreEventsValueSetUp() +{ + ScoreEvent_SetEarnMeterValues( "KillTitan", 0.10, 0.15 ) + ScoreEvent_SetEarnMeterValues( "KillAutoTitan", 0.10, 0.15 ) + ScoreEvent_SetEarnMeterValues( "AttritionTitanKilled", 0.10, 0.15 ) + ScoreEvent_SetEarnMeterValues( "KillPilot", 0.10, 0.10 ) + ScoreEvent_SetEarnMeterValues( "AttritionPilotKilled", 0.10, 0.10 ) + ScoreEvent_SetEarnMeterValues( "AttritionBossKilled", 0.10, 0.20 ) + ScoreEvent_SetEarnMeterValues( "AttritionGruntKilled", 0.02, 0.02, 0.5 ) + ScoreEvent_SetEarnMeterValues( "AttritionSpectreKilled", 0.02, 0.02, 0.5 ) + ScoreEvent_SetEarnMeterValues( "AttritionStalkerKilled", 0.02, 0.02, 0.5 ) + ScoreEvent_SetEarnMeterValues( "AttritionSuperSpectreKilled", 0.10, 0.10, 0.5 ) + + // HACK + foreach ( string eventName in AT_ENABLE_SCOREEVENTS ) + ScoreEvent_Enable( GetScoreEvent( eventName ) ) + + foreach ( string eventName in AT_DISABLE_SCOREEVENTS ) + ScoreEvent_Disable( GetScoreEvent( eventName ) ) } -void function CreateATCamps_Delayed() +void function AT_PlayerOrNPCKilledScoreEvent( entity victim, entity attacker, var damageInfo ) { - // we delay registering camps until EntitiesDidLoad since they rely on spawnpoints and stuff, which might not all be ready in the creation callback - // unsure if this would be an issue in practice, but protecting against it in case it would be - foreach ( entity camp in file.campsToRegisterOnEntitiesDidLoad ) + if ( !IsValid( attacker ) ) + return + + // Suicide + if ( attacker == victim ) { - AT_WaveOrigin campStruct - campStruct.ent = camp - campStruct.origin = camp.GetOrigin() - campStruct.radius = expect string( camp.kv.radius ).tofloat() - campStruct.height = expect string( camp.kv.height ).tofloat() + if ( victim.IsPlayer() ) + AT_PlayerBonusLoss( victim, AT_GetPlayerBonusPoints( victim ) / 2 ) - // assumes every info_attrition_camp will have all 9 phases, possibly not a good idea? - for ( int i = 0; i < 9; i++ ) - campStruct.phaseAllowed.append( expect string( camp.kv[ "phase_" + ( i + 1 ) ] ) == "1" ) + return + } + + // NPC is the attacker + if ( !attacker.IsPlayer() ) + { + if ( attacker.IsTitan() && IsValid( GetPetTitanOwner( attacker ) ) ) // Re-asign attacker + attacker = GetPetTitanOwner( attacker ) + else // NPC steals money from player, killing it will award the stolen bonus + normal reward + AT_NPCTryStealBonusPoints( attacker, victim ) - // get droppod spawns - foreach ( entity spawnpoint in SpawnPoints_GetDropPod() ) - if ( Distance( camp.GetOrigin(), spawnpoint.GetOrigin() ) < 1500.0 ) - campStruct.dropPodSpawnPoints.append( spawnpoint ) + return + } + + // Get event name + string eventName = GetAttritionScoreEventName( victim.GetClassName() ) + + if ( victim.IsTitan() ) // titan specific + eventName = GetAttritionScoreEventNameFromAI( victim ) + + if ( eventName == "" ) // no valid scoreEvent + return + + int scoreVal = ScoreEvent_GetPointValue( GetScoreEvent( eventName ) ) + + // pet titan check + if ( victim.IsTitan() && IsValid( GetPetTitanOwner( victim ) ) ) + { + if( GetPetTitanOwner( victim ) == attacker ) // Player ejected + return - foreach ( entity spawnpoint in SpawnPoints_GetTitan() ) - if ( Distance( camp.GetOrigin(), spawnpoint.GetOrigin() ) < 1500.0 ) - campStruct.titanSpawnPoints.append( spawnpoint ) + if( GetPetTitanOwner( victim ).IsPlayer() ) // Killed player npc titan + return + + scoreVal = ATTRITION_SCORE_TITAN_MIN + } + + // killed npc + if ( victim.IsNPC() ) + { + int bonusFromNPC = 0 + // If NPC was carrying a bonus award it to the attacker + if ( victim in file.npcStolenBonus ) + { + bonusFromNPC = file.npcStolenBonus[ victim ] + delete file.npcStolenBonus[ victim ] + } + AT_AddPlayerBonusPointsForEntityKilled( attacker, scoreVal, damageInfo, bonusFromNPC ) + AddPlayerScore( attacker, eventName ) // we add scoreEvent here, since basic score events has been overwrited by sh_gamemode_at.nut + // update score difference and scoreboard + AT_AddToPlayerTeamScore( attacker, scoreVal ) + } + + // bonus stealing check + if ( victim.IsPlayer() ) + AT_PlayerTryStealBonusPoints( attacker, victim, damageInfo ) +} + +bool function AT_NPCTryStealBonusPoints( entity attacker, entity victim ) +{ + // basic checks + if ( !attacker.IsNPC() ) + return false - // todo: turret spawns someday maybe + if ( !victim.IsPlayer() ) + return false + + int victimBonus = AT_GetPlayerBonusPoints( victim ) + int bonusToSteal = victimBonus / 2 // npc always steal half the bonus from player, no extra bonus for killing the player + if ( bonusToSteal == 0 ) // player has no bonus! + return false + + if ( !( attacker in file.npcStolenBonus ) ) // init + file.npcStolenBonus[ attacker ] <- 0 - file.camps.append( campStruct ) + file.npcStolenBonus[ attacker ] += bonusToSteal + + AT_PlayerBonusLoss( victim, bonusToSteal ) // tell victim of bonus stolen + + if ( !( attacker in file.titanIsBountyBoss ) ) // if attacker npc is not a bounty titan, we make them highlighted + NPCBountyStolenHighlight( attacker ) + + return true +} + +void function NPCBountyStolenHighlight( entity npc ) +{ + Highlight_SetEnemyHighlight( npc, "enemy_boss_bounty" ) +} + +bool function AT_PlayerTryStealBonusPoints( entity attacker, entity victim, var damageInfo ) +{ + // basic checks + if ( !attacker.IsPlayer() ) + return false + + if ( !victim.IsPlayer() ) + return false + + int victimBonus = AT_GetPlayerBonusPoints( victim ) + + int minScoreCanSteal = ATTRITION_SCORE_PILOT_MIN + if ( victim.IsTitan() ) + minScoreCanSteal = ATTRITION_SCORE_TITAN_MIN + + int bonusToSteal = victimBonus / 2 + int attackerScore = bonusToSteal + bool realStealBonus = true + if ( bonusToSteal <= minScoreCanSteal ) // no enough bonus to steal + { + attackerScore = minScoreCanSteal // give attacker min bonus + realStealBonus = false // we don't do attacker steal events below, just half victim's bonus } + + // servercallback + int victimEHandle = victim.GetEncodedEHandle() + vector damageOrigin = DamageInfo_GetDamagePosition( damageInfo ) + + // only do attacker events if victim has enough bonus to steal + if ( realStealBonus ) + { + Remote_CallFunction_NonReplay( + attacker, + "ServerCallback_AT_PlayerKillScorePopup", + bonusToSteal, // stolenScore + victimEHandle, // victimEHandle + damageOrigin.x, // x + damageOrigin.y, // y + damageOrigin.z // z + ) + } + else // otherwise we do a normal entity killed scoreEvent + { + AT_AddPlayerBonusPointsForEntityKilled( attacker, attackerScore, damageInfo ) + } + + // update score difference and scoreboard + AT_AddToPlayerTeamScore( attacker, minScoreCanSteal ) + + // steal bonus + // only do attacker events if victim has enough bonus to steal + if ( realStealBonus ) + { + AT_AddPlayerBonusPoints( attacker, bonusToSteal ) + AddPlayerScore( attacker, "AttritionBonusStolen" ) + } + + // tell victim of bonus stolen + AT_PlayerBonusLoss( victim, bonusToSteal ) - file.campsToRegisterOnEntitiesDidLoad.clear() + return realStealBonus } -// scoring funcs +void function AT_PlayerBonusLoss( entity player, int bonusLoss ) +{ + AT_AddPlayerBonusPoints( player, -bonusLoss ) + Remote_CallFunction_NonReplay( + player, + "ServerCallback_AT_ShowStolenBonus", + bonusLoss // stolenScore + ) +} + +// team score meter +void function AT_AddToPlayerTeamScore( entity player, int amount ) +{ + // do not award any score after the match is ended + if ( GetGameState() > eGameState.Playing ) + return + + // add to scoreboard + player.AddToPlayerGameStat( PGS_ASSAULT_SCORE, amount ) + + // Check score so we dont go over max + if ( GameRules_GetTeamScore(player.GetTeam()) + amount > GetScoreLimit_FromPlaylist() ) + { + amount = GetScoreLimit_FromPlaylist() - GameRules_GetTeamScore(player.GetTeam()) + } + + // update score difference + AddTeamScore( player.GetTeam(), amount ) +} + +// bonus points, players earn from killing +void function AT_AddPlayerBonusPoints( entity player, int amount ) +{ + // do not award any score after the match is ended + if ( GetGameState() > eGameState.Playing ) + return + + // add to scoreboard + player.AddToPlayerGameStat( PGS_SCORE, amount ) + AT_SetPlayerBonusPoints( player, player.GetPlayerNetInt( "AT_bonusPoints" ) + ( player.GetPlayerNetInt( "AT_bonusPoints256" ) * 256 ) + amount ) +} + +int function AT_GetPlayerBonusPoints( entity player ) +{ + return player.GetPlayerNetInt( "AT_bonusPoints" ) + player.GetPlayerNetInt( "AT_bonusPoints256" ) * 256 +} -// don't use this where possible as it doesn't set score and stuff -void function AT_SetPlayerCash( entity player, int amount ) +void function AT_SetPlayerBonusPoints( entity player, int amount ) { // split into stacks of 256 where necessary int stacks = amount / 256 // automatically rounds down because int division @@ -120,198 +642,986 @@ void function AT_SetPlayerCash( entity player, int amount ) player.SetPlayerNetInt( "AT_bonusPoints", amount - stacks * 256 ) } -void function AT_AddPlayerCash( entity player, int amount ) +// total points, the value player actually uploaded to team score +void function AT_AddPlayerTotalPoints( entity player, int amount ) { - // update score difference - AddTeamScore( player.GetTeam(), amount / 2 ) - AT_SetPlayerCash( player, player.GetPlayerNetInt( "AT_bonusPoints" ) + ( player.GetPlayerNetInt( "AT_bonusPoints256" ) * 256 ) + amount ) + // update score difference and scoreboard, calling this function meaning player has deposited their bonus to team score + AT_AddToPlayerTeamScore( player, amount ) + AT_SetPlayerTotalPoints( player, player.GetPlayerNetInt( "AT_totalPoints" ) + ( player.GetPlayerNetInt( "AT_totalPoints256" ) * 256 ) + amount ) +} + +void function AT_SetPlayerTotalPoints( entity player, int amount ) +{ + // split into stacks of 256 where necessary + int stacks = amount / 256 // automatically rounds down because int division + + player.SetPlayerNetInt( "AT_totalPoints256", stacks ) + player.SetPlayerNetInt( "AT_totalPoints", amount - stacks * 256 ) +} + +// earn points, seems not used +void function AT_AddPlayerEarnedPoints( entity player, int amount ) +{ + AT_SetPlayerBonusPoints( player, player.GetPlayerNetInt( "AT_earnedPoints" ) + ( player.GetPlayerNetInt( "AT_earnedPoints256" ) * 256 ) + amount ) +} + +void function AT_SetPlayerEarnedPoints( entity player, int amount ) +{ + // split into stacks of 256 where necessary + int stacks = amount / 256 // automatically rounds down because int division + + player.SetPlayerNetInt( "AT_earnedPoints256", stacks ) + player.SetPlayerNetInt( "AT_earnedPoints", amount - stacks * 256 ) } -// run gamestate +// damaging bounty +void function AT_AddPlayerBonusPointsForBossDamaged( entity player, entity victim, int amount, var damageInfo ) +{ + AT_AddPlayerBonusPoints( player, amount ) + // update score difference and scoreboard + AT_AddToPlayerTeamScore( player, amount ) + + // send servercallback for damaging + int bossEHandle = victim.GetEncodedEHandle() + vector damageOrigin = DamageInfo_GetDamagePosition( damageInfo ) -void function RunATGame() + Remote_CallFunction_NonReplay( + player, + "ServerCallback_AT_BossDamageScorePopup", + amount, // damageScore + amount, // damageBonus + bossEHandle, // bossEHandle + damageOrigin.x, // x + damageOrigin.y, // y + damageOrigin.z // z + ) +} + +void function AT_AddPlayerBonusPointsForEntityKilled( entity player, int amount, var damageInfo, int extraBonus = 0 ) { - thread RunATGame_Threaded() + AT_AddPlayerBonusPoints( player, amount + extraBonus ) + + // send servercallback for damaging + int attackerEHandle = player.GetEncodedEHandle() + vector damageOrigin = DamageInfo_GetDamagePosition( damageInfo ) + + Remote_CallFunction_NonReplay( + player, + "ServerCallback_AT_ShowATScorePopup", + attackerEHandle, // attackerEHandle + amount, // damageScore + amount + extraBonus, // damageBonus + damageOrigin.x, // damagePosX + damageOrigin.y, // damagePosX + damageOrigin.z, // damagePosX + 0 // damageType ( not used ) + ) } -void function RunATGame_Threaded() +///////////////////////////////// +///// SCORING FUNCTIONS END ///// +///////////////////////////////// + + + +////////////////////////////// +///// GAMELOOP FUNCTIONS ///// +////////////////////////////// + +void function AT_GameLoop_Threaded() { svGlobal.levelEnt.EndSignal( "GameStateChanged" ) - OnThreadEnd( function() - { - SetGlobalNetBool( "banksOpen", false ) - }) + // game end func + // TODO: Cant seem to be able to get this crash ??? + OnThreadEnd + ( + function() + { + // prevent crash before entity creation on map change + if ( GetGameState() >= eGameState.Prematch ) + { + SetGlobalNetBool( "preBankPhase", false ) + SetGlobalNetBool( "banksOpen", false ) + } + } + ) - wait WAVE_STATE_TRANSITION_TIME // initial wait before first wave - - for ( int waveCount = 1; ; waveCount++ ) + // Initial wait before first wave + wait AT_FIRST_WAVE_START_DELAY - AT_WAVE_TRANSITION_DELAY + + int lastWaveId = -1 + for ( int waveCount = 1; ; waveCount++ ) { - wait WAVE_STATE_TRANSITION_TIME + wait AT_WAVE_TRANSITION_DELAY // cap to number of real waves - int waveId = ( waveCount / 2 ) - // last wave is clearly unfinished so don't use, just cap to last actually used one - if ( waveId >= GetWaveDataSize() - 1 ) + int waveId = ( waveCount - 1 ) / 2 + int waveCapAmount = 2 + waveId = int( min( waveId, GetWaveDataSize() - waveCapAmount ) ) + + // New wave dialogue + bool waveChanged = lastWaveId != waveId + if ( waveChanged ) + { + PlayFactionDialogueToTeam( "bh_newWave", TEAM_IMC ) + PlayFactionDialogueToTeam( "bh_newWave", TEAM_MILITIA ) + } + else // same wave, second half { - waveId = GetWaveDataSize() - 2 - waveCount = waveId * 2 + PlayFactionDialogueToTeam( "bh_incoming", TEAM_IMC ) + PlayFactionDialogueToTeam( "bh_incoming", TEAM_MILITIA ) } + + lastWaveId = waveId SetGlobalNetInt( "AT_currentWave", waveId ) - bool isBossWave = waveCount / float( 2 ) > waveId // odd number waveCount means boss wave + bool isBossWave = waveCount % 2 == 0 // even number waveCount means boss wave // announce the wave foreach ( entity player in GetPlayerArray() ) { if ( isBossWave ) + { Remote_CallFunction_NonReplay( player, "ServerCallback_AT_AnnounceBoss" ) + } else - Remote_CallFunction_NonReplay( player, "ServerCallback_AT_AnnouncePreParty", 0.0, waveId ) + { + Remote_CallFunction_NonReplay( + player, + "ServerCallback_AT_AnnouncePreParty", + 0.0, // endTime ( not used ) + waveId // waveNum + ) + } } - wait WAVE_STATE_TRANSITION_TIME + wait AT_WAVE_TRANSITION_DELAY - // run the wave + // Run the wave + thread AT_CampSpawnThink( waveId, isBossWave ) + + if ( !isBossWave ) + { + svGlobal.levelEnt.WaitSignal( "ATAllCampsClean" ) // signaled when all camps cleaned in spawn functions + } + else + { + wait AT_BOUNTY_TITAN_CHECK_DELAY + // wait until all bounty titans killed + while ( IsAlive( GetGlobalNetEnt( "camp1Ent" ) ) || IsAlive( GetGlobalNetEnt( "camp2Ent" ) ) ) + WaitFrame() + } + + // wave end, prebank phase + svGlobal.levelEnt.Signal( "ATWaveEnd" ) // defensive fix, destroy existing campEnts + SetGlobalNetBool( "preBankPhase", true ) + + wait AT_WAVE_END_ANNOUNCEMENT_DELAY - AT_WaveData wave = GetWaveData( waveId ) - array< array<AT_SpawnData> > campSpawnData + // announce wave end + foreach ( entity player in GetPlayerArray() ) + { + Remote_CallFunction_NonReplay( + player, + "ServerCallback_AT_AnnounceWaveOver", + waveId, // waveNum ( not used ) + 0, // militiaDamageTotal ( not used ) + 0, // imcDamageTotal ( not used ) + 0, // milMVP ( not used ) + 0, // imcMVP ( not used ) + 0, // milMVPDamage ( not used ) + 0 // imcMVPDamage ( not used ) + ) + } + + wait AT_WAVE_TRANSITION_DELAY - if ( isBossWave ) - campSpawnData = wave.bossSpawnData - else - campSpawnData = wave.spawnDataArrays + // banking phase + SetGlobalNetBool( "preBankPhase", false ) + SetGlobalNetTime( "AT_bankStartTime", Time() ) + SetGlobalNetTime( "AT_bankEndTime", Time() + AT_BANKS_OPEN_DURATION ) + SetGlobalNetBool( "banksOpen", true ) + + foreach ( entity player in GetPlayerArray() ) + Remote_CallFunction_NonReplay( player, "ServerCallback_AT_BankOpen" ) + + foreach ( entity bank in file.banks ) + thread AT_BankActiveThink( bank ) + - // initialise pending spawns - foreach ( array< AT_SpawnData > campData in campSpawnData ) + float endTime = Time() + AT_BANKS_OPEN_DURATION + bool forceCloseTriggered = false + // wait until no player is holding bonus, or max wait time + while ( Time() <= endTime ) { - foreach ( AT_SpawnData spawnData in campData ) - spawnData.pendingSpawns = spawnData.totalToSpawn + // If everyone has deposited their bonuses close the banks early + if ( !ATAnyPlayerHasBonus() && !forceCloseTriggered ) + { + forceCloseTriggered = true + endTime = Time() + AT_BANK_FORCE_CLOSE_DELAY + } + + WaitFrame() } - // clear tracked spawns - file.trackedCampNPCSpawns = {} - while ( true ) - { - // if this is ever 0 by the end of this loop, wave is complete - int numActiveCampSpawners = 0 + SetGlobalNetBool( "banksOpen", false ) + foreach ( entity player in GetPlayerArray() ) + Remote_CallFunction_NonReplay( player, "ServerCallback_AT_BankClose" ) + } +} + +bool function ATAnyPlayerHasBonus() +{ + foreach ( entity player in GetPlayerArray() ) + { + if ( AT_GetPlayerBonusPoints( player ) ) + return true + } + return false +} + +////////////////////////////////// +///// GAMELOOP FUNCTIONS END ///// +////////////////////////////////// + + + +////////////////////////// +///// CAMP FUNCTIONS ///// +////////////////////////// + +void function AT_CampSpawnThink( int waveId, bool isBossWave ) +{ + AT_WaveData wave = GetWaveData( waveId ) + array< array<AT_SpawnData> > campSpawnData + + if ( isBossWave ) + campSpawnData = wave.bossSpawnData + else + campSpawnData = wave.spawnDataArrays + + array<AT_WaveOrigin> allCampsToUse + foreach ( AT_WaveOrigin campStruct in file.camps ) + { + if ( campStruct.phaseAllowed[ waveId ] ) + allCampsToUse.append( campStruct ) + } + + // HACK + // There's too many phase3 camps on exoplanet and rise, make sure we always have the correct count + int maxCampsForWave = waveId == 0 ? 1 : 2 + while( allCampsToUse.len() > maxCampsForWave ) + { + // Get the required number of camps + array<AT_WaveOrigin> tempCamps + for( int i = 0; i < maxCampsForWave; i++ ) + tempCamps.append( allCampsToUse[RandomInt( allCampsToUse.len() )] ) - // iterate over camp data for wave - for ( int campIdx = 0; campIdx < campSpawnData.len() && campIdx < file.camps.len(); campIdx++ ) + + // Check if they're intersecting, if they are, try again + bool intersecting = false + for( int i = 0; i < tempCamps.len(); i++ ) + { + AT_WaveOrigin campA = tempCamps[i] + for( int j = 0; j < tempCamps.len(); j++ ) { - if ( !( campIdx in file.trackedCampNPCSpawns ) ) - file.trackedCampNPCSpawns[ campIdx ] <- {} + // Don't compare the same two camps + if( j == i ) + continue + + AT_WaveOrigin campB = tempCamps[j] + + if( Distance( campA.origin, campB.origin ) < campA.radius + campB.radius ) + intersecting = true + } + } + + if( !intersecting ) + allCampsToUse = tempCamps + + // If we ever get really unlucky just wait a frame + WaitFrame() + } + + foreach ( int spawnId, AT_WaveOrigin curCampData in allCampsToUse ) + { + array<AT_SpawnData> curSpawnData = campSpawnData[ spawnId ] + + int totalNPCsToSpawn = 0 + // initialise pending spawns and get total npcs + foreach ( AT_SpawnData spawnData in curSpawnData ) + { + spawnData.pendingSpawns = spawnData.totalToSpawn + // add to network variables + string npcNetVar = GetNPCNetVarName( spawnData.aitype, spawnId ) + SetGlobalNetInt( npcNetVar, spawnData.totalToSpawn ) + + totalNPCsToSpawn += spawnData.totalToSpawn + } + + if ( !isBossWave ) + { + // camp Ent, boss wave will use boss themselves as campEnt + string campEntVarName = "camp" + string( spawnId + 1 ) + "Ent" + bool waveNotActive = GetGlobalNetBool( "preBankPhase" ) || GetGlobalNetBool( "banksOpen" ) + if ( !IsValid( GetGlobalNetEnt( campEntVarName ) ) && !waveNotActive ) + SetGlobalNetEnt( campEntVarName, CreateCampTracker( curCampData, spawnId ) ) - // iterate over ai spawn data for camp - foreach ( AT_SpawnData spawnData in campSpawnData[ campIdx ] ) + array<AT_SpawnData> minionSquadDatas + foreach ( AT_SpawnData data in curSpawnData ) + { + switch ( data.aitype ) { - if ( !( spawnData.aitype in file.trackedCampNPCSpawns[ campIdx ] ) ) - file.trackedCampNPCSpawns[ campIdx ][ spawnData.aitype ] <- 0 - - if ( spawnData.pendingSpawns > 0 || file.trackedCampNPCSpawns[ campIdx ][ spawnData.aitype ] > 0 ) - numActiveCampSpawners++ + case "npc_soldier": + case "npc_spectre": + case "npc_stalker": + if ( !AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK ) + minionSquadDatas.append( data ) + else + thread AT_DroppodSquadEvent_Single( curCampData, spawnId, data ) + break + + case "npc_super_spectre": + thread AT_ReaperEvent( curCampData, spawnId, data ) + break + } + } + + // minions squad spawn + if ( !AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK ) + { + if ( minionSquadDatas.len() > 0 ) + thread AT_DroppodSquadEvent( curCampData, spawnId, minionSquadDatas ) + } + + // use campProgressThink for handling wave state + thread CampProgressThink( spawnId, totalNPCsToSpawn ) + } + else // bosswave spawn + { + foreach ( AT_SpawnData data in curSpawnData ) + { + if( data.aitype != "npc_titan" ) + continue - // try to spawn as many ai as we can, as long as the camp doesn't already have too many spawned - int spawnCount - for ( spawnCount = 0; spawnCount < spawnData.pendingSpawns && spawnCount < spawnData.totalAllowedOnField - file.trackedCampNPCSpawns[ campIdx ][ spawnData.aitype ]; ) - { - // not doing this in a generic way atm, but could be good for the future if we want to support more ai - switch ( spawnData.aitype ) - { - case "npc_soldier": - case "npc_spectre": - case "npc_stalker": - thread AT_SpawnDroppodSquad( campIdx, spawnData.aitype ) - spawnCount += 4 - break - - case "npc_super_spectre": - thread AT_SpawnReaper( campIdx ) - spawnCount += 1 - break - - case "npc_titan": - thread AT_SpawnBountyTitan( campIdx ) - spawnCount += 1 - break - - default: - print( "BOUNTY HUNT: Tried to spawn unsupported ai of type \"" + "\" at camp " + campIdx ) - } + thread AT_BountyTitanEvent( curCampData, spawnId, data ) + break + } + } + } +} + +void function CampProgressThink( int spawnId, int totalNPCsToSpawn ) +{ + string campLetter = GetCampLetter( spawnId ) + string campProgressName = campLetter + "campProgress" + string campEntVarName = "camp" + string( spawnId + 1 ) + "Ent" + + // initial wait + SetGlobalNetFloat( campProgressName, 1.0 ) + + // TODO: random wait, make this a constant ?? + wait 3.0 + + float cleanUpTime = -1.0 + + while ( true ) + { + int npcsLeft + // get all npcs might be in this camp + for ( int i = 0; i < 5; i++ ) + { + string netVarName = string( i + 1 ) + campLetter + "campCount" + int netVarValue = GetGlobalNetInt( netVarName ) + if ( netVarValue >= 0 ) // uninitialized network var starts from -1, avoid checking them + npcsLeft += netVarValue + } + + float campLeft = float( npcsLeft ) / float( totalNPCsToSpawn ) + SetGlobalNetFloat( campProgressName, campLeft ) + + if( npcsLeft <= AT_CAMP_BORED_NPCS_LEFT_TO_START_CLEANUP && cleanUpTime < 0.0 ) + { + cleanUpTime = Time() + AT_CAMP_BORED_CLEANUP_WAIT + print("Cleanup timer started!") + } + + if( Time() > cleanUpTime && cleanUpTime > 0.0 && spawnId in file.campScriptEntArrays ) + { + foreach( int handle in file.campScriptEntArrays[spawnId] ) + { + array<entity> entities = GetScriptManagedEntArray( handle ) + entities.removebyvalue( null ) + foreach ( entity ent in entities ) + { + if ( IsAlive( ent ) && ent.IsNPC() ) + { + printt( "Killing bored AI " + ent.GetClassName() + " at " + ent.GetOrigin() ) + ent.Die() } - - // track spawns - file.trackedCampNPCSpawns[ campIdx ][ spawnData.aitype ] += spawnCount - spawnData.pendingSpawns -= spawnCount } } + } + + if ( campLeft <= 0.0 ) // camp wiped! + { + PlayFactionDialogueToTeam( "bh_cleared" + campLetter, TEAM_IMC ) + PlayFactionDialogueToTeam( "bh_cleared" + campLetter, TEAM_MILITIA ) + + entity campEnt = GetGlobalNetEnt( campEntVarName ) + if ( IsValid( campEnt ) ) + campEnt.Signal( "ATCampClean" ) // destroy the camp ent + + // check if both camps being destroyed + if ( !IsValid( GetGlobalNetEnt( "camp1Ent" ) ) && !IsValid( GetGlobalNetEnt( "camp2Ent" ) ) ) + svGlobal.levelEnt.Signal( "ATAllCampsClean" ) // end the wave - if ( numActiveCampSpawners == 0 ) - break - - wait 0.5 + return } - - wait WAVE_STATE_TRANSITION_TIME - - // banking phase + + WaitFrame() } } // entity funcs +// camp +entity function CreateCampTracker( AT_WaveOrigin campData, int spawnId ) +{ + // store data + vector campOrigin = campData.origin + float campRadius = campData.radius + float campHeight = campData.height + // add a minimap icon + entity mapIconEnt = CreateEntity( "prop_script" ) + DispatchSpawn( mapIconEnt ) + + mapIconEnt.SetOrigin( campOrigin ) + mapIconEnt.DisableHibernation() + SetTeam( mapIconEnt, AT_AI_TEAM ) + mapIconEnt.Minimap_AlwaysShow( TEAM_IMC, null ) + mapIconEnt.Minimap_AlwaysShow( TEAM_MILITIA, null ) + + mapIconEnt.Minimap_SetCustomState( GetCampMinimapState( spawnId ) ) + mapIconEnt.Minimap_SetAlignUpright( true ) + mapIconEnt.Minimap_SetZOrder( MINIMAP_Z_OBJECT ) + mapIconEnt.Minimap_SetObjectScale( campRadius / 16000.0 ) // proper icon on the map + + // attach a location tracker + entity tracker = GetAvailableLocationTracker() + tracker.SetOwner( mapIconEnt ) // needs a owner to show up + tracker.SetOrigin( campOrigin ) + SetLocationTrackerRadius( tracker, campRadius ) + SetLocationTrackerID( tracker, spawnId ) + DispatchSpawn( tracker ) + + thread TrackWaveEndForCampInfo( tracker, mapIconEnt ) + return tracker +} + +void function TrackWaveEndForCampInfo( entity tracker, entity mapIconEnt ) +{ + tracker.EndSignal( "OnDestroy" ) + tracker.EndSignal( "ATCampClean" ) + + OnThreadEnd + ( + function(): ( tracker, mapIconEnt ) + { + // camp cleaned, wave or game ended, destroy the camp info + if ( IsValid( tracker ) ) + tracker.Destroy() + + if ( IsValid( mapIconEnt ) ) + mapIconEnt.Destroy() + } + ) + + WaitSignal( svGlobal.levelEnt, "GameStateChanged", "ATWaveEnd" ) +} + +string function GetCampLetter( int spawnId ) +{ + return spawnId == 0 ? "A" : "B" +} + +int function GetCampMinimapState( int id ) +{ + switch ( id ) + { + case 0: + return eMinimapObject_prop_script.AT_DROPZONE_A + case 1: + return eMinimapObject_prop_script.AT_DROPZONE_B + case 2: + return eMinimapObject_prop_script.AT_DROPZONE_C + } + + unreachable +} + +////////////////////////////// +///// CAMP FUNCTIONS END ///// +////////////////////////////// + + + +////////////////////////// +///// BANK FUNCTIONS ///// +////////////////////////// + +void function AT_BankActiveThink( entity bank ) +{ + svGlobal.levelEnt.EndSignal( "GameStateChanged" ) + bank.EndSignal( "OnDestroy" ) + + // Banks closed + OnThreadEnd + ( + function(): ( bank ) + { + if ( IsValid( bank ) ) + { + // Update use prompt + if ( GetGameState() != eGameState.Playing ) + bank.UnsetUsable() + else + bank.SetUsePrompts( "#AT_USE_BANK_CLOSED", "#AT_USE_BANK_CLOSED" ) + + thread PlayAnim( bank, "mh_active_2_inactive" ) + FadeOutSoundOnEntity( bank, "Mobile_Hardpoint_Idle", 0.5 ) + bank.Minimap_Hide( TEAM_IMC, null ) + bank.Minimap_Hide( TEAM_MILITIA, null ) + } + } + ) + + // Update use prompt to usable + bank.SetUsable() + bank.SetUsePrompts( "#AT_USE_BANK", "#AT_USE_BANK_PC" ) + + thread PlayAnim( bank, "mh_inactive_2_active" ) + EmitSoundOnEntity( bank, "Mobile_Hardpoint_Idle" ) + + // Show minimap icon for bank + bank.Minimap_AlwaysShow( TEAM_IMC, null ) + bank.Minimap_AlwaysShow( TEAM_MILITIA, null ) + bank.Minimap_SetCustomState( eMinimapObject_prop_script.AT_BANK ) + + // Wait for bank close or game end + while ( GetGlobalNetBool( "banksOpen" ) ) + WaitFrame() +} + +function OnPlayerUseBank( bank, player ) +{ + // Banks are always usable so that we can show the use prompt + // Only allow deposit when banks are open + if ( !GetGlobalNetBool( "banksOpen" ) ) + return + + expect entity( bank ) + expect entity( player ) + + // bank.SetUsableByGroup( "pilot" ) didn't seem to work so we just + // exit here if player is in a titan + if( player.IsTitan() ) + return + + // Player has no bonus, try to send a tip using SendHUDMessage + if ( AT_GetPlayerBonusPoints( player ) == 0 ) + { + ATSendDepositTipToPlayer( player, "#AT_USE_BANK_NO_BONUS_HINT" ) + return + } + + // Prevent more than one instance of this thread running + if ( !file.playerBankUploading[ player ] ) + thread PlayerUploadingBonus_Threaded( bank, player ) +} + +bool function ATSendDepositTipToPlayer( entity player, string message ) +{ + if ( Time() < file.playerHudMessageAllowedTime[ player ] ) + return false + + SendHudMessage( player, message, -1, 0.4, 255, 255, 255, 255, 0.5, 1.0, 0.5 ) + file.playerHudMessageAllowedTime[ player ] = Time() + AT_PLAYER_HUD_MESSAGE_COOLDOWN + + return true +} + +struct AT_playerUploadStruct +{ + bool uploadSuccess = false + int depositedPoints = 0 +} + +void function PlayerUploadingBonus_Threaded( entity bank, entity player ) +{ + bank.EndSignal( "OnDestroy" ) + player.EndSignal( "OnDestroy" ) + player.EndSignal( "OnDeath" ) + + file.playerBankUploading[ player ] = true + + // this literally only exists because structs are passed by ref, + // and primitives like ints and bools are passed by val + // which meant that the OnThreadEnd was just getting 0 and false + AT_playerUploadStruct uploadInfo + + // Cleanup and call finish deposit func + OnThreadEnd + ( + function(): ( player, uploadInfo ) + { + if ( IsValid( player ) ) + { + file.playerBankUploading[ player ] = false + + // Clean up looping sound + StopSoundOnEntity( player, "HUD_MP_BountyHunt_BankBonusPts_Ticker_Loop_1P" ) + StopSoundOnEntity( player, "HUD_MP_BountyHunt_BankBonusPts_Ticker_Loop_3P" ) + + // Do medal event + // TODO: Check if vanilla actually do.s this every time you finish depositing??? + AddPlayerScore( player, "AttritionCashedBonus" ) + + // Do server callback + Remote_CallFunction_NonReplay( + player, + "ServerCallback_AT_FinishDeposit", + uploadInfo.depositedPoints // deposit + ) + + player.SetPlayerNetBool( "AT_playerUploading", false ) + + if ( uploadInfo.uploadSuccess ) // Player deposited all remaining bonus + { + // Emit uploading successful sound + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_End_Successful_1P" ) + EmitSoundOnEntityExceptToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_End_Successful_3P" ) + + // player is MVP + int ourScore = player.GetPlayerGameStat( PGS_ASSAULT_SCORE ) + bool isMVP = true + foreach(teamPlayer in GetPlayerArrayOfTeam(player.GetTeam())) + { + if (ourScore < teamPlayer.GetPlayerGameStat( PGS_ASSAULT_SCORE )) + { + isMVP = false + break + } + } + if (isMVP) + PlayFactionDialogueToPlayer( "bh_mvp", player ) + } + else // Player was killed or left the bank radius + { + // Emit uploading failed sound + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_End_Unsuccessful_1P" ) + EmitSoundOnEntityExceptToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_End_Unsuccessful_3P" ) + } + } + } + ) + + // Uploading start sound + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_1P" ) + EmitSoundOnEntityExceptToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Deposit_Start_3P" ) + EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Ticker_Loop_1P" ) + EmitSoundOnEntityExceptToPlayer( player, player, "HUD_MP_BountyHunt_BankBonusPts_Ticker_Loop_3P" ) + + player.SetPlayerNetBool( "AT_playerUploading", true ) + + // Upload bonus while the player is within range of the bank + while ( Distance( player.GetOrigin(), bank.GetOrigin() ) <= AT_BANK_DEPOSIT_RADIUS && GetGlobalNetBool( "banksOpen" ) ) + { + // Calling this moves the "Uploading..." graphic to the same place it is + // in vanilla + Remote_CallFunction_NonReplay( player, "ServerCallback_AT_ShowRespawnBonusLoss" ) + + int bonusToUpload = int( min( AT_BANK_DEPOSIT_RATE, AT_GetPlayerBonusPoints( player ) ) ) + // No more bonus to upload, return + if ( bonusToUpload == 0 ) + { + uploadInfo.uploadSuccess = true + return + } + + // Remove bonus points and add them to total poins + AT_AddPlayerBonusPoints( player, -bonusToUpload ) + AT_AddPlayerTotalPoints( player, bonusToUpload ) + + uploadInfo.depositedPoints += bonusToUpload + WaitFrame() + } +} + +////////////////////////////// +///// BANK FUNCTIONS END ///// +////////////////////////////// -void function AT_SpawnDroppodSquad( int camp, string aiType ) + + +///////////////////////// +///// NPC FUNCTIONS ///// +///////////////////////// + +int function GetScriptManagedNPCArrayLength_Alive( int scriptManagerId ) +{ + array<entity> entities = GetScriptManagedEntArray( scriptManagerId ) + entities.removebyvalue( null ) + int npcsAlive = 0 + foreach ( entity ent in entities ) + { + if ( IsAlive( ent ) && ent.IsNPC() ) + npcsAlive += 1 + } + return npcsAlive +} + +void function AT_DroppodSquadEvent( AT_WaveOrigin campData, int spawnId, array<AT_SpawnData> minionDatas ) +{ + svGlobal.levelEnt.EndSignal( "GameStateChanged" ) + // create a script managed array for all handled minions + int eventManager = CreateScriptManagedEntArray() + + if( !(spawnId in file.campScriptEntArrays) ) + file.campScriptEntArrays[spawnId] <- [] + + file.campScriptEntArrays[spawnId].append(eventManager) + + int totalAllowedOnField = SQUAD_SIZE * AT_DROPPOD_SQUADS_ALLOWED_ON_FIELD + while ( true ) + { + foreach ( AT_SpawnData data in minionDatas ) + { + string ent = data.aitype + waitthread AT_SpawnDroppodSquad( campData, spawnId, ent, eventManager ) + data.pendingSpawns -= SQUAD_SIZE + if ( data.pendingSpawns <= 0 ) // current spawn data has reached max spawn amount + minionDatas.removebyvalue( data ) // remove this data + if ( GetScriptManagedNPCArrayLength_Alive( eventManager ) >= totalAllowedOnField ) // we have enough npcs on field? + break // stop following spawning functions + } + if ( minionDatas.len() == 0 ) // all spawn data has finished spawn + return + + int npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + while ( npcOnFieldCount >= totalAllowedOnField - SQUAD_SIZE ) // wait until we have lost more than 1 squad + { + WaitFrame() + npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + } + } +} + +// for AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK, handles a single spawndata +void function AT_DroppodSquadEvent_Single( AT_WaveOrigin campData, int spawnId, AT_SpawnData data ) +{ + svGlobal.levelEnt.EndSignal( "GameStateChanged" ) + + // get ent and create a script managed array for current event + string ent = data.aitype + int eventManager = CreateScriptManagedEntArray() + + if( !(spawnId in file.campScriptEntArrays) ) + file.campScriptEntArrays[spawnId] <- [] + + file.campScriptEntArrays[spawnId].append(eventManager) + + int totalAllowedOnField = data.totalAllowedOnField // mostly 12 for grunts and spectres, too much! + // start spawner + while ( true ) + { + waitthread AT_SpawnDroppodSquad( campData, spawnId, ent, eventManager ) + data.pendingSpawns -= SQUAD_SIZE + if ( data.pendingSpawns <= 0 ) // we have reached max npcs + return // stop any spawning functions + + int npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + while ( npcOnFieldCount >= totalAllowedOnField - SQUAD_SIZE ) // wait until we have less npcs than allowed count + { + WaitFrame() + npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + } + } +} + +void function AT_SpawnDroppodSquad( AT_WaveOrigin campData, int spawnId, string aiType, int scriptManagerId ) { entity spawnpoint - if ( file.camps[ camp ].dropPodSpawnPoints.len() == 0 ) - spawnpoint = file.camps[ camp ].ent + if ( campData.dropPodSpawnPoints.len() == 0 ) + spawnpoint = campData.ent else - spawnpoint = file.camps[ camp ].dropPodSpawnPoints.getrandom() + spawnpoint = campData.dropPodSpawnPoints.getrandom() + // anti-crash + if ( !IsValid( spawnpoint ) ) + spawnpoint = campData.ent // add variation to spawns wait RandomFloat( 1.0 ) - AiGameModes_SpawnDropPod( spawnpoint.GetOrigin(), spawnpoint.GetAngles(), BH_AI_TEAM, aiType, void function( array<entity> guys ) : ( camp, aiType ) - { - AT_HandleSquadSpawn( guys, camp, aiType ) - }) + AiGameModes_SpawnDropPod( + spawnpoint.GetOrigin(), + spawnpoint.GetAngles(), + AT_AI_TEAM, + aiType, + // squad handler + void function( array<entity> guys ) : ( campData, spawnId, aiType, scriptManagerId ) + { + AT_HandleSquadSpawn( guys, campData, spawnId, aiType, scriptManagerId ) + }, + eDropPodFlag.DISSOLVE_AFTER_DISEMBARKS + ) } -void function AT_HandleSquadSpawn( array<entity> guys, int camp, string aiType ) +void function AT_HandleSquadSpawn( array<entity> guys, AT_WaveOrigin campData, int spawnId, string aiType, int scriptManagerId ) { foreach ( entity guy in guys ) { - guy.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) - - // untrack them on death - thread AT_WaitToUntrackNPC( guy, camp, aiType ) + // TODO: NPCs still seem to go outside their camp ??? + //guy.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) + + // tracking lifetime + AddToScriptManagedEntArray( scriptManagerId, guy ) + thread AT_TrackNPCLifeTime( guy, spawnId, aiType ) + + thread AT_ForceAssaultAroundCamp( guy, campData ) + } +} + +void function AT_ForceAssaultAroundCamp( entity guy, AT_WaveOrigin campData ) +{ + guy.EndSignal( "OnDestroy" ) + guy.EndSignal( "OnDeath" ) + + // goal check + vector ornull goalPos = NavMesh_ClampPointForAI(campData.origin, guy) + goalPos = goalPos == null ? campData.origin : goalPos + expect vector(goalPos) + + float goalRadius = campData.radius / 4 + float guyGoalRadius = guy.GetMinGoalRadius() + if ( guyGoalRadius > goalRadius ) // this npc cannot use forced goal radius? + goalRadius = guyGoalRadius + + while( true ) + { + guy.AssaultPoint( goalPos ) + guy.AssaultSetGoalRadius( goalRadius ) + guy.AssaultSetFightRadius( 0 ) + guy.AssaultSetArrivalTolerance( int(goalRadius) ) + + wait RandomFloatRange( 1, 5 ) + } +} + +void function AT_ReaperEvent( AT_WaveOrigin campData, int spawnId, AT_SpawnData data ) +{ + svGlobal.levelEnt.EndSignal( "GameStateChanged" ) + + // create a script managed array for current event + int eventManager = CreateScriptManagedEntArray() + + if( !(spawnId in file.campScriptEntArrays) ) + file.campScriptEntArrays[spawnId] <- [] + + file.campScriptEntArrays[spawnId].append(eventManager) + + int totalAllowedOnField = 1 // 1 allowed at the same time for heavy armor units + if ( AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK ) + totalAllowedOnField = data.totalAllowedOnField + + while ( true ) + { + waitthread AT_SpawnReaper( campData, spawnId, eventManager ) + data.pendingSpawns -= 1 + if ( data.pendingSpawns <= 0 ) // we have reached max npcs + return // stop any spawning functions + + int npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + while ( npcOnFieldCount >= totalAllowedOnField ) // wait until we have less npcs than allowed count + { + WaitFrame() + npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + } } } -void function AT_SpawnReaper( int camp ) +void function AT_SpawnReaper( AT_WaveOrigin campData, int spawnId, int scriptManagerId ) { entity spawnpoint - if ( file.camps[ camp ].dropPodSpawnPoints.len() == 0 ) - spawnpoint = file.camps[ camp ].ent + if ( campData.dropPodSpawnPoints.len() == 0 ) + spawnpoint = campData.ent else - spawnpoint = file.camps[ camp ].titanSpawnPoints.getrandom() + spawnpoint = campData.dropPodSpawnPoints.getrandom() + // anti-crash + if ( !IsValid( spawnpoint ) ) + spawnpoint = campData.ent // add variation to spawns wait RandomFloat( 1.0 ) - AiGameModes_SpawnReaper( spawnpoint.GetOrigin(), spawnpoint.GetAngles(), BH_AI_TEAM, "npc_super_spectre",void function( entity reaper ) : ( camp ) + AiGameModes_SpawnReaper( + spawnpoint.GetOrigin(), + spawnpoint.GetAngles(), + AT_AI_TEAM, + "npc_super_spectre_aitdm", + // reaper handler + void function( entity reaper ) : ( campData, spawnId, scriptManagerId ) + { + AT_HandleReaperSpawn( reaper, campData, spawnId, scriptManagerId ) + } + ) +} + +void function AT_HandleReaperSpawn( entity reaper, AT_WaveOrigin campData, int spawnId, int scriptManagerId ) +{ + // tracking lifetime + AddToScriptManagedEntArray( scriptManagerId, reaper ) + thread AT_TrackNPCLifeTime( reaper, spawnId, "npc_super_spectre" ) + + thread AT_ForceAssaultAroundCamp( reaper, campData ) +} + +void function AT_BountyTitanEvent( AT_WaveOrigin campData, int spawnId, AT_SpawnData data ) +{ + svGlobal.levelEnt.EndSignal( "GameStateChanged" ) + + // create a script managed array for current event + int eventManager = CreateScriptManagedEntArray() + + int totalAllowedOnField = 1 // 1 allowed at the same time for heavy armor units + if ( AT_USE_TOTAL_ALLOWED_ON_FIELD_CHECK ) + totalAllowedOnField = data.totalAllowedOnField + while ( true ) { - thread AT_WaitToUntrackNPC( reaper, camp, "npc_super_spectre" ) - }) + waitthread AT_SpawnBountyTitan( campData, spawnId, eventManager ) + data.pendingSpawns -= 1 + if ( data.pendingSpawns <= 0 ) // we have reached max npcs + return // stop any spawning functions + + int npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + while ( npcOnFieldCount >= totalAllowedOnField ) // wait until we have less npcs than allowed count + { + WaitFrame() + npcOnFieldCount = GetScriptManagedNPCArrayLength_Alive( eventManager ) + } + } } -void function AT_SpawnBountyTitan( int camp ) +void function AT_SpawnBountyTitan( AT_WaveOrigin campData, int spawnId, int scriptManagerId ) { entity spawnpoint - if ( file.camps[ camp ].dropPodSpawnPoints.len() == 0 ) - spawnpoint = file.camps[ camp ].ent + if ( campData.titanSpawnPoints.len() == 0 ) + spawnpoint = campData.ent else - spawnpoint = file.camps[ camp ].titanSpawnPoints.getrandom() + spawnpoint = campData.titanSpawnPoints.getrandom() + // anti-crash + if ( !IsValid( spawnpoint ) ) + spawnpoint = campData.ent // add variation to spawns wait RandomFloat( 1.0 ) @@ -320,57 +1630,178 @@ void function AT_SpawnBountyTitan( int camp ) int bountyID = 0 try { - bountyID = ReserveBossID( VALID_BOUNTY_TITAN_SETTINGS.getrandom() ) + bountyID = ReserveBossID( AT_BOUNTY_TITANS_AI_SETTINGS.getrandom() ) } catch ( ex ) {} // if we go above the expected wave count that vanilla supports, there's basically no way to ensure that this func won't error, so default 0 after that point string aisettings = GetTypeFromBossID( bountyID ) string titanClass = expect string( Dev_GetAISettingByKeyField_Global( aisettings, "npc_titan_player_settings" ) ) + AiGameModes_SpawnTitan( + spawnpoint.GetOrigin(), + spawnpoint.GetAngles(), + AT_AI_TEAM, + titanClass, + aisettings, + // titan handler + void function( entity titan ) : ( campData, spawnId, bountyID, scriptManagerId ) + { + AT_HandleBossTitanSpawn( titan, campData, spawnId, bountyID, scriptManagerId ) + } + ) +} + +void function AT_HandleBossTitanSpawn( entity titan, AT_WaveOrigin campData, int spawnId, int bountyID, int scriptManagerId ) +{ + // set the bounty to be campEnt, for client tracking + SetGlobalNetEnt( "camp" + string( spawnId + 1 ) + "Ent", titan ) + // set up health + titan.SetMaxHealth( titan.GetMaxHealth() * AT_BOUNTY_TITAN_HEALTH_MULTIPLIER ) + titan.SetHealth( titan.GetMaxHealth() ) + // make minimap always show them and highlight them + titan.Minimap_AlwaysShow( TEAM_IMC, null ) + titan.Minimap_AlwaysShow( TEAM_MILITIA, null ) + thread BountyBossHighlightThink( titan ) + + // set up titan-specific death callbacks, mark it as bounty boss + file.titanIsBountyBoss[ titan ] <- true + file.bountyTitanRewards[ titan ] <- ATTRITION_SCORE_BOSS_DAMAGE + AddEntityCallback_OnPostDamaged( titan, OnBountyTitanPostDamage ) + AddEntityCallback_OnKilled( titan, OnBountyTitanKilled ) - AiGameModes_SpawnTitan( spawnpoint.GetOrigin(), spawnpoint.GetAngles(), BH_AI_TEAM, titanClass, aisettings, void function( entity titan ) : ( camp, bountyID ) + titan.GetTitanSoul().soul.skipDoomState = true + // i feel like this should be localised, but there's nothing for it in r1_english? + titan.SetTitle( GetNameFromBossID( bountyID ) ) + + // tracking lifetime + AddToScriptManagedEntArray( scriptManagerId, titan ) + thread AT_TrackNPCLifeTime( titan, spawnId, "npc_titan" ) +} + +void function BountyBossHighlightThink( entity titan ) +{ + titan.EndSignal( "OnDestroy" ) + titan.EndSignal( "OnDeath" ) + + while ( true ) { - // set up titan-specific death/damage callbacks - AddEntityCallback_OnDamaged( titan, OnBountyDamaged) - AddEntityCallback_OnKilled( titan, OnBountyKilled ) - - titan.GetTitanSoul().soul.skipDoomState = true - // i feel like this should be localised, but there's nothing for it in r1_english? - titan.SetTitle( GetNameFromBossID( bountyID ) ) - thread AT_WaitToUntrackNPC( titan, camp, "npc_titan" ) - } ) + Highlight_SetEnemyHighlight( titan, "enemy_boss_bounty" ) + titan.WaitSignal( "StopPhaseShift" ) // prevent phase shift mess up highlights + } } -// Tracked entities will require their own "wallet" -// for titans it should be used for rounding error compenstation -// for infantry it sould be used to store money if the npc kills a player -void function OnBountyDamaged( entity titan, var damageInfo ) +void function OnBountyTitanPostDamage( entity titan, var damageInfo ) { entity attacker = DamageInfo_GetAttacker( damageInfo ) + if ( !IsValid( attacker ) ) // delayed by projectile shots + return + // damaged by npc or something? if ( !attacker.IsPlayer() ) - attacker = GetLatestAssistingPlayerInfo( titan ).player - - if ( IsValid( attacker ) && attacker.IsPlayer() ) { - int reward = int ( BOUNTY_TITAN_DAMAGE_POOL * DamageInfo_GetDamage( damageInfo ) / titan.GetMaxHealth() ) - printt ( titan.GetMaxHealth(), DamageInfo_GetDamage( damageInfo ) ) - - AT_AddPlayerCash( attacker, reward ) + attacker = GetBountyBossDamageOwner( attacker, titan ) + if ( !IsValid( attacker ) || !attacker.IsPlayer() ) + return } + + int rewardSegment = ATTRITION_SCORE_BOSS_DAMAGE + int healthSegment = titan.GetMaxHealth() / rewardSegment + + // sometimes damage is not enough to add 1 point, we save the damage for player's next attack + if ( !( titan in file.playerSavedBountyDamage[ attacker ] ) ) + file.playerSavedBountyDamage[ attacker ][ titan ] <- 0 + + file.playerSavedBountyDamage[ attacker ][ titan ] += int( DamageInfo_GetDamage( damageInfo ) ) + if ( file.playerSavedBountyDamage[ attacker ][ titan ] < healthSegment ) + return // they can't earn reward from this shot + + int damageSegment = file.playerSavedBountyDamage[ attacker ][ titan ] / healthSegment + int savedDamageLeft = file.playerSavedBountyDamage[ attacker ][ titan ] % healthSegment + file.playerSavedBountyDamage[ attacker ][ titan ] = savedDamageLeft + + float damageFrac = float( damageSegment ) / rewardSegment + int rewardLeft = file.bountyTitanRewards[ titan ] + int reward = int( ATTRITION_SCORE_BOSS_DAMAGE * damageFrac ) + if ( reward >= rewardLeft ) // overloaded shot? + reward = rewardLeft + file.bountyTitanRewards[ titan ] -= reward + + if ( reward > 0 ) + AT_AddPlayerBonusPointsForBossDamaged( attacker, titan, reward, damageInfo ) } -void function OnBountyKilled( entity titan, var damageInfo ) +void function OnBountyTitanKilled( entity titan, var damageInfo ) { entity attacker = DamageInfo_GetAttacker( damageInfo ) + if ( !IsValid( attacker ) ) // delayed by projectile shots + return + // damaged by npc or something? if ( !attacker.IsPlayer() ) - attacker = GetLatestAssistingPlayerInfo( titan ).player + { + attacker = GetBountyBossDamageOwner( attacker, titan ) + if ( !IsValid( attacker ) || !attacker.IsPlayer() ) + return + } + + // add all remaining reward to attacker + // bounty killed bonus handled by AT_PlayerOrNPCKilledScoreEvent() + int rewardLeft = file.bountyTitanRewards[ titan ] + delete file.bountyTitanRewards[ titan ] + if ( rewardLeft > 0 ) + AT_AddPlayerBonusPointsForBossDamaged( attacker, titan, rewardLeft, damageInfo ) + + // remove this bounty's damage saver + foreach ( entity player in GetPlayerArray() ) + { + if ( titan in file.playerSavedBountyDamage[ player ] ) + delete file.playerSavedBountyDamage[ player ][ titan ] + } + + // faction dialogue + int team = attacker.GetTeam() + PlayFactionDialogueToPlayer( "bh_playerKilledBounty", attacker ) + PlayFactionDialogueToTeamExceptPlayer( "bh_bountyClaimedByFriendly", team, attacker ) + PlayFactionDialogueToTeam( "bh_bountyClaimedByEnemy", GetOtherTeam( team ) ) +} + +entity function GetBountyBossDamageOwner( entity attacker, entity titan ) +{ + if ( attacker.IsPlayer() ) // already a player + return attacker - if ( IsValid( attacker ) && attacker.IsPlayer() ) - AT_AddPlayerCash( attacker, BOUNTY_TITAN_KILL_REWARD ) + if ( attacker.IsTitan() ) // attacker is a npc titan + { + // try to find it's pet titan owner + if ( IsValid( GetPetTitanOwner( attacker ) ) ) + return GetPetTitanOwner( attacker ) + } + + // other damages or non-owner npcs, not sure how it happens, just use this titan's last attacker + return GetLatestAssistingPlayerInfo( titan ).player } -void function AT_WaitToUntrackNPC( entity guy, int camp, string aiType ) +void function AT_TrackNPCLifeTime( entity guy, int spawnId, string aiType ) { guy.WaitSignal( "OnDeath", "OnDestroy" ) - file.trackedCampNPCSpawns[ camp ][ aiType ]-- + + string npcNetVar = GetNPCNetVarName( aiType, spawnId ) + SetGlobalNetInt( npcNetVar, GetGlobalNetInt( npcNetVar ) - 1 ) +} + + +// network var +string function GetNPCNetVarName( string className, int spawnId ) +{ + string npcId = string( GetAiTypeInt( className ) + 1 ) + string campLetter = GetCampLetter( spawnId ) + if ( npcId == "0" ) // cannot find this ai support! + { + if ( className == "npc_super_spectre" ) // stupid, reapers are not handled by GetAiTypeInt(), but it must be 4 + return "4" + campLetter + "campCount" + return "" + } + return npcId + campLetter + "campCount" } + +///////////////////////////// +///// NPC FUNCTIONS END ///// +///////////////////////////// diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut index 705b7836..d8b0c9bd 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut @@ -29,6 +29,8 @@ struct { array<HardpointStruct> hardpoints array<CP_PlayerStruct> players + table<entity,int> playerAssaultPoints + table<entity,int> playerDefensePoints } file void function GamemodeCP_Init() @@ -112,11 +114,13 @@ void function GamemodeCP_OnPlayerKilled(entity victim, entity attacker, var dama { AddPlayerScore( attacker , "HardpointDefense", victim ) attacker.AddToPlayerGameStat(PGS_DEFENSE_SCORE,POINTVALUE_HARDPOINT_DEFENSE) + UpdatePlayerScoreForChallenge(attacker,0,POINTVALUE_HARDPOINT_DEFENSE) } else if((victimCP.hardpoint.GetTeam()==victim.GetTeam())||(GetHardpointCappingTeam(victimCP)==victim.GetTeam())) { AddPlayerScore( attacker, "HardpointAssault", victim ) attacker.AddToPlayerGameStat(PGS_ASSAULT_SCORE,POINTVALUE_HARDPOINT_ASSAULT) + UpdatePlayerScoreForChallenge(attacker,POINTVALUE_HARDPOINT_ASSAULT,0) } } } @@ -127,10 +131,12 @@ void function GamemodeCP_OnPlayerKilled(entity victim, entity attacker, var dama { AddPlayerScore( attacker , "HardpointSnipe", victim ) attacker.AddToPlayerGameStat(PGS_ASSAULT_SCORE,POINTVALUE_HARDPOINT_SNIPE) + UpdatePlayerScoreForChallenge(attacker,POINTVALUE_HARDPOINT_SNIPE,0) } else{ AddPlayerScore( attacker , "HardpointSiege", victim ) attacker.AddToPlayerGameStat(PGS_ASSAULT_SCORE,POINTVALUE_HARDPOINT_SIEGE) + UpdatePlayerScoreForChallenge(attacker,POINTVALUE_HARDPOINT_SIEGE,0) } } else if(attackerCP.hardpoint!=null)//Perimeter Defense @@ -138,6 +144,7 @@ void function GamemodeCP_OnPlayerKilled(entity victim, entity attacker, var dama if(attackerCP.hardpoint.GetTeam()==attacker.GetTeam()) AddPlayerScore( attacker , "HardpointPerimeterDefense", victim) attacker.AddToPlayerGameStat(PGS_DEFENSE_SCORE,POINTVALUE_HARDPOINT_PERIMETER_DEFENSE) + UpdatePlayerScoreForChallenge(attacker,0,POINTVALUE_HARDPOINT_PERIMETER_DEFENSE) } foreach(CP_PlayerStruct player in file.players) //Reset Victim Holdtime Counter @@ -308,6 +315,7 @@ void function CapturePointForTeam(HardpointStruct hardpoint, int Team) if(player.IsPlayer()){ AddPlayerScore(player,"ControlPointCapture") player.AddToPlayerGameStat(PGS_ASSAULT_SCORE,POINTVALUE_HARDPOINT_CAPTURE) + UpdatePlayerScoreForChallenge(player,POINTVALUE_HARDPOINT_CAPTURE,0) } } } @@ -319,12 +327,17 @@ void function GamemodeCP_InitPlayer(entity player) playerStruct.timeOnPoints = [0.0,0.0,0.0] playerStruct.isOnHardpoint = false file.players.append(playerStruct) + file.playerAssaultPoints[player] <- 0 + file.playerDefensePoints[player] <- 0 thread PlayerThink(playerStruct) } void function GamemodeCP_RemovePlayer(entity player) { - + if(player in file.playerAssaultPoints) + delete file.playerAssaultPoints[player] + if(player in file.playerDefensePoints) + delete file.playerDefensePoints[player] foreach(index,CP_PlayerStruct playerStruct in file.players) { if(playerStruct.player==player) @@ -376,11 +389,13 @@ void function PlayerThink(CP_PlayerStruct player) { AddPlayerScore(player.player,"ControlPointAmpedHold") player.player.AddToPlayerGameStat( PGS_DEFENSE_SCORE, POINTVALUE_HARDPOINT_AMPED_HOLD ) + UpdatePlayerScoreForChallenge(player.player,0,POINTVALUE_HARDPOINT_AMPED_HOLD) } else { AddPlayerScore(player.player,"ControlPointHold") player.player.AddToPlayerGameStat( PGS_DEFENSE_SCORE, POINTVALUE_HARDPOINT_HOLD ) + UpdatePlayerScoreForChallenge(player.player,0,POINTVALUE_HARDPOINT_HOLD) } } break @@ -471,8 +486,10 @@ void function HardpointThink( HardpointStruct hardpoint ) } else if(cappingTeam==TEAM_UNASSIGNED) // nobody on point { - if((GetHardpointState(hardpoint)==CAPTURE_POINT_STATE_AMPED)||(GetHardpointState(hardpoint)==CAPTURE_POINT_STATE_AMPING)) + if((GetHardpointState(hardpoint)>=CAPTURE_POINT_STATE_AMPED) || (GetHardpointState(hardpoint)==CAPTURE_POINT_STATE_SELF_UNAMPING)) { + if (GetHardpointState(hardpoint) == CAPTURE_POINT_STATE_AMPED) + SetHardpointState(hardpoint,CAPTURE_POINT_STATE_SELF_UNAMPING) // plays a pulsating effect on the UI only when the hardpoint is amped SetHardpointCappingTeam(hardpoint,hardpointEnt.GetTeam()) SetHardpointCaptureProgress(hardpoint,max(1.0,GetHardpointCaptureProgress(hardpoint)-(deltaTime/HARDPOINT_AMPED_DELAY))) if(GetHardpointCaptureProgress(hardpoint)<=1.001) // unamp @@ -546,8 +563,10 @@ void function HardpointThink( HardpointStruct hardpoint ) } else if(file.ampingEnabled)//amping or reamping { - if(GetHardpointState(hardpoint)<CAPTURE_POINT_STATE_AMPING) - SetHardpointState(hardpoint,CAPTURE_POINT_STATE_AMPING) + // i have no idea why but putting it CAPTURE_POINT_STATE_AMPING will say 'CONTESTED' on the UI + // since whether the point is contested is checked above, putting the hardpoint state to a value of 8 fixes it somehow + if(GetHardpointState(hardpoint)<=CAPTURE_POINT_STATE_AMPING) + SetHardpointState( hardpoint, 8 ) SetHardpointCaptureProgress( hardpoint, min( 2.0, GetHardpointCaptureProgress( hardpoint ) + ( deltaTime / HARDPOINT_AMPED_DELAY * capperAmount ) ) ) if(GetHardpointCaptureProgress(hardpoint)==2.0&&!(GetHardpointState(hardpoint)==CAPTURE_POINT_STATE_AMPED)) { @@ -570,6 +589,7 @@ void function HardpointThink( HardpointStruct hardpoint ) { AddPlayerScore(player,"ControlPointAmped") player.AddToPlayerGameStat(PGS_DEFENSE_SCORE,POINTVALUE_HARDPOINT_AMPED) + UpdatePlayerScoreForChallenge(player,0,POINTVALUE_HARDPOINT_AMPED) } } } @@ -645,7 +665,10 @@ void function OnHardpointEntered( entity trigger, entity player ) hardpoint.militiaCappers.append( player ) foreach(CP_PlayerStruct playerStruct in file.players) if(playerStruct.player == player) + { playerStruct.isOnHardpoint = true + player.SetPlayerNetInt( "playerHardpointID", hardpoint.hardpoint.GetHardpointID() ) + } } void function OnHardpointLeft( entity trigger, entity player ) @@ -661,7 +684,10 @@ void function OnHardpointLeft( entity trigger, entity player ) FindAndRemove( hardpoint.militiaCappers, player ) foreach(CP_PlayerStruct playerStruct in file.players) if(playerStruct.player == player) + { playerStruct.isOnHardpoint = false + player.SetPlayerNetInt( "playerHardpointID", 69 ) // an arbitary number to remove the hud from the player + } } string function CaptureStateToString( int state ) @@ -675,6 +701,7 @@ string function CaptureStateToString( int state ) case CAPTURE_POINT_STATE_CAPTURED: return "CAPTURED" case CAPTURE_POINT_STATE_AMPING: + case 8: return "AMPING" case CAPTURE_POINT_STATE_AMPED: return "AMPED" @@ -703,3 +730,26 @@ string function GetHardpointGroup(entity hardpoint) //Hardpoint Entity B on Home return string(hardpoint.kv.hardpointGroup) } + +void function UpdatePlayerScoreForChallenge(entity player,int assaultpoints = 0,int defensepoints = 0) +{ + if(player in file.playerAssaultPoints) + { + file.playerAssaultPoints[player] += assaultpoints + if( file.playerAssaultPoints[player] >= 1000 && !HasPlayerCompletedMeritScore(player) ) + { + AddPlayerScore(player,"ChallengeCPAssault") + SetPlayerChallengeMeritScore(player) + } + } + + if(player in file.playerDefensePoints) + { + file.playerDefensePoints[player] += defensepoints + if( file.playerDefensePoints[player] >= 500 && !HasPlayerCompletedMeritScore(player) ) + { + AddPlayerScore(player,"ChallengeCPDefense") + SetPlayerChallengeMeritScore(player) + } + } +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut index 99f34164..97addc24 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut @@ -26,6 +26,8 @@ void function CaptureTheFlag_Init() { PrecacheModel( CTF_FLAG_MODEL ) PrecacheModel( CTF_FLAG_BASE_MODEL ) + PrecacheParticleSystem( FLAG_FX_FRIENDLY ) + PrecacheParticleSystem( FLAG_FX_ENEMY ) CaptureTheFlagShared_Init() SetSwitchSidesBased( true ) @@ -73,27 +75,20 @@ void function RateSpawnpoints_CTF( int checkClass, array<entity> spawnpoints, in bool function VerifyCTFSpawnpoint( entity spawnpoint, int team ) { // ensure spawnpoints aren't too close to enemy base + vector allyFlagSpot + vector enemyFlagSpot + foreach ( entity spawn in GetEntArrayByClass_Expensive( "info_spawnpoint_flag" ) ) + { + if( spawn.GetTeam() == team ) + allyFlagSpot = spawn.GetOrigin() + else + enemyFlagSpot = spawn.GetOrigin() + } - if ( HasSwitchedSides() ) - team = GetOtherTeam( team ) - - array<entity> startSpawns = SpawnPoints_GetPilotStart( team ) - array<entity> enemyStartSpawns = SpawnPoints_GetPilotStart( GetOtherTeam( team ) ) - - vector averageFriendlySpawns - vector averageEnemySpawns - - foreach ( entity spawn in startSpawns ) - averageFriendlySpawns += spawn.GetOrigin() - - averageFriendlySpawns /= startSpawns.len() - - foreach ( entity spawn in enemyStartSpawns ) - averageEnemySpawns += spawn.GetOrigin() - - averageEnemySpawns /= startSpawns.len() + if( Distance2D( spawnpoint.GetOrigin(), allyFlagSpot ) > Distance2D( spawnpoint.GetOrigin(), enemyFlagSpot ) ) + return false - return Distance2D( spawnpoint.GetOrigin(), averageEnemySpawns ) / Distance2D( averageFriendlySpawns, averageEnemySpawns ) > 0.35 + return true } void function CTFInitPlayer( entity player ) @@ -164,6 +159,9 @@ void function CreateFlags() flag.SetValueForModelKey( CTF_FLAG_MODEL ) SetTeam( flag, flagTeam ) flag.MarkAsNonMovingAttachment() + flag.Minimap_AlwaysShow( TEAM_IMC, null ) // show flag icon on minimap + flag.Minimap_AlwaysShow( TEAM_MILITIA, null ) + flag.Minimap_SetAlignUpright( true ) DispatchSpawn( flag ) flag.SetModel( CTF_FLAG_MODEL ) flag.SetOrigin( spawn.GetOrigin() + < 0, 0, base.GetBoundingMaxs().z * 2 > ) // ensure flag doesn't spawn clipped into geometry @@ -291,7 +289,7 @@ void function GiveFlag( entity player, entity flag ) PlayFactionDialogueToTeamExceptPlayer( "ctf_flagPickupFriendly", player.GetTeam(), player ) MessageToTeam( flag.GetTeam(), eEventNotifications.PlayerHasFriendlyFlag, player, player ) - EmitSoundOnEntityToTeam( flag, "UI_CTF_EnemyGrabFlag", flag.GetTeam() ) + EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_EnemyGrabFlag", flag.GetTeam() ) SetFlagStateForTeam( flag.GetTeam(), eFlagState.Away ) // used for held } @@ -339,14 +337,13 @@ void function DropFlag( entity player, bool realDrop = true ) file.imcCaptureAssistList.append( player ) else file.militiaCaptureAssistList.append( player ) - + // do notifications MessageToPlayer( player, eEventNotifications.YouDroppedTheEnemyFlag ) EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_FlagDrop" ) - + MessageToTeam( player.GetTeam(), eEventNotifications.PlayerDroppedEnemyFlag, player, player ) // todo need a sound here maybe - MessageToTeam( GetOtherTeam( player.GetTeam() ), eEventNotifications.PlayerDroppedFriendlyFlag, player, player ) // todo need a sound here maybe } @@ -417,20 +414,33 @@ void function CaptureFlag( entity player, entity flag ) assistList = file.militiaCaptureAssistList foreach( entity assistPlayer in assistList ) + { if ( player != assistPlayer ) AddPlayerScore( assistPlayer, "FlagCaptureAssist", player ) + if( !HasPlayerCompletedMeritScore( assistPlayer ) ) + { + AddPlayerScore( assistPlayer, "ChallengeCTFCapAssist" ) + SetPlayerChallengeMeritScore( assistPlayer ) + } + } assistList.clear() - + // notifs MessageToPlayer( player, eEventNotifications.YouCapturedTheEnemyFlag ) EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_PlayerScore" ) + if( !HasPlayerCompletedMeritScore( player ) ) + { + AddPlayerScore( player, "ChallengeCTFRetAssist" ) + SetPlayerChallengeMeritScore( player ) + } + MessageToTeam( team, eEventNotifications.PlayerCapturedEnemyFlag, player, player ) EmitSoundOnEntityToTeamExceptPlayer( flag, "UI_CTF_3P_TeamScore", player.GetTeam(), player ) MessageToTeam( GetOtherTeam( team ), eEventNotifications.PlayerCapturedFriendlyFlag, player, player ) - EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_EnemyScore", flag.GetTeam() ) + EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_EnemyScores", flag.GetTeam() ) if ( GameRules_GetTeamScore( team ) == GameMode_GetRoundScoreLimit( GAMETYPE ) - 1 ) { @@ -446,6 +456,9 @@ void function OnPlayerEntersFlagReturnTrigger( entity trigger, entity player ) flag = file.imcFlag else flag = file.militiaFlag + + if( !IsValid( flag ) || !IsValid( player ) ) + return if ( !player.IsPlayer() || player.IsTitan() || player.GetTeam() != flag.GetTeam() || IsFlagHome( flag ) || flag.GetParent() != null ) return @@ -481,6 +494,7 @@ void function TryReturnFlag( entity player, entity flag ) }) player.EndSignal( "FlagReturnEnded" ) + flag.EndSignal( "FlagReturnEnded" ) // avoid multiple players to return one flag at once player.EndSignal( "OnDeath" ) wait CTF_GetFlagReturnTime() @@ -488,12 +502,19 @@ void function TryReturnFlag( entity player, entity flag ) // flag return succeeded // return flag ResetFlag( flag ) - + flag.Signal( "FlagReturnEnded" ) + // do notifications for return MessageToPlayer( player, eEventNotifications.YouReturnedFriendlyFlag ) AddPlayerScore( player, "FlagReturn", player ) player.AddToPlayerGameStat( PGS_DEFENSE_SCORE, 1 ) + if( !HasPlayerCompletedMeritScore( player ) ) + { + AddPlayerScore( player, "ChallengeCTFRetAssist" ) + SetPlayerChallengeMeritScore( player ) + } + MessageToTeam( flag.GetTeam(), eEventNotifications.PlayerReturnedFriendlyFlag, null, player ) EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_TeamReturnsFlag", flag.GetTeam() ) PlayFactionDialogueToTeam( "ctf_flagReturnedFriendly", flag.GetTeam() ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut index 27eef177..4bff6038 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut @@ -6,6 +6,9 @@ void function FFA_Init() ScoreEvent_SetupEarnMeterValuesForMixedModes() AddCallback_OnPlayerKilled( OnPlayerKilled ) + + // modified for northstar + AddCallback_OnClientConnected( OnClientConnected ) } void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) @@ -16,4 +19,18 @@ void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) // why isn't this PGS_SCORE? odd game attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, 1 ) } +} + +// modified for northstar +void function OnClientConnected( entity player ) +{ + thread FFAPlayerScoreThink( player ) // good to have this! instead of DisconnectCallback this could handle a null player +} + +void function FFAPlayerScoreThink( entity player ) +{ + int team = player.GetTeam() + + player.WaitSignal( "OnDestroy" ) // this can handle disconnecting + AddTeamScore( team, -GameRules_GetTeamScore( team ) ) }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut index 9d8f84b5..6d0fd3c7 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut @@ -17,6 +17,7 @@ void function GamemodeFRA_Init() ScoreEvent_SetEarnMeterValues( "PilotBatteryPickup", 0.0, 0.34 ) EarnMeterMP_SetPassiveMeterGainEnabled( false ) PilotBattery_SetMaxCount( 3 ) + SetupGenericFFAChallenge() AddCallback_OnPlayerKilled( FRARemoveEarnMeter ) } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut index 31c85a57..8999231d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut @@ -8,6 +8,8 @@ struct { float lastDamageInfoTime bool shouldDoHighlights + + table< entity, int > pilotstreak } file void function GamemodeLts_Init() @@ -34,6 +36,37 @@ void function GamemodeLts_Init() ClassicMP_SetCustomIntro( ClassicMP_DefaultNoIntro_Setup, ClassicMP_DefaultNoIntro_GetLength() ) ClassicMP_ForceDisableEpilogue( true ) AddCallback_GameStateEnter( eGameState.Playing, WaitForThirtySecondsLeft ) + + AddCallback_OnClientConnected( SetupPlayerLTSChallenges ) //Just to make up the Match Goals tracking + AddCallback_OnClientDisconnected( RemovePlayerLTSChallenges ) //Safety removal of data to prevent crashes + AddCallback_OnPlayerKilled( LTSChallengeForPlayerKilled ) +} + +void function SetupPlayerLTSChallenges( entity player ) +{ + file.pilotstreak[ player ] <- 0 +} + +void function RemovePlayerLTSChallenges( entity player ) +{ + if( player in file.pilotstreak ) + delete file.pilotstreak[ player ] +} + +void function LTSChallengeForPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim == attacker || !attacker.IsPlayer() || GetGameState() != eGameState.Playing ) + return + + if ( victim.IsPlayer() && attacker in file.pilotstreak ) + { + file.pilotstreak[attacker]++ + if( file.pilotstreak[attacker] >= 2 && !HasPlayerCompletedMeritScore( attacker ) ) + { + AddPlayerScore( attacker, "ChallengeLTS" ) + SetPlayerChallengeMeritScore( attacker ) + } + } } void function WaitForThirtySecondsLeft() diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut index 659dbb7a..768bbde1 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut @@ -180,6 +180,12 @@ void function MarkPlayers( entity imcMark, entity militiaMark ) entity livingMark = GetMarked( GetOtherTeam( deadMark.GetTeam() ) ) livingMark.SetPlayerGameStat( PGS_DEFENSE_SCORE, livingMark.GetPlayerGameStat( PGS_DEFENSE_SCORE ) + 1 ) + if( !HasPlayerCompletedMeritScore( livingMark ) ) + { + AddPlayerScore( livingMark, "ChallengeMFD" ) + SetPlayerChallengeMeritScore( livingMark ) + } + // thread this so we don't kill our own thread thread AddTeamScore( livingMark.GetTeam(), 1 ) } @@ -188,10 +194,22 @@ void function UpdateMarksForKill( entity victim, entity attacker, var damageInfo { if ( victim == GetMarked( victim.GetTeam() ) ) { - MessageToAll( eEventNotifications.MarkedForDeathKill, null, victim, attacker.GetEncodedEHandle() ) + // handle suicides. Not sure what the actual message is that vanilla shows for this + // but this will prevent crashing for now + bool isSuicide = IsSuicide( victim, attacker, DamageInfo_GetDamageSourceIdentifier( damageInfo ) ) + entity actualAttacker = isSuicide ? victim : attacker + + MessageToAll( eEventNotifications.MarkedForDeathKill, null, victim, actualAttacker.GetEncodedEHandle() ) svGlobal.levelEnt.Signal( "MarkKilled", { mark = victim } ) - if ( attacker.IsPlayer() ) + if ( !isSuicide && attacker.IsPlayer() ) + { attacker.SetPlayerGameStat( PGS_ASSAULT_SCORE, attacker.GetPlayerGameStat( PGS_ASSAULT_SCORE ) + 1 ) + if( !HasPlayerCompletedMeritScore( attacker ) ) + { + AddPlayerScore( attacker, "ChallengeMFD" ) + SetPlayerChallengeMeritScore( attacker ) + } + } } }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut index 57355ad8..c91c27d1 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut @@ -19,6 +19,7 @@ void function GamemodePs_Init() AddCallback_OnPlayerKilled( GiveScoreForPlayerKill )
ScoreEvent_SetupEarnMeterValuesForMixedModes()
SetTimeoutWinnerDecisionFunc( CheckScoreForDraw )
+ SetupGenericFFAChallenge()
// spawnzone stuff
SetShouldCreateMinimapSpawnZones( true )
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut index cb277b00..4617476e 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut @@ -18,6 +18,7 @@ void function GamemodeSpeedball_Init() Riff_ForceTitanAvailability( eTitanAvailability.Never ) Riff_ForceSetEliminationMode( eEliminationMode.Pilots ) ScoreEvent_SetupEarnMeterValuesForMixedModes() + SetupGenericFFAChallenge() AddSpawnCallbackEditorClass( "script_ref", "info_speedball_flag", CreateFlag ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut index 5c0e6fec..61ede2d4 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut @@ -6,6 +6,7 @@ void function GamemodeTdm_Init() AddCallback_OnPlayerKilled( GiveScoreForPlayerKill )
ScoreEvent_SetupEarnMeterValuesForMixedModes()
SetTimeoutWinnerDecisionFunc( CheckScoreForDraw )
+ SetupGenericTDMChallenge()
}
void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo )
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut index 6b30a399..3ba84394 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut @@ -2,6 +2,11 @@ global function GamemodeTTDM_Init const float TTDMIntroLength = 15.0
+struct
+{
+ table< entity, int > challengeCount
+} file
+
void function GamemodeTTDM_Init()
{
Riff_ForceSetSpawnAsTitan( eSpawnAsTitan.Always )
@@ -14,6 +19,8 @@ void function GamemodeTTDM_Init() ClassicMP_ForceDisableEpilogue( true )
SetTimeoutWinnerDecisionFunc( CheckScoreForDraw )
+ AddCallback_OnClientConnected( SetupPlayerTTDMChallenges ) //Just to make up the Match Goals tracking
+ AddCallback_OnClientDisconnected( RemovePlayerTTDMChallenges ) //Safety removal of data to prevent crashes
AddCallback_OnPlayerKilled( AddTeamScoreForPlayerKilled ) // dont have to track autotitan kills since you cant leave your titan in this mode
// probably needs scoreevent earnmeter values
@@ -56,6 +63,17 @@ void function TTDMIntroShowIntermissionCam( entity player ) thread PlayerWatchesTTDMIntroIntermissionCam( player )
}
+void function SetupPlayerTTDMChallenges( entity player )
+{
+ file.challengeCount[ player ] <- 0
+}
+
+void function RemovePlayerTTDMChallenges( entity player )
+{
+ if( player in file.challengeCount )
+ delete file.challengeCount[ player ]
+}
+
void function PlayerWatchesTTDMIntroIntermissionCam( entity player )
{
player.EndSignal( "OnDestroy" )
@@ -79,6 +97,19 @@ void function AddTeamScoreForPlayerKilled( entity victim, entity attacker, var d if ( victim == attacker || !victim.IsPlayer() || !attacker.IsPlayer() && GetGameState() == eGameState.Playing )
return
+ if( victim in file.challengeCount )
+ file.challengeCount[victim] = 0
+
+ if( attacker in file.challengeCount )
+ {
+ file.challengeCount[attacker]++
+ if( file.challengeCount[attacker] >= 2 && !HasPlayerCompletedMeritScore( attacker ) )
+ {
+ AddPlayerScore( attacker, "ChallengeTTDM" )
+ SetPlayerChallengeMeritScore( attacker )
+ }
+ }
+
AddTeamScore( GetOtherTeam( victim.GetTeam() ), 1 )
}
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut index 4e8f85ac..9057f7d8 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut @@ -8,6 +8,7 @@ global function PlayerInventory_EndCriticalSectionForWeaponOnEndFrame global function PlayerInventory_PushInventoryItem global function PlayerInventory_PushInventoryItemByBurnRef global function PlayerInventory_PopInventoryItem +global function PlayerInventory_TakeAllInventoryItems global function PlayerInventory_CountBurnRef struct @@ -19,6 +20,7 @@ void function Sv_ItemInventory_Init() { AddCallback_OnClientConnected( Sv_ItemInventory_OnClientConnected ) AddCallback_OnPlayerGetsNewPilotLoadout( Sv_ItemInventory_OnPlayerGetsNewPilotLoadout ) + AddCallback_GameStateEnter( eGameState.Prematch, PrematchClearInventory ) } void function Sv_ItemInventory_OnClientConnected( entity player ) @@ -26,13 +28,21 @@ void function Sv_ItemInventory_OnClientConnected( entity player ) file.playerInventoryStacks[ player ] <- [] } +void function PrematchClearInventory() // vanilla behavior +{ + foreach( entity player in GetPlayerArray() ) + { + PlayerInventory_TakeAllInventoryItems( player ) + } +} + void function Sv_ItemInventory_OnPlayerGetsNewPilotLoadout( entity player, PilotLoadoutDef newPilotLoadout ) { array<InventoryItem> playerInventoryStack = file.playerInventoryStacks[ player ] if (playerInventoryStack.len() > 0) { InventoryItem topInventoryItem = playerInventoryStack[playerInventoryStack.len() - 1] - PlayerInventory_GiveInventoryItem(player, topInventoryItem) + thread PlayerInventory_GiveInventoryItem(player, topInventoryItem) } return @@ -68,13 +78,25 @@ int function PlayerInventory_CountBurnRef( entity player, string burnRef ) void function PlayerInventory_TakeInventoryItem( entity player ) { + player.EndSignal( "OnDestroy" ) entity preexistingWeapon = player.GetOffhandWeapon( OFFHAND_INVENTORY ) - if ( IsValid( preexistingWeapon ) ) - player.TakeWeaponNow( preexistingWeapon.GetWeaponClassName() ) + + if( !IsValid( preexistingWeapon ) ) + return + preexistingWeapon.EndSignal( "OnDestroy" ) + if( preexistingWeapon.GetWeaponClassName() == "mp_ability_burncardweapon" ) + { + var fireTime = preexistingWeapon.GetWeaponInfoFileKeyField( "fire_anim_rate" ) + if( fireTime ) + wait fireTime + } + player.TakeWeaponNow( preexistingWeapon.GetWeaponClassName() ) } void function PlayerInventory_GiveInventoryItem( entity player, InventoryItem inventoryItem ) { + player.EndSignal( "OnDestroy" ) + array<string> mods = [] if ( inventoryItem.itemType == eInventoryItemType.burnmeter ) { @@ -84,7 +106,10 @@ void function PlayerInventory_GiveInventoryItem( entity player, InventoryItem in } // ensure inventory slot isn't full to avoid crash - PlayerInventory_TakeInventoryItem( player ) + waitthread PlayerInventory_TakeInventoryItem( player ) + entity preexistingWeapon = player.GetOffhandWeapon( OFFHAND_INVENTORY ) // defensive fix + if( IsValid( preexistingWeapon ) ) + player.TakeWeaponNow( preexistingWeapon.GetWeaponClassName() ) player.GiveOffhandWeapon( inventoryItem.weaponRef, OFFHAND_INVENTORY, mods ) } @@ -94,7 +119,7 @@ void function PlayerInventory_PushInventoryItem( entity player, InventoryItem in file.playerInventoryStacks[ player ].append(inventoryItem) player.SetPlayerNetInt( "itemInventoryCount", file.playerInventoryStacks[ player ].len() ) - PlayerInventory_GiveInventoryItem(player, inventoryItem) + thread PlayerInventory_GiveInventoryItem(player, inventoryItem) } void function PlayerInventory_PushInventoryItemByBurnRef( entity player, string burnRef ) @@ -117,15 +142,23 @@ void function PlayerInventory_PopInventoryItem( entity player ) if (playerInventoryStack.len() > 0) { InventoryItem nextInventoryItem = playerInventoryStack[playerInventoryStack.len() - 1] - PlayerInventory_GiveInventoryItem(player, nextInventoryItem) + thread PlayerInventory_GiveInventoryItem( player, nextInventoryItem ) } else { - PlayerInventory_TakeInventoryItem( player ) + waitthread PlayerInventory_TakeInventoryItem( player ) } } return } +void function PlayerInventory_TakeAllInventoryItems( entity player ) +{ + file.playerInventoryStacks[ player ].clear() + waitthread PlayerInventory_TakeInventoryItem( player ) + player.SetPlayerNetInt( "itemInventoryCount", 0 ) + return +} + void function PlayerInventory_RefreshEquippedState( entity player ) { @@ -139,4 +172,4 @@ void function PlayerInventory_StartCriticalSection( entity player ) void function PlayerInventory_EndCriticalSectionForWeaponOnEndFrame( entity weapon ) { -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut index ae933b71..8b65ec93 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut @@ -14,6 +14,7 @@ void function Lobby_Init() { // non-private lobby clientcommands AddClientCommandCallback( "StartPrivateMatchSearch", ClientCommandCallback_StartPrivateMatchSearch ) + AddClientCommandCallback( "SetAnnouncementVersionSeen", ClientCommandCallback_SetAnnouncementVersionSeen ) } } @@ -37,3 +38,14 @@ bool function ClientCommandCallback_StartPrivateMatchSearch( entity player, arra return true } + +bool function ClientCommandCallback_SetAnnouncementVersionSeen( entity player, array<string> args ) +{ + if ( args.len() < 1 ) + return false + + int version = int( args[0] ) + + player.SetPersistentVar( "announcementVersionSeen", version ) + return true +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut index c410869e..0a28031a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut @@ -38,14 +38,14 @@ void function SetupPrivateMatchUIVarsWhenReady() bool function ClientCommandCallback_PrivateMatchLaunch( entity player, array<string> args ) { if ( GetConVarBool( "ns_private_match_only_host_can_start" ) ) - if ( !NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) + if ( !NSIsPlayerLocalPlayer( player ) ) return true - PlayerChangedTheGame( player , " changed the game state." , args ) + LogPrivateMatchChange( player , " changed the game state." , args ) if ( file.startState == ePrivateMatchStartState.STARTING ) { - PlayerChangedTheGame( player , " canceled the game countdown." , args ) + LogPrivateMatchChange( player , " canceled the game countdown." , args ) // cancel start if we're already mid-countdown file.startState = ePrivateMatchStartState.READY @@ -54,7 +54,7 @@ bool function ClientCommandCallback_PrivateMatchLaunch( entity player, array<str } else { - PlayerChangedTheGame( player , " started the game countdown." , args ) + LogPrivateMatchChange( player , " started the game countdown." , args ) // start match file.startState = ePrivateMatchStartState.STARTING @@ -73,10 +73,10 @@ bool function ClientCommandCallback_PrivateMatchSetMode( entity player, array<st return true if ( GetConVarInt( "ns_private_match_only_host_can_change_settings" ) == 2 ) - if ( !NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) + if ( !NSIsPlayerLocalPlayer( player ) ) return true - PlayerChangedTheGame( player , " changed the mode to " , args ) + LogPrivateMatchChange( player , " changed the mode to " , args ) // todo: need to verify this value file.mode = args[0] @@ -97,10 +97,10 @@ bool function ClientCommandCallback_SetCustomMap( entity player, array<string> a return true if ( GetConVarInt( "ns_private_match_only_host_can_change_settings" ) == 2 ) - if ( !NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) + if ( !NSIsPlayerLocalPlayer( player ) ) return true - PlayerChangedTheGame( player , " changed the map to " , args ) + LogPrivateMatchChange( player , " changed the map to " , args ) // todo: need to verify this value file.map = args[0] @@ -217,10 +217,10 @@ bool function ClientCommandCallback_PrivateMatchSetPlaylistVarOverride( entity p return true if ( GetConVarInt( "ns_private_match_only_host_can_change_settings" ) >= 1 ) - if ( !NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) + if ( !NSIsPlayerLocalPlayer( player ) ) return true - PlayerChangedTheGame( player , " override the setting " , args ) + LogPrivateMatchChange( player , " override the setting " , args ) bool found = false foreach ( string category in GetPrivateMatchSettingCategories() ) @@ -244,23 +244,21 @@ bool function ClientCommandCallback_PrivateMatchSetPlaylistVarOverride( entity p bool function ClientCommandCallback_ResetMatchSettingsToDefault( entity player, array<string> args ) { if ( GetConVarInt( "ns_private_match_only_host_can_change_settings" ) >= 1 ) - if ( !NSIsPlayerIndexLocalPlayer( player.GetPlayerIndex() ) ) + if ( !NSIsPlayerLocalPlayer( player ) ) return true - PlayerChangedTheGame( player , " reset to default" , args ) + LogPrivateMatchChange( player , " reset to default" , args ) ClearPlaylistVarOverrides() return true } -void function PlayerChangedTheGame( entity player , string step , array<string> args ){ - if( step.find( "mode" ) || step.find( "map" )){ +void function LogPrivateMatchChange( entity player , string step , array<string> args ) +{ + if( step.find( "mode" ) || step.find( "map" ) ) print( player.GetPlayerName() + step + args[ 0 ] + ".---" + "UID:" +player.GetUID() ) - } - else if(step.find("setting")){ + else if ( step.find( "setting" ) ) print( player.GetPlayerName() + step + args[ 0 ] + " to "+ args[ 1 ] + ".---" + "UID:" +player.GetUID() ) - } - else{ + else print( player.GetPlayerName() + step + ".---" + "UID:" + player.GetUID()) - } }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut index ccccefaf..d2be2ab4 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut @@ -17,6 +17,7 @@ void function PrivateMatchModesInit() AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_PILOT", "boosts_enabled", [ "#SETTING_DEFAULT", "#SETTING_DISABLED" ], "1" ) AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_PILOT", "earn_meter_pilot_overdrive", [ "#SETTING_DISABLED", "#SETTING_ENABLED", "Only" ], "1" ) AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_PILOT", "earn_meter_pilot_multiplier", "1.0" ) + AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_PILOT", "player_force_respawn", "5" ) AddPrivateMatchModeSettingArbitrary( "#MODE_SETTING_CATEGORY_TITAN", "earn_meter_titan_multiplier", "1.0" ) AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_TITAN", "aegis_upgrades", [ "#SETTING_DISABLED", "#SETTING_ENABLED" ], "0" ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut index a4c6e187..362407b3 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut @@ -1412,15 +1412,28 @@ void function CodeCallback_WeaponFireInCloak( entity player ) //player.SetCloakFlicker( 1.0, 2.0 ) DisableCloak( player, 0.5 ) - entity weapon = player.GetOffhandWeapon( OFFHAND_LEFT ) - //printt( "weapon", weapon.GetWeaponClassName() ) - // JFS; need code feature to properly reset next attack time/cooldown stuff - if ( IsValid( weapon ) && weapon.GetWeaponClassName() == "mp_ability_cloak" ) + entity cloakWeapon + int offhandSlot + for ( int i = 0; i <= OFFHAND_MELEE; i++ ) // OFFHAND_MELEE is the largest { - player.TakeOffhandWeapon( OFFHAND_LEFT ) - player.GiveOffhandWeapon( "mp_ability_cloak", OFFHAND_LEFT ) - weapon = player.GetOffhandWeapon( OFFHAND_LEFT ) - weapon.SetWeaponPrimaryClipCountAbsolute( 0 ) + entity nowWeapon = player.GetOffhandWeapon( i ) + if( IsValid( nowWeapon )) + { + if( nowWeapon.GetWeaponClassName() == "mp_ability_cloak" ) + { + cloakWeapon = nowWeapon + offhandSlot = i + } + } + } + if( IsValid( cloakWeapon ) ) + { + array<string> mods = cloakWeapon.GetMods() + // can't reset cooldown properly in script, let's give player a empty one + player.TakeWeapon( "mp_ability_cloak" ) // not using TakeWeaponNow() to fit vanilla behavior + player.GiveOffhandWeapon( "mp_ability_cloak", offhandSlot, mods ) + cloakWeapon = player.GetOffhandWeapon( offhandSlot ) + cloakWeapon.SetWeaponPrimaryClipCountAbsolute( 0 ) } } else diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut index 1c53167f..b77a37b2 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut @@ -19,6 +19,8 @@ global function ShouldEntTakeDamage_SPMP global function GetTitanBuildTime global function TitanPlayerHotDropsIntoLevel +global function SetRecalculateRespawnAsTitanStartPointCallback + struct { bool killcamsEnabled = true bool playerDeathsHidden = false @@ -26,6 +28,8 @@ struct { entity intermissionCamera array<entity> specCams + + entity functionref( entity player, entity basePoint ) recalculateRespawnAsTitanStartPointCallback } file void function BaseGametype_Init_MPSP() @@ -39,6 +43,8 @@ void function BaseGametype_Init_MPSP() AddCallback_OnPlayerKilled( CheckForAutoTitanDeath ) RegisterSignal( "PlayerRespawnStarted" ) RegisterSignal( "KillCamOver" ) + + FlagInit( "WeaponDropsAllowed", true ) } void function SetIntermissionCamera( entity camera ) @@ -130,6 +136,15 @@ void function CodeCallback_OnClientConnectionCompleted( entity player ) Lobby_OnClientConnectionCompleted( player ) return } + else if ( !IsFDMode( GAMETYPE ) ) + { + // reset this for non-fd modes + // for some reason the postgame scoreboard uses this to + // determine if it should show the FD aegis rank one + // FD should either set this in their own mode, or add an else + // to this if statement when it releases + player.SetPersistentVar( "lastFDTitanRef", "" ) + } player.hasConnected = true @@ -270,6 +285,9 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga ClearRespawnAvailable( player ) + // reset this so that we default to pilot spawn + player.SetPersistentVar( "spawnAsTitan", false ) + OnThreadEnd( function() : ( player ) { if ( !IsValid( player ) ) @@ -279,6 +297,10 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga }) entity attacker = DamageInfo_GetAttacker( damageInfo ) + entity inflictor = DamageInfo_GetInflictor( damageInfo ) + int eHandle = attacker.GetEncodedEHandle() + if ( inflictor && ShouldTryUseProjectileReplay( player, attacker, damageInfo, false ) ) + eHandle = inflictor.GetEncodedEHandle() int methodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo ) table<int, bool> alreadyAssisted @@ -298,6 +320,9 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga attackerInfo.attacker.AddToPlayerGameStat( PGS_ASSISTS, 1 ) } } + + if( attacker.IsPlayer() ) + Highlight_SetDeathRecapHighlight( attacker, "killer_outline" ) } player.p.rematchOrigin = player.p.deathOrigin @@ -355,7 +380,7 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga if ( "respawnTime" in attacker.s ) respawnTime = Time() - expect float ( attacker.s.respawnTime ) - thread PlayerWatchesKillReplayWrapper( player, attacker, respawnTime, timeOfDeath, beforeTime, replayTracker ) + thread PlayerWatchesKillReplayWrapper( player, attacker, eHandle, respawnTime, timeOfDeath, beforeTime, replayTracker ) } player.SetPlayerSettings( "spectator" ) // prevent a crash with going from titan => pilot on respawn @@ -372,6 +397,13 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga SetRespawnAvailable( player ) wait respawnDelay + + int forceRespawn = GetCurrentPlaylistVarInt( "player_force_respawn", -1 ) + + // -1 is disabled, anything over is the time we wait in seconds + // before respawning the player + if( forceRespawn >= 0 ) + thread ForceRespawnMeSignalAfterDelay( player, forceRespawn ) player.WaitSignal( "RespawnMe" ) // set in base_gametype: ClientCommand_RespawnPlayer @@ -391,7 +423,22 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga } } -void function PlayerWatchesKillReplayWrapper( entity player, entity attacker, float timeSinceAttackerSpawned, float timeOfDeath, float beforeTime, table replayTracker ) +// idk if this is a good delay or if it matches vanilla +void function ForceRespawnMeSignalAfterDelay( entity player, int delay = 5 ) +{ + player.EndSignal( "RespawnMe" ) + player.EndSignal( "OnDestroy" ) + + if( player.IsWatchingKillReplay() ) + player.WaitSignal( "KillCamOver" ) + + wait delay + + printt( format( "Forcing player respawn for player %s (took >%d seconds to respawn)", player.GetPlayerName(), delay ) ) + player.Signal( "RespawnMe" ) +} + +void function PlayerWatchesKillReplayWrapper( entity player, entity attacker, int eHandle, float timeSinceAttackerSpawned, float timeOfDeath, float beforeTime, table replayTracker ) { player.EndSignal( "RespawnMe" ) player.EndSignal( "OnRespawned" ) @@ -414,7 +461,7 @@ void function PlayerWatchesKillReplayWrapper( entity player, entity attacker, fl }) player.SetPredictionEnabled( false ) - PlayerWatchesKillReplay( player, attacker.GetEncodedEHandle(), attacker.GetIndexForEntity(), timeSinceAttackerSpawned, timeOfDeath, beforeTime, replayTracker ) + PlayerWatchesKillReplay( player, eHandle, attacker.GetIndexForEntity(), timeSinceAttackerSpawned, timeOfDeath, beforeTime, replayTracker ) } void function DecideRespawnPlayer( entity player ) @@ -424,16 +471,25 @@ void function DecideRespawnPlayer( entity player ) void function RespawnAsPilot( entity player ) { + // respawn crash exploit hotfix + if(IsAlive( player )) return + player.RespawnPlayer( FindSpawnPoint( player, false, ( ShouldStartSpawn( player ) || Flag( "ForceStartSpawn" ) ) && !IsFFAGame() ) ) } void function RespawnAsTitan( entity player, bool manualPosition = false ) { + // respawn crash exploit hotfix + if(IsAlive( player )) return + player.Signal( "PlayerRespawnStarted" ) player.isSpawning = true entity spawnpoint = FindSpawnPoint( player, true, ( ShouldStartSpawn( player ) || Flag( "ForceStartSpawn" ) ) && !IsFFAGame() ) + if ( file.recalculateRespawnAsTitanStartPointCallback != null ) + spawnpoint = file.recalculateRespawnAsTitanStartPointCallback( player, spawnpoint ) + TitanLoadoutDef titanLoadout = GetTitanLoadoutForPlayer( player ) asset model = GetPlayerSettingsAssetForClassName( titanLoadout.setFile, "bodymodel" ) @@ -447,7 +503,20 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) AddCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING ) // hide hud // do titanfall scoreevent - AddPlayerScore( player, "Titanfall", player ) + if ( !level.firstTitanfall ) + { + AddPlayerScore( player, "FirstTitanfall", player ) + + #if HAS_STATS + UpdatePlayerStat( player, "misc_stats", "titanFallsFirst" ) + #endif + + level.firstTitanfall = true + } + else + { + AddPlayerScore( player, "Titanfall", player ) + } entity camera = CreateTitanDropCamera( spawnpoint.GetAngles(), < 90, titan.GetAngles().y, 0 > ) camera.SetParent( titan ) @@ -478,7 +547,7 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) titan.Destroy() // pilotbecomestitan leaves an npc titan that we need to delete else RespawnAsPilot( player ) // this is 100% an edgecase, just avoid softlocking if we ever hit it in playable gamestates - + camera.Fire( "Disable", "!activator", 0, player ) camera.Destroy() }) @@ -487,6 +556,7 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) player.RespawnPlayer( null ) // spawn player as pilot so they get their pilot loadout on embark player.SetOrigin( titan.GetOrigin() ) + ClearTitanAvailable( player ) // titanfall succeed, clear titan availability // don't make player titan when entity batteryContainer is not valid. // This will prevent a servercrash that sometimes occur when evac is disabled and somebody is calling a titan in the defeat screen. @@ -555,10 +625,19 @@ void function CheckForAutoTitanDeath( entity victim, entity attacker, var damage } } +void function SetRecalculateRespawnAsTitanStartPointCallback( entity functionref( entity player, entity basePoint ) callbackFunc ) +{ + file.recalculateRespawnAsTitanStartPointCallback = callbackFunc +} + // stuff to change later bool function ShouldEntTakeDamage_SPMP( entity ent, var damageInfo ) { + // dropships are immune to being crushed + if ( ( IsDropship( ent ) || IsEvacDropship( ent ) ) && IsTitanCrushDamage( damageInfo ) ) + return false + return true } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut index 37b89169..ea88c1bc 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut @@ -1 +1,219 @@ -//fuck
\ No newline at end of file +untyped +global function InitTurretBatteryPort // only for fw turrets! + +void function InitTurretBatteryPort( entity batteryPort ) +{ + + batteryPort.s.beingUsed <- false // bool + batteryPort.s.hackAvaliable <- true // bool, for controlling hacking avaliablity + + // SetUsableByGroup() updates is done in TurretStateWatcher() + batteryPort.SetUsableByGroup( "pilot" ) // show hind to any pilots + batteryPort.SetUsePrompts( "#RODEO_APPLY_BATTERY_HINT", "#RODEO_APPLY_BATTERY_HINT" ) // don't know what to use + AddCallback_OnUseEntity( batteryPort, OnUseTurretBatteryPort ) +} + +function OnUseTurretBatteryPort( entBeingUse, user ) +{ + expect entity( entBeingUse ) + expect entity( user ) + + //print( "try to use batteryPort" ) + thread TryUseTurretBatteryPort( user, entBeingUse ) +} + +void function TryUseTurretBatteryPort( entity player, entity batteryPort ) +{ + if( batteryPort.s.beingUsed ) // already being using + return + + player.EndSignal( "OnDeath" ) + player.EndSignal( "OnDestroy" ) + player.EndSignal( "ScriptAnimStop" ) // so you can jump off animation + AddButtonPressedPlayerInputCallback( player, IN_JUMP, ForceStopUseBatteryPort ) + + OnThreadEnd( + function():( player ) + { + RemoveButtonPressedPlayerInputCallback( player, IN_JUMP, ForceStopUseBatteryPort ) + } + ) + + + var BatteryPortUsable = batteryPort.s.isUsable + + if( expect bool( BatteryPortUsable( batteryPort, player ) ) ) + { + // friendly try to apply one, or enemy try to hack this turret + waitthread PlayerApplesBatteryPackToPort( player, batteryPort ) + } +} + +void function ForceStopUseBatteryPort( entity player ) +{ + player.Signal( "ScriptAnimStop" ) +} + +void function PlayerApplesBatteryPackToPort( entity player, entity batteryPort ) +{ + table result = {} + result.success <- false + batteryPort.s.beingUsed = true + + BatteryPortSequenceStruct dataStruct = DisableCloakBeforeBatteryPortSequence( player ) + + // these are from _rodeo_titan.gnut + entity battery = GetBatteryOnBack( player ) + battery.Hide() //Hide it because the animation has a battery model already + Battery_StopFX( battery ) + + entity tempBattery3p + tempBattery3p = CreatePropDynamic( RODEO_BATTERY_MODEL_FOR_RODEO_ANIMS ) + tempBattery3p.SetParent( player, "R_HAND", false, 0.0 ) + tempBattery3p.RemoveFromSpatialPartition() + + entity tempBattery1p + tempBattery1p = CreatePropDynamic( RODEO_BATTERY_MODEL_FOR_RODEO_ANIMS ) + tempBattery1p.SetParent( player.GetFirstPersonProxy(), "R_HAND", false, 0.0 ) + tempBattery1p.RemoveFromSpatialPartition() + + player.p.rodeoAnimTempProps.append( tempBattery3p ) + player.p.rodeoAnimTempProps.append( tempBattery1p ) + + OnThreadEnd( + function() : ( battery, batteryPort, player, result, dataStruct ) + { + if ( IsValid( battery ) ) // animation interrupted, otherwise the battery will be destroyed + { + battery.Show() + Battery_StartFX( battery ) + } + + if ( IsValid( batteryPort ) ) + { + batteryPort.s.beingUsed = false + batteryPort.Anim_Stop() + } + + if ( IsValid( player ) ) + { + // restore control + DeployAndEnableWeapons( player ) + //ViewConeFree( player ) // no need to lock viewcone + + // clean up + ClearBatteryAnimTempProps( player ) + PutEntityInSafeSpot( player, player, null, player.GetOrigin() + <0, 0, 32>, player.GetOrigin() ) + + CleanUpBatterySequenceForPlayer( player ) + RestoreCloakAfterBatteryPortSequence( player, dataStruct ) + } + } + ) + + FirstPersonSequenceStruct sequence + sequence.attachment = "REF" // only ref the batteryPort has + + sequence.thirdPersonAnim = "pt_mp_battery_port_insert" //"pt_rodeo_ride_r_return_battery" + sequence.firstPersonAnim = "ptpov_mp_battery_port_insert" //"ptpov_rodeo_ride_r_return_battery" + + // player stats + HolsterAndDisableWeapons( player ) + //ViewConeZero( player ) // no need to lock viewcone + + batteryPort.Anim_Play( "bp_mp_battery_port_insert" ) + + thread WaitForActivateBattery( player, battery, batteryPort ) + waitthread FirstPersonSequence( sequence, player, batteryPort ) +} + +void function WaitForActivateBattery( entity player, entity battery, entity batteryPort ) +{ + player.EndSignal( "OnDeath" ) + player.EndSignal( "OnDestroy" ) + player.EndSignal( "ScriptAnimStop" ) // so you can jump off animation + battery.EndSignal( "OnDestroy" ) + + player.WaitSignal( "BatteryActivate" ) // this is registered in _gamemode_fw.nut! + ApplyBatteryToBatteryPort( player, batteryPort ) +} + +void function ApplyBatteryToBatteryPort( entity player, entity batteryPort ) +{ + if ( player.GetPlayerNetInt( "batteryCount" ) <= 0 ) // player actually not carrying a battery + return + + entity battery = Rodeo_TakeBatteryAwayFromPilot( player ) + if ( !IsValid( battery ) ) + return + + // player can apply battery + + // disable hacking + batteryPort.s.hackAvaliable = false // can't be hacked again until completely killed + + + var useBatteryPort = batteryPort.s.useBattery + useBatteryPort( batteryPort, player ) + + // all things done, destroy this batt + battery.Destroy() +} + +// for disabling cloak +struct BatteryPortSequenceStruct +{ + bool wasCloaked = false + float cloakEndTime = 0.0 +} + +BatteryPortSequenceStruct function DisableCloakBeforeBatteryPortSequence( entity player ) +{ + BatteryPortSequenceStruct dataStruct + if ( !IsCloaked( player ) ) + return dataStruct // empty struct! + + dataStruct.wasCloaked = true + dataStruct.cloakEndTime = player.GetCloakEndTime() + DisableCloak( player, 0.0 ) + + return dataStruct +} + +bool function RestoreCloakAfterBatteryPortSequence( entity player, BatteryPortSequenceStruct dataStruct ) +{ + if ( !IsAlive( player ) ) + return false + + if ( !dataStruct.wasCloaked ) + return false + + if ( dataStruct.cloakEndTime <= 0.0 ) + return false + + float remainingCloakDuration = max( 0.0, dataStruct.cloakEndTime - Time() ) + if ( remainingCloakDuration <= CLOAK_FADE_IN ) //Has to be greater than 1.0 fade in duration, otherwise will cloak forever + return false + + EnableCloak( player, remainingCloakDuration, CLOAK_FADE_IN ) + return true +} + +void function CleanUpBatterySequenceForPlayer( entity player ) +{ + ClearPlayerAnimViewEntity( player ) + player.AnimViewEntity_SetLerpOutTime( 0.4 ) // blend out the clear anim view entity + player.ClearParent() + player.Anim_Stop() +} + +void function ClearBatteryAnimTempProps( entity player ) +{ + foreach( tempProp in player.p.rodeoAnimTempProps ) + { + if ( IsValid( tempProp ) ) + tempProp.Destroy() + } + + player.p.rodeoAnimTempProps.clear() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut index 466a5042..016097f2 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut @@ -1,6 +1,276 @@ global function InitChallenges +global function SetPlayerChallengeEvacState //Hooked in _evac.gnut +global function SetPlayerChallengeMatchWon //Hooked in _score.nut +global function SetPlayerChallengeMatchComplete //Hooked in _score.nut +global function SetPlayerChallengeMeritScore //Up to gamemodes to use this directly if needed +global function IncrementPlayerChallengeTitanLeveledUp //Hooked in titan_xp.gnut +global function IncrementPlayerChallengeWeaponLeveledUp //Hooked in weapon_xp.gnut +global function IncrementPlayerChallengeFactionLeveledUp //Hooked in faction_xp.gnut (invisible but necessary for post-summary menu) +global function RegisterChallenges_OnMatchEnd //Hooked in _gamestate_mp.gnut + +global function HasPlayerCompletedMeritScore //Check from gamemodes to not reapply SetPlayerChallengeMeritScore +global function SetupGenericTDMChallenge //Used by gamemodes which simply adopts the: "Kill 3 Pilots without dying." Challenge +global function SetupGenericFFAChallenge //Used by gamemodes which simply adopts the: "Kill 5 Pilots." Challenge + +struct +{ + table< entity, int > playerTotalMeritCount + table< entity, bool > playerChallenge + table< entity, int > pilotstreak + bool isHappyHourActive +} file + + + + + + +/*============================================================================================================= + __ __ _ _ ____ _ _ _ + | \/ | __ _ | |_ ___ | |__ / ___|| |__ __ _ | || | ___ _ __ __ _ ___ ___ + | |\/| | / _` || __|/ __|| '_ \ | | | '_ \ / _` || || | / _ \| '_ \ / _` | / _ \/ __| + | | | || (_| || |_| (__ | | | | | |___ | | | || (_| || || || __/| | | || (_| || __/\__ \ + |_| |_| \__,_| \__|\___||_| |_| \____||_| |_| \__,_||_||_| \___||_| |_| \__, | \___||___/ + |___/ +=============================================================================================================*/ void function InitChallenges() { +#if (UI && CLIENT) + + SCB_SetCompleteMeritState( 4 ) + SCB_SetEvacMeritState( 4 ) + SCB_SetMeritCount( 4 ) + SCB_SetScoreMeritState( 4 ) + SCB_SetWinMeritState( 4 ) + SCB_SetWeaponMeritCount( -1 ) + SCB_SetTitanMeritCount( -1 ) + +#elseif (SERVER && MP) + + AddCallback_OnClientConnected( SetupPlayerMenuChallenges ) + AddCallback_OnClientDisconnected( RemovePlayerFromChallengePool ) + +#endif +} + +void function SetupPlayerMenuChallenges( entity player ) +{ + file.playerTotalMeritCount[ player ] <- 0 + file.pilotstreak[ player ] <- 0 + file.playerChallenge[ player ] <- false + + thread SetupChallenges_Threaded( player ) +} +void function SetupChallenges_Threaded( entity player ) +{ + player.EndSignal( "OnDestroy" ) + + WaitFrame() + + Remote_CallFunction_UI( player, "SCB_SetCompleteMeritState", 0 ) + Remote_CallFunction_UI( player, "SCB_SetEvacMeritState", 4 ) //4 tells RUI to hide it + Remote_CallFunction_UI( player, "SCB_SetMeritCount", 0 ) + Remote_CallFunction_UI( player, "SCB_SetScoreMeritState", 0 ) + Remote_CallFunction_UI( player, "SCB_SetWinMeritState", 0 ) + Remote_CallFunction_UI( player, "SCB_SetWeaponMeritCount", 0 ) + Remote_CallFunction_UI( player, "SCB_SetTitanMeritCount", 0 ) +} + +void function SetupGenericTDMChallenge() +{ + AddCallback_OnPlayerKilled( TDMChallenges_OnPlayerKilled ) +} + +void function SetupGenericFFAChallenge() +{ + AddCallback_OnPlayerKilled( FFAChallenges_OnPlayerKilled ) +} + +void function RemovePlayerFromChallengePool( entity player ) +{ + if( player in file.playerChallenge ) + delete file.playerChallenge[ player ] + if( player in file.playerTotalMeritCount ) + delete file.playerTotalMeritCount[ player ] + if( player in file.pilotstreak ) + delete file.pilotstreak[ player ] +} + +void function RegisterChallenges_OnMatchEnd() +{ + bool eliteWarpaintRNG = false + + if( RandomIntRange( 0, 100 ) <= 30 ) //30% Chance to trigger akin to vanilla, apply always since all players have paid cosmetics unlocked + eliteWarpaintRNG = true + + foreach( player in GetPlayerArray() ) + { + player.SetPersistentVar( "isPostGameScoreboardValid", true ) + player.SetPersistentVar( "isFDPostGameScoreboardValid", false ) //FD itself overrides this right after when match ends + SetUIVar( level, "showGameSummary", true ) + + if( eliteWarpaintRNG ) + SetPlayerChallengeSquadLeader( player ) + + if( ShouldAwardHappyHourBonus( player ) ) + { + AddPlayerScore( player, "HappyHourBonus" ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.HAPPY_HOUR + "]", 5 ) //The XP Given from Happy Hour Score is 5 merits + } + } +} + +void function TDMChallenges_OnPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim == attacker || !attacker.IsPlayer() || GetGameState() != eGameState.Playing ) + return + + if ( victim.IsPlayer() ) + { + if( victim in file.pilotstreak ) + file.pilotstreak[victim] = 0 + if( attacker in file.pilotstreak ) + { + file.pilotstreak[attacker]++ + if( file.pilotstreak[attacker] >= 3 && !HasPlayerCompletedMeritScore( attacker ) ) + { + AddPlayerScore( attacker, "ChallengeTDM" ) + SetPlayerChallengeMeritScore( attacker ) + } + } + } +} + +void function FFAChallenges_OnPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim == attacker || !attacker.IsPlayer() || GetGameState() != eGameState.Playing ) + return + + if ( victim.IsPlayer() && attacker in file.pilotstreak ) + { + file.pilotstreak[attacker]++ + if( file.pilotstreak[attacker] >= 5 && !HasPlayerCompletedMeritScore( attacker ) ) + { + AddPlayerScore( attacker, "ChallengePVPKillCount" ) + SetPlayerChallengeMeritScore( attacker ) + } + } +} + +bool function HasPlayerCompletedMeritScore( entity player ) +{ + Assert( player in file.playerChallenge, player + " is not registered in the challenge pool hooks." ) + return file.playerChallenge[ player ] +} + + + + + + + +/*============================================================================================================= + ____ _ _ _ _ + / ___| __ _ _ __ ___ ___ _ __ ___ ___ __| | ___ | | | | ___ ___ | | __ ___ + | | _ / _` || '_ ` _ \ / _ \| '_ ` _ \ / _ \ / _` | / _ \ | |_| | / _ \ / _ \ | |/ // __| + | |_| || (_| || | | | | || __/| | | | | || (_) || (_| || __/ | _ || (_) || (_) || < \__ \ + \____| \__,_||_| |_| |_| \___||_| |_| |_| \___/ \__,_| \___| |_| |_| \___/ \___/ |_|\_\|___/ + +=============================================================================================================*/ + +void function SetPlayerChallengeEvacState( entity player, int successEvac = 0 ) +{ + if( successEvac == 0 ) //Evac Ship destroyed + Remote_CallFunction_UI( player, "SCB_SetEvacMeritState", 2 ) + + else if( successEvac == 1 ) //Player itself managed to evac + { + file.playerTotalMeritCount[ player ]++ + Remote_CallFunction_UI( player, "SCB_SetEvacMeritState", 1 ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.EVAC + "]", 1 ) + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) + } + + else if( successEvac == 2 ) //Team managed to evac + Remote_CallFunction_UI( player, "SCB_SetEvacMeritState", 3 ) +} + +void function SetPlayerChallengeMatchWon( entity player, bool playerWon ) +{ + if( playerWon ) + { + file.playerTotalMeritCount[ player ]++ + Remote_CallFunction_UI( player, "SCB_SetWinMeritState", 1 ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.MATCH_VICTORY + "]", 1 ) + player.SetPersistentVar( "matchWin", true ) + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) + } + else + Remote_CallFunction_UI( player, "SCB_SetWinMeritState", -1 ) +} + +void function SetPlayerChallengeMatchComplete( entity player ) +{ + file.playerTotalMeritCount[ player ]++ + Remote_CallFunction_UI( player, "SCB_SetCompleteMeritState", 1 ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.MATCH_COMPLETED + "]", 1 ) + player.SetPersistentVar( "matchComplete", true ) + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) +} + +void function SetPlayerChallengeSquadLeader( entity player ) +{ + if( !ProgressionEnabledForPlayer( player ) ) + return + + Remote_CallFunction_NonReplay( player, "ServerCallback_SquadLeaderDoubleXP" ) + Remote_CallFunction_NonReplay( player, "ServerCallback_SquadLeaderBonus", player.GetEncodedEHandle() ) + player.SetPersistentVar( "matchSquadBonus", true ) + Player_GiveDoubleXP( player, 1 ) + foreach( entity teamplayer in GetPlayerArrayOfTeam( player.GetTeam() ) ) + { + if( teamplayer == player ) + continue + + Remote_CallFunction_NonReplay( player, "ServerCallback_SquadLeaderBonus", teamplayer.GetEncodedEHandle() ) + } +} + +void function SetPlayerChallengeMeritScore( entity player ) +{ + if( !HasPlayerCompletedMeritScore( player ) ) + { + file.playerChallenge[ player ] = true + file.playerTotalMeritCount[ player ]++ + Remote_CallFunction_UI( player, "SCB_SetScoreMeritState", 1 ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.SCORE_MILESTONE + "]", 1 ) + player.SetPersistentVar( "matchScoreEvent", true ) + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) + } +} + +void function IncrementPlayerChallengeTitanLeveledUp( entity player ) +{ + player.p.meritData.titanMerits++ + file.playerTotalMeritCount[ player ]++ + + Remote_CallFunction_UI( player, "SCB_SetTitanMeritCount", player.p.meritData.titanMerits++ ) + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) +} + +void function IncrementPlayerChallengeWeaponLeveledUp( entity player ) +{ + player.p.meritData.weaponMerits++ + file.playerTotalMeritCount[ player ]++ + + Remote_CallFunction_UI( player, "SCB_SetWeaponMeritCount", player.p.meritData.weaponMerits ) + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) +} + +void function IncrementPlayerChallengeFactionLeveledUp( entity player ) +{ + file.playerTotalMeritCount[ player ]++ + Remote_CallFunction_UI( player, "SCB_SetMeritCount", file.playerTotalMeritCount[ player ] ) }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut index 16a3ce92..0ababfc7 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut @@ -58,7 +58,9 @@ void function CodeCallback_MatchIsOver() #if MP void function PopulatePostgameData() { - // something's busted here because this isn't showing automatically on match end, ag + // show the postgame scoreboard summary + SetUIVar( level, "showGameSummary", true ) + foreach ( entity player in GetPlayerArray() ) { int teams = GetCurrentPlaylistVarInt( "max_teams", 2 ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut index 0555df9b..c3bdf01c 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut @@ -26,18 +26,9 @@ const int MAX_DROPSHIP_PLAYERS = 4 global const float DROPSHIP_INTRO_LENGTH = 15.0 // TODO tweak this -struct IntroDropship -{ - entity dropship - - int playersInDropship - entity[MAX_DROPSHIP_PLAYERS] players -} - struct { - // these used to be IntroDropship[2]s but i wanted to be able to use array.getrandom so they have to be actual arrays - array<IntroDropship> militiaDropships - array<IntroDropship> imcDropships + table< entity, array<entity> > militiaDropships + table< entity, array<entity> > imcDropships float introStartTime } file @@ -52,7 +43,12 @@ void function ClassicMP_DefaultDropshipIntro_Setup() void function DropshipIntro_OnClientConnected( entity player ) { if ( GetGameState() == eGameState.Prematch ) - thread SpawnPlayerIntoDropship( player ) + { + if( PlayerCanSpawn( player ) ) + DoRespawnPlayer( player, null ) + + PutPlayerInDropship( player ) + } } void function OnPrematchStart() @@ -62,11 +58,11 @@ void function OnPrematchStart() print( "starting dropship intro!" ) file.introStartTime = Time() - // make 2 empty dropship structs per team - IntroDropship emptyDropship + // Clear Dropship arrays of Teams for Match Restarts (i.e Half-Times) file.militiaDropships.clear() file.imcDropships.clear() + // Try to gather all possible Dropship spawn points for Team array<entity> validDropshipSpawns array<entity> dropshipSpawns = GetEntArrayByClass_Expensive( "info_spawnpoint_dropship_start" ) foreach ( entity dropshipSpawn in dropshipSpawns ) @@ -78,47 +74,47 @@ void function OnPrematchStart() validDropshipSpawns.append( dropshipSpawn ) } - // if no dropship spawns for this mode, just allow any dropship spawns + // Use any spawn point if not enough valid for this Gamemode exists if ( validDropshipSpawns.len() < 2 ) validDropshipSpawns = dropshipSpawns // spawn dropships foreach ( entity dropshipSpawn in validDropshipSpawns ) { - // todo: possibly make this only spawn dropships if we've got enough players to need them int createTeam = HasSwitchedSides() ? GetOtherTeam( dropshipSpawn.GetTeam() ) : dropshipSpawn.GetTeam() - array<IntroDropship> teamDropships = createTeam == TEAM_MILITIA ? file.militiaDropships : file.imcDropships + table< entity, array<entity> > teamDropships = createTeam == TEAM_MILITIA ? file.militiaDropships : file.imcDropships if ( teamDropships.len() >= 2 ) - continue + break - // create entity entity dropship = CreateDropship( createTeam, dropshipSpawn.GetOrigin(), dropshipSpawn.GetAngles() ) - - teamDropships.append( clone emptyDropship ) - teamDropships[ teamDropships.len() - 1 ].dropship = dropship - AddAnimEvent( dropship, "dropship_warpout", WarpoutEffect ) + dropship.SetValueForModelKey( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) - dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + if ( dropshipSpawn.GetTeam() == TEAM_IMC ) + dropship.SetValueForModelKey( $"models/vehicle/goblin_dropship/goblin_dropship_hero.mdl" ) DispatchSpawn( dropship ) - // have to do this after dispatch otherwise it won't work for some reason - // weirdly enough, tf2 actually does use different dropships for imc and militia, despite these concepts not really being a thing for players in tf2 - // probably was just missed by devs, but keeping it in for accuracy + dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) if ( dropshipSpawn.GetTeam() == TEAM_IMC ) dropship.SetModel( $"models/vehicle/goblin_dropship/goblin_dropship_hero.mdl" ) - else - dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) + + teamDropships[ dropship ] <- [ null, null, null, null ] thread PlayAnim( dropship, "dropship_classic_mp_flyin" ) } + // Populate Dropships foreach ( entity player in GetPlayerArray() ) { if ( !IsPrivateMatchSpectator( player ) ) - thread SpawnPlayerIntoDropship( player ) + { + if( PlayerCanSpawn( player ) ) + DoRespawnPlayer( player, null ) + + PutPlayerInDropship( player ) + } else RespawnPrivateMatchSpectator( player ) } @@ -128,75 +124,79 @@ void function OnPrematchStart() void function EndIntroWhenFinished() { - wait 15.0 + wait DROPSHIP_INTRO_LENGTH ClassicMP_OnIntroFinished() } -void function SpawnPlayerIntoDropship( entity player ) +void function PutPlayerInDropship( entity player ) { - player.EndSignal( "OnDestroy" ) + //Find the player's dropship and seat + table< entity, array<entity> > teamDropships + if ( player.GetTeam() == TEAM_MILITIA ) + teamDropships = file.militiaDropships + else + teamDropships = file.imcDropships + + entity playerDropship + array< int > availableShipSlots + array< entity > introDropships + int playerDropshipIndex = RandomInt( MAX_DROPSHIP_PLAYERS ) + foreach( dropship, playerslot in teamDropships ) + { + introDropships.append( dropship ) + for ( int i = 0; i < MAX_DROPSHIP_PLAYERS; i++ ) + { + if ( !IsValidPlayer( playerslot[i] ) ) + availableShipSlots.append( i ) + } + + if( !availableShipSlots.len() ) + continue + + int slotPick = availableShipSlots.getrandom() + playerslot[slotPick] = player + playerDropship = dropship + playerDropshipIndex = slotPick + break + } + + if( !IsAlive( playerDropship ) ) //If we're at this point, we have more players than we do dropships, so just pick a random one + playerDropship = introDropships.getrandom() + + thread SpawnPlayerIntoDropship( player, playerDropshipIndex, playerDropship ) +} - if ( IsAlive( player ) ) - player.Die() // kill them so we don't have any issues respawning them later +void function SpawnPlayerIntoDropship( entity player, int playerDropshipIndex, entity playerDropship ) +{ + player.EndSignal( "OnDestroy" ) + player.EndSignal( "OnDeath" ) - player.s.dropshipIntroIsJumping <- false - OnThreadEnd( function() : ( player ) + OnThreadEnd( function() : ( player, playerDropshipIndex, playerDropship ) { if ( IsValid( player ) ) { player.ClearParent() ClearPlayerAnimViewEntity( player ) - - if ( !player.s.dropshipIntroIsJumping ) - { - player.MovementEnable() - player.EnableWeaponViewModel() - RemoveCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING ) - } + } + if( IsAlive( playerDropship ) ) + { + if ( playerDropship.GetTeam() == TEAM_MILITIA ) + file.militiaDropships[ playerDropship ][ playerDropshipIndex ] = null + else + file.imcDropships[ playerDropship ][ playerDropshipIndex ] = null } }) - WaitFrame() - - player.EndSignal( "OnDeath" ) - - // find the player's dropship and seat - array<IntroDropship> teamDropships - if ( player.GetTeam() == TEAM_MILITIA ) - teamDropships = file.militiaDropships - else - teamDropships = file.imcDropships - - IntroDropship playerDropship - int playerDropshipIndex = -1 - foreach ( IntroDropship dropship in teamDropships ) - for ( int i = 0; i < dropship.players.len(); i++ ) - if ( dropship.players[ i ] == null ) - { - playerDropship = dropship - playerDropshipIndex = i - - dropship.players[ i ] = player - break - } - - if ( playerDropship.dropship == null ) - { - // if we're at this point, we have more players than we do dropships, so just pick a random one - playerDropship = teamDropships.getrandom() - playerDropshipIndex = RandomInt( MAX_DROPSHIP_PLAYERS ) - } - - // respawn player and holster their weapons so they aren't out - player.RespawnPlayer( null ) - HolsterAndDisableWeapons(player) + HolsterAndDisableWeapons( player ) player.DisableWeaponViewModel() + UnMuteAll( player ) + StopSoundOnEntity( player, "Duck_For_FrontierDefenseTitanSelectScreen" ) // hide hud and fade screen out from black AddCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING ) ScreenFadeFromBlack( player, 0.5, 0.5 ) // faction leaders are done clientside, spawn them here - Remote_CallFunction_NonReplay( player, "ServerCallback_SpawnFactionCommanderInDropship", playerDropship.dropship.GetEncodedEHandle(), file.introStartTime ) + Remote_CallFunction_NonReplay( player, "ServerCallback_SpawnFactionCommanderInDropship", playerDropship.GetEncodedEHandle(), file.introStartTime ) // do firstperson sequence FirstPersonSequenceStruct idleSequence @@ -207,9 +207,7 @@ void function SpawnPlayerIntoDropship( entity player ) idleSequence.viewConeFunction = ViewConeRampFree idleSequence.hideProxy = true idleSequence.setInitialTime = Time() - file.introStartTime - thread FirstPersonSequence( idleSequence, player, playerDropship.dropship ) - WaittillAnimDone( player ) - + waitthread FirstPersonSequence( idleSequence, player, playerDropship ) // todo: possibly rework this to actually get the time the idle anim takes and start the starttime of the jump sequence for very late joiners using that // jump sequence @@ -217,13 +215,17 @@ void function SpawnPlayerIntoDropship( entity player ) jumpSequence.firstPersonAnim = DROPSHIP_JUMP_ANIMS_POV[ playerDropshipIndex ] jumpSequence.thirdPersonAnim = DROPSHIP_JUMP_ANIMS[ playerDropshipIndex ] jumpSequence.attachment = "ORIGIN" + jumpSequence.viewConeFunction = ViewConeFree jumpSequence.setInitialTime = max( 0.0, Time() - ( file.introStartTime + 11.0 ) ) // pretty sure you should do this with GetScriptedAnimEventCycleFrac? // idk unsure how to use that, all i know is getsequenceduration > the length it actually should be - thread FirstPersonSequence( jumpSequence, player, playerDropship.dropship ) - WaittillAnimDone( player ) // somehow this is better than just waiting for the blocking FirstPersonSequence call? + #if BATTLECHATTER_ENABLED + if( playerDropshipIndex == 0 ) + PlayBattleChatterLine( player, "bc_pIntroChat" ) + #endif + + waitthread FirstPersonSequence( jumpSequence, player, playerDropship ) - player.s.dropshipIntroIsJumping <- true thread PlayerJumpsFromDropship( player ) } @@ -239,20 +241,21 @@ void function PlayerJumpsFromDropship( entity player ) // show weapon viewmodel and hud and let them move again player.MovementEnable() player.EnableWeaponViewModel() - DeployAndEnableWeapons(player) + DeployAndEnableWeapons( player ) RemoveCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING ) } }) - - // wait for intro timer to be fully done - wait ( file.introStartTime + DROPSHIP_INTRO_LENGTH ) - Time() - player.MovementDisable() // disable all movement but let them look around still - player.ConsumeDoubleJump() // movementdisable doesn't prevent double jumps // wait for player to hit the ground - wait 0.1 // assume players will never actually hit ground before this + player.ClearParent() + WaitFrame() + player.SetVelocity( < 0, 0, -100 > ) // Toss players a bit down so it makes a smoother transition when jumping off the Dropship + player.MovementDisable() // Disable all movement but let them look around still + player.ConsumeDoubleJump() // MovementDisable doesn't prevent double jumps + WaitFrame() while ( !player.IsOnGround() && !player.IsWallRunning() && !player.IsWallHanging() ) // todo this needs tweaking WaitFrame() - TryGameModeAnnouncement( player ) -}
\ No newline at end of file + if ( GetRoundsPlayed() == 0 ) //Intro is announced only for the first round in Vanilla as certain gamemodes have different announcements for rounds restarts + TryGameModeAnnouncement( player ) +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut index 425a8b8b..0d1b42b7 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut @@ -21,6 +21,8 @@ global function SetTitanMeterGainScale #if MP global function CodeCallback_OnServerAnimEvent +global function CodeCallback_WeaponDropped +global function AddCallback_OnWeaponDropped #endif struct AccumulatedDamageData @@ -43,6 +45,7 @@ struct ] table<entity, AccumulatedDamageData> playerAccumulatedDamageData + array< void functionref( entity ) > weaponDroppedCallbacks } file void function CodeCallback_Init() @@ -283,12 +286,26 @@ void function CodeCallback_DamagePlayerOrNPC( entity ent, var damageInfo ) return RunClassDamageFinalCallbacks( ent, damageInfo ) + #if VERBOSE_DAMAGE_PRINTOUTS printt( " after class damage final callbacks:", DamageInfo_GetDamage( damageInfo ) ) #endif if ( DamageInfo_GetDamage( damageInfo ) == 0 ) return + // Added via AddEntityCallback_OnFinalDamaged + foreach ( callbackFunc in ent.e.entFinalDamageCallbacks ) + { + callbackFunc( ent, damageInfo ) + } + + #if VERBOSE_DAMAGE_PRINTOUTS + printt( " afterAddEntityCallback_OnFinalDamaged callbacks:", DamageInfo_GetDamage( damageInfo ) ) + #endif + + if ( DamageInfo_GetDamage( damageInfo ) == 0 ) + return + if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_DOOMED_HEALTH_LOSS ) DamageInfo_AddDamageFlags( damageInfo, DAMAGEFLAG_NOPAIN ) @@ -1016,4 +1033,26 @@ void function CodeCallback_OnServerAnimEvent( entity ent, string eventName ) PerfEnd( PerfIndexServer.CB_OnServerAnimEvent ) } + +void function AddCallback_OnWeaponDropped( void functionref( entity ) callback ) +{ + file.weaponDroppedCallbacks.append( callback ) +} + +void function CodeCallback_WeaponDropped( entity weapon ) +{ + // shamelessly taken form SP + if ( !IsValid( weapon ) ) + return + + // Might look a bit hacky to put it here, but thats how SP does it + if ( !Flag( "WeaponDropsAllowed" ) ) + { + weapon.Destroy() + return + } + + foreach( callback in file.weaponDroppedCallbacks ) + callback( weapon ) +} #endif // #if MP
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut index bfcd23e0..f7c398d9 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut @@ -13,6 +13,8 @@ global function SetTimerBased global function SetShouldUseRoundWinningKillReplay global function SetRoundWinningKillReplayKillClasses global function SetRoundWinningKillReplayAttacker +global function SetCallback_TryUseProjectileReplay +global function ShouldTryUseProjectileReplay global function SetWinner global function SetTimeoutWinnerDecisionFunc global function AddTeamScore @@ -48,13 +50,28 @@ struct { float roundWinningKillReplayTime entity roundWinningKillReplayVictim entity roundWinningKillReplayAttacker + int roundWinningKillReplayInflictorEHandle // this is either the inflictor or the attacker int roundWinningKillReplayMethodOfDeath float roundWinningKillReplayTimeOfDeath float roundWinningKillReplayHealthFrac array<void functionref()> roundEndCleanupCallbacks + bool functionref( entity victim, entity attacker, var damageInfo, bool isRoundEnd ) shouldTryUseProjectileReplayCallback } file +void function SetCallback_TryUseProjectileReplay( bool functionref( entity victim, entity attacker, var damageInfo, bool isRoundEnd ) callback ) +{ + file.shouldTryUseProjectileReplayCallback = callback +} + +bool function ShouldTryUseProjectileReplay( entity victim, entity attacker, var damageInfo, bool isRoundEnd ) +{ + if ( file.shouldTryUseProjectileReplayCallback != null ) + return file.shouldTryUseProjectileReplayCallback( victim, attacker, damageInfo, isRoundEnd ) + // default to true (vanilla behaviour) + return true +} + void function PIN_GameStart() { // todo: using the pin telemetry function here, weird and was done veeery early on before i knew how this all worked, should use a different one @@ -79,6 +96,7 @@ void function PIN_GameStart() AddCallback_OnPlayerKilled( OnPlayerKilled ) AddDeathCallback( "npc_titan", OnTitanKilled ) + AddCallback_EntityChangedTeam( "player", OnPlayerChangedTeam ) RegisterSignal( "CleanUpEntitiesForRoundEnd" ) } @@ -184,6 +202,14 @@ void function GameStateEnter_Prematch() if ( !GetClassicMPMode() && !ClassicMP_ShouldTryIntroAndEpilogueWithoutClassicMP() ) thread StartGameWithoutClassicMP() + + // Initialise any spectators. Hopefully they are all initialised already in CodeCallback_OnClientConnectionCompleted + // (_base_gametype_mp.gnut) but for modes like LTS this doesn't seem to happen late enough to work properly. + foreach ( player in GetPlayerArray() ) + { + if ( IsPrivateMatchSpectator( player ) ) + InitialisePrivateMatchSpectatorPlayer( player ) + } } void function StartGameWithoutClassicMP() @@ -220,6 +246,8 @@ void function GameStateEnter_Playing_Threaded() { WaitFrame() // ensure timelimits are all properly set + thread DialoguePlayNormal() // runs dialogue play function + while ( GetGameState() == eGameState.Playing ) { // could cache these, but what if we update it midgame? @@ -268,6 +296,8 @@ void function GameStateEnter_WinnerDetermined_Threaded() // do win announcement int winningTeam = GetWinningTeamWithFFASupport() + DialoguePlayWinnerDetermined() // play a faction dialogue when winner is determined + foreach ( entity player in GetPlayerArray() ) { int announcementSubstr @@ -278,6 +308,9 @@ void function GameStateEnter_WinnerDetermined_Threaded() Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceRoundWinner", winningTeam, announcementSubstr, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME, GameRules_GetTeamScore2( TEAM_MILITIA ), GameRules_GetTeamScore2( TEAM_IMC ) ) else Remote_CallFunction_NonReplay( player, "ServerCallback_AnnounceWinner", winningTeam, announcementSubstr, ROUND_WINNING_KILL_REPLAY_SCREEN_FADE_TIME ) + + if ( player.GetTeam() == winningTeam ) + UnlockAchievement( player, achievements.MP_WIN ) } WaitFrame() // wait a frame so other scripts can setup killreplay stuff @@ -312,6 +345,7 @@ void function GameStateEnter_WinnerDetermined_Threaded() WaitFrame() // prevent a race condition with PlayerWatchesRoundWinningKillReplay file.roundWinningKillReplayAttacker = null // clear this + file.roundWinningKillReplayInflictorEHandle = -1 if ( killcamsWereEnabled ) SetKillcamsEnabled( true ) @@ -362,6 +396,7 @@ void function GameStateEnter_WinnerDetermined_Threaded() } else { + RegisterChallenges_OnMatchEnd() if ( ClassicMP_ShouldRunEpilogue() ) { ClassicMP_SetupEpilogue() @@ -384,11 +419,14 @@ void function PlayerWatchesRoundWinningKillReplay( entity player, float replayLe player.SetPredictionEnabled( false ) // prediction fucks with replays entity attacker = file.roundWinningKillReplayAttacker - player.SetKillReplayDelay( Time() - replayLength, THIRD_PERSON_KILL_REPLAY_ALWAYS ) - player.SetKillReplayInflictorEHandle( attacker.GetEncodedEHandle() ) - player.SetKillReplayVictim( file.roundWinningKillReplayVictim ) - player.SetViewIndex( attacker.GetIndexForEntity() ) - player.SetIsReplayRoundWinning( true ) + if ( IsValid( attacker ) ) + { + player.SetKillReplayDelay( Time() - replayLength, THIRD_PERSON_KILL_REPLAY_ALWAYS ) + player.SetKillReplayInflictorEHandle( file.roundWinningKillReplayInflictorEHandle ) + player.SetKillReplayVictim( file.roundWinningKillReplayVictim ) + player.SetViewIndex( attacker.GetIndexForEntity() ) + player.SetIsReplayRoundWinning( true ) + } if ( replayLength >= ROUND_WINNING_KILL_REPLAY_LENGTH_OF_REPLAY - 0.5 ) // only do fade if close to full length replay { @@ -450,6 +488,7 @@ void function GameStateEnter_SwitchingSides_Threaded() svGlobal.levelEnt.Signal( "RoundEnd" ) // might be good to get a new signal for this? not 100% necessary tho i think SetServerVar( "switchedSides", 1 ) file.roundWinningKillReplayAttacker = null // reset this after replay + file.roundWinningKillReplayInflictorEHandle = -1 if ( file.usePickLoadoutScreen ) SetGameState( eGameState.PickLoadout ) @@ -473,7 +512,7 @@ void function PlayerWatchesSwitchingSidesKillReplay( entity player, bool doRepla entity attacker = file.roundWinningKillReplayAttacker player.SetKillReplayDelay( Time() - replayLength, THIRD_PERSON_KILL_REPLAY_ALWAYS ) - player.SetKillReplayInflictorEHandle( attacker.GetEncodedEHandle() ) + player.SetKillReplayInflictorEHandle( file.roundWinningKillReplayInflictorEHandle ) player.SetKillReplayVictim( file.roundWinningKillReplayVictim ) player.SetViewIndex( attacker.GetIndexForEntity() ) player.SetIsReplayRoundWinning( true ) @@ -503,6 +542,20 @@ void function GameStateEnter_SuddenDeath() { // disable respawns, suddendeath calling is done on a kill callback SetRespawnsEnabled( false ) + + // defensive fixes, so game won't stuck in SuddenDeath forever + bool mltElimited = false + bool imcElimited = false + if( GetPlayerArrayOfTeam_Alive( TEAM_MILITIA ).len() < 1 ) + mltElimited = true + if( GetPlayerArrayOfTeam_Alive( TEAM_IMC ).len() < 1 ) + imcElimited = true + if( mltElimited && imcElimited ) + SetWinner( TEAM_UNASSIGNED ) + else if( mltElimited ) + SetWinner( TEAM_IMC ) + else if( imcElimited ) + SetWinner( TEAM_MILITIA ) } @@ -554,6 +607,9 @@ void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) return } + entity inflictor = DamageInfo_GetInflictor( damageInfo ) + bool shouldUseInflictor = IsValid( inflictor ) && ShouldTryUseProjectileReplay( victim, attacker, damageInfo, true ) + // set round winning killreplay info here if we're tracking pilot kills // todo: make this not count environmental deaths like falls, unsure how to prevent this if ( file.roundWinningKillReplayTrackPilotKills && victim != attacker && attacker != svGlobal.worldspawn && IsValid( attacker ) ) @@ -563,6 +619,7 @@ void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) file.roundWinningKillReplayTime = Time() file.roundWinningKillReplayVictim = victim file.roundWinningKillReplayAttacker = attacker + file.roundWinningKillReplayInflictorEHandle = ( shouldUseInflictor ? inflictor : attacker ).GetEncodedEHandle() file.roundWinningKillReplayMethodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo ) file.roundWinningKillReplayTimeOfDeath = Time() file.roundWinningKillReplayHealthFrac = GetHealthFrac( attacker ) @@ -613,6 +670,9 @@ void function OnTitanKilled( entity victim, var damageInfo ) return } + entity inflictor = DamageInfo_GetInflictor( damageInfo ) + bool shouldUseInflictor = IsValid( inflictor ) && ShouldTryUseProjectileReplay( victim, DamageInfo_GetAttacker( damageInfo ), damageInfo, true ) + // set round winning killreplay info here if we're tracking titan kills // todo: make this not count environmental deaths like falls, unsure how to prevent this entity attacker = DamageInfo_GetAttacker( damageInfo ) @@ -623,6 +683,7 @@ void function OnTitanKilled( entity victim, var damageInfo ) file.roundWinningKillReplayTime = Time() file.roundWinningKillReplayVictim = victim file.roundWinningKillReplayAttacker = attacker + file.roundWinningKillReplayInflictorEHandle = ( shouldUseInflictor ? inflictor : attacker ).GetEncodedEHandle() file.roundWinningKillReplayMethodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo ) file.roundWinningKillReplayTimeOfDeath = Time() file.roundWinningKillReplayHealthFrac = GetHealthFrac( attacker ) @@ -737,11 +798,12 @@ void function SetRoundWinningKillReplayKillClasses( bool pilot, bool titan ) file.roundWinningKillReplayTrackTitanKills = titan // player kills in titans should get tracked anyway, might be worth renaming this } -void function SetRoundWinningKillReplayAttacker( entity attacker ) +void function SetRoundWinningKillReplayAttacker( entity attacker, int inflictorEHandle = -1 ) { file.roundWinningKillReplayTime = Time() file.roundWinningKillReplayHealthFrac = GetHealthFrac( attacker ) file.roundWinningKillReplayAttacker = attacker + file.roundWinningKillReplayInflictorEHandle = inflictorEHandle == -1 ? attacker.GetEncodedEHandle() : inflictorEHandle file.roundWinningKillReplayTimeOfDeath = Time() } @@ -773,9 +835,45 @@ void function SetWinner( int team, string winningReason = "", string losingReaso } SetGameState( eGameState.WinnerDetermined ) + ScoreEvent_RoundComplete( team ) } else + { SetGameState( eGameState.WinnerDetermined ) + ScoreEvent_MatchComplete( team ) + + array<entity> players = GetPlayerArray() + int functionref( entity, entity ) compareFunc = GameMode_GetScoreCompareFunc( GAMETYPE ) + if ( compareFunc != null ) + { + players.sort( compareFunc ) + int playerCount = players.len() + int currentPlace = 1 + for ( int i = 0; i < 3; i++ ) + { + if ( i >= playerCount ) + continue + + if ( i > 0 && compareFunc( players[i - 1], players[i] ) != 0 ) + currentPlace += 1 + + switch( currentPlace ) + { + case 1: + UpdatePlayerStat( players[i], "game_stats", "mvp" ) + UpdatePlayerStat( players[i], "game_stats", "mvp_total" ) + UpdatePlayerStat( players[i], "game_stats", "top3OnTeam" ) + break + case 2: + UpdatePlayerStat( players[i], "game_stats", "top3OnTeam" ) + break + case 3: + UpdatePlayerStat( players[i], "game_stats", "top3OnTeam" ) + break + } + } + } + } } } @@ -868,3 +966,108 @@ float function GetTimeLimit_ForGameMode() // default to 10 mins, because that seems reasonable return GetCurrentPlaylistVarFloat( playlistString, 10 ) } + +// faction dialogue + +void function DialoguePlayNormal() +{ + int totalScore = GameMode_GetScoreLimit( GameRules_GetGameMode() ) + int winningTeam + int losingTeam + float diagIntervel = 71 // play a faction dailogue every 70 + 1s to prevent play together with winner dialogue + + while( GetGameState() == eGameState.Playing ) + { + wait diagIntervel + if( GameRules_GetTeamScore( TEAM_MILITIA ) < GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_IMC + losingTeam = TEAM_MILITIA + } + if( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_MILITIA + losingTeam = TEAM_IMC + } + if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) >= totalScore * 0.4 ) + { + PlayFactionDialogueToTeam( "scoring_winningLarge", winningTeam ) + PlayFactionDialogueToTeam( "scoring_losingLarge", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) <= totalScore * 0.2 ) + { + PlayFactionDialogueToTeam( "scoring_winningClose", winningTeam ) + PlayFactionDialogueToTeam( "scoring_losingClose", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) == GameRules_GetTeamScore( losingTeam ) ) + { + continue + } + else + { + PlayFactionDialogueToTeam( "scoring_winning", winningTeam ) + PlayFactionDialogueToTeam( "scoring_losing", losingTeam ) + } + } +} + +void function DialoguePlayWinnerDetermined() +{ + int totalScore = GameMode_GetScoreLimit( GameRules_GetGameMode() ) + int winningTeam + int losingTeam + + if( GameRules_GetTeamScore( TEAM_MILITIA ) < GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_IMC + losingTeam = TEAM_MILITIA + } + if( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_MILITIA + losingTeam = TEAM_IMC + } + if( IsRoundBased() ) // check for round based modes + { + if( GameRules_GetTeamScore( winningTeam ) != GameMode_GetRoundScoreLimit( GAMETYPE ) ) // no winner dialogue till game really ends + return + } + if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) >= totalScore * 0.4 ) + { + PlayFactionDialogueToTeam( "scoring_wonMercy", winningTeam ) + PlayFactionDialogueToTeam( "scoring_lostMercy", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) <= totalScore * 0.2 ) + { + PlayFactionDialogueToTeam( "scoring_wonClose", winningTeam ) + PlayFactionDialogueToTeam( "scoring_lostClose", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) == GameRules_GetTeamScore( losingTeam ) ) + { + PlayFactionDialogueToTeam( "scoring_tied", winningTeam ) + PlayFactionDialogueToTeam( "scoring_tied", losingTeam ) + } + else + { + PlayFactionDialogueToTeam( "scoring_won", winningTeam ) + PlayFactionDialogueToTeam( "scoring_lost", losingTeam ) + } +} + +/// This is to move all NPCs that a player owns from one team to the other during a match +/// Auto-Titans, Turrets, Ticks and Hacked Spectres will all move along together with the player to the new Team +/// Also possibly prevents mods that spawns other types of NPCs that players can own from breaking when switching (i.e Drones, Hacked Reapers) +void function OnPlayerChangedTeam( entity player ) +{ + if ( !player.hasConnected ) // Prevents players who just joined to trigger below code, as server always pre setups their teams + return + + NotifyClientsOfTeamChange( player, GetOtherTeam( player.GetTeam() ), player.GetTeam() ) + + foreach( npc in GetNPCArray() ) + { + entity bossPlayer = npc.GetBossPlayer() + if ( IsValidPlayer( bossPlayer ) && bossPlayer == player && IsAlive( npc ) ) + SetTeam( npc, player.GetTeam() ) + } +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_model_viewer.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_model_viewer.nut new file mode 100644 index 00000000..c33f4ef0 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_model_viewer.nut @@ -0,0 +1,180 @@ +untyped
+
+
+global function ModelViewer_Init
+
+global function ToggleModelViewer
+
+global modelViewerModels = []
+
+#if DEV
+struct
+{
+ bool initialized
+ bool active
+ entity gameUIFreezeControls
+ array<string> playerWeapons
+ array<string> playerOffhands
+ bool dpadUpPressed = true
+ bool dpadDownPressed = true
+ var lastTitanAvailability
+} file
+#endif // DEV
+
+function ModelViewer_Init()
+{
+ #if DEV
+ if ( reloadingScripts )
+ return
+ AddClientCommandCallback( "ModelViewer", ClientCommand_ModelViewer )
+ #endif
+}
+
+function ToggleModelViewer()
+{
+ #if DEV
+ entity player = GetPlayerArray()[ 0 ]
+ if ( !file.active )
+ {
+ file.active = true
+
+ DisablePrecacheErrors()
+ wait 0.5
+
+ ModelViewerDisableConflicts()
+ Remote_CallFunction_NonReplay( player, "ServerCallback_ModelViewerDisableConflicts" )
+
+ ReloadShared()
+
+ if ( !file.initialized )
+ {
+ file.initialized = true
+ ControlsInit()
+ }
+
+ Remote_CallFunction_NonReplay( player, "ServerCallback_MVEnable" )
+
+ file.lastTitanAvailability = level.nv.titanAvailability
+ Riff_ForceTitanAvailability( eTitanAvailability.Never )
+
+ WeaponsRemove()
+ thread UpdateModelBounds()
+ }
+ else
+ {
+ file.active = false
+
+ Remote_CallFunction_NonReplay( player, "ServerCallback_MVDisable" )
+ RestorePrecacheErrors()
+
+ Riff_ForceTitanAvailability( file.lastTitanAvailability )
+
+ WeaponsRestore()
+ }
+ #endif
+}
+
+#if DEV
+function ModelViewerDisableConflicts()
+{
+ disable_npcs() //Just disable_npcs() for now, will probably add things later
+}
+
+function ReloadShared()
+{
+ modelViewerModels = GetModelViewerList()
+}
+
+function ControlsInit()
+{
+ file.gameUIFreezeControls = CreateEntity( "game_ui" )
+ file.gameUIFreezeControls.kv.spawnflags = 32
+ file.gameUIFreezeControls.kv.FieldOfView = -1.0
+
+ DispatchSpawn( file.gameUIFreezeControls )
+}
+
+bool function ClientCommand_ModelViewer( entity player, array<string> args )
+{
+ string command = args[ 0 ]
+ switch ( command )
+ {
+ case "freeze_player":
+ file.gameUIFreezeControls.Fire( "Activate", "!player", 0 )
+ break
+
+ case "unfreeze_player":
+ file.gameUIFreezeControls.Fire( "Deactivate", "!player", 0 )
+ break
+ }
+
+ return true
+}
+
+function UpdateModelBounds()
+{
+ wait( 0.3 )
+
+ foreach ( index, modelName in modelViewerModels )
+ {
+ entity model = CreatePropDynamic( expect asset( modelName ) )
+ local mins = model.GetBoundingMins()
+ local maxs = model.GetBoundingMaxs()
+
+ mins.x = min( -8.0, mins.x )
+ mins.y = min( -8.0, mins.y )
+ mins.z = min( -8.0, mins.z )
+
+ maxs.x = max( 8.0, maxs.x )
+ maxs.y = max( 8.0, maxs.y )
+ maxs.z = max( 8.0, maxs.z )
+
+ Remote_CallFunction_NonReplay( GetPlayerArray()[ 0 ], "ServerCallback_MVUpdateModelBounds", index, mins.x, mins.y, mins.z, maxs.x, maxs.y, maxs.z )
+ model.Destroy()
+ }
+}
+
+function WeaponsRemove()
+{
+ entity player = GetPlayerArray()[0]
+ if ( !IsValid( player ) )
+ return
+
+ file.playerWeapons.clear()
+ file.playerOffhands.clear()
+
+ array<entity> weapons = player.GetMainWeapons()
+ foreach ( weaponEnt in weapons )
+ {
+ string weapon = weaponEnt.GetWeaponClassName()
+ file.playerWeapons.append( weapon )
+ player.TakeWeapon( weapon )
+ }
+
+ array<entity> offhands = player.GetOffhandWeapons()
+ foreach ( index, offhandEnt in offhands )
+ {
+ string offhand = offhandEnt.GetWeaponClassName()
+ file.playerOffhands.append( offhand )
+ player.TakeOffhandWeapon( index )
+ }
+}
+
+function WeaponsRestore()
+{
+ entity player = GetPlayerArray()[0]
+ if ( !IsValid( player ) )
+ return
+
+ foreach ( weapon in file.playerWeapons )
+ {
+ player.GiveWeapon( weapon )
+ }
+
+ foreach ( index, offhand in file.playerOffhands )
+ {
+ player.GiveOffhandWeapon( offhand, index )
+ }
+}
+
+#endif // DEV
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut index 2d1ff074..2a4c4282 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut @@ -7,6 +7,8 @@ global function ScoreEvent_PlayerKilled global function ScoreEvent_TitanDoomed global function ScoreEvent_TitanKilled global function ScoreEvent_NPCKilled +global function ScoreEvent_MatchComplete +global function ScoreEvent_RoundComplete global function ScoreEvent_SetEarnMeterValues global function ScoreEvent_SetupEarnMeterValuesForMixedModes @@ -27,6 +29,10 @@ void function InitPlayerForScoreEvents( entity player ) player.s.currentKillstreak <- 0 player.s.lastKillTime <- 0.0 player.s.currentTimedKillstreak <- 0 + player.s.lastKillTime_Mayhem <- 0.0 + player.s.currentTimedKillstreak_Mayhem <- 0 + player.s.lastKillTime_Onslaught <- 0.0 + player.s.currentTimedKillstreak_Onslaught <- 0 } void function AddPlayerScore( entity targetPlayer, string scoreEventName, entity associatedEnt = null, string noideawhatthisis = "", int pointValueOverride = -1 ) @@ -92,6 +98,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag victim.s.currentTimedKillstreak = 0 victim.p.numberOfDeathsSinceLastKill++ // this is reset on kill + victim.p.lastKiller = attacker // have to do this early before we reset victim's player killstreaks // nemesis when you kill a player that is dominating you @@ -130,12 +137,20 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag attacker.p.numberOfDeathsSinceLastKill = 0 } + // revenge + quick revenge + if ( attacker.p.lastKiller == victim ) + { + if ( Time() - GetPlayerLastRespawnTime( attacker ) < QUICK_REVENGE_TIME_LIMIT ) + AddPlayerScore( attacker, "QuickRevenge" ) + else + AddPlayerScore( attacker, "Revenge" ) + } // untimed killstreaks attacker.s.currentKillstreak++ - if ( attacker.s.currentKillstreak == 3 ) + if ( attacker.s.currentKillstreak == KILLINGSPREE_KILL_REQUIREMENT ) AddPlayerScore( attacker, "KillingSpree" ) - else if ( attacker.s.currentKillstreak == 5 ) + else if ( attacker.s.currentKillstreak == RAMPAGE_KILL_REQUIREMENT ) AddPlayerScore( attacker, "Rampage" ) // increment untimed killstreaks against specific players @@ -187,24 +202,42 @@ void function ScoreEvent_TitanKilled( entity victim, entity attacker, var damage return if ( attacker.IsTitan() ) - AddPlayerScore( attacker, "TitanKillTitan", victim.GetTitanSoul().GetOwner() ) + { + if( victim.GetBossPlayer() || victim.IsPlayer() ) // to confirm this is a pet titan or player titan + AddPlayerScore( attacker, "TitanKillTitan", attacker ) // this will show the "Titan Kill" callsign event + else + AddPlayerScore( attacker, "TitanKillTitan" ) + } else - AddPlayerScore( attacker, "KillTitan", victim.GetTitanSoul().GetOwner() ) + { + if( victim.GetBossPlayer() || victim.IsPlayer() ) + AddPlayerScore( attacker, "KillTitan", attacker ) + else + AddPlayerScore( attacker, "KillTitan" ) + } - table<int, bool> alreadyAssisted - foreach( DamageHistoryStruct attackerInfo in victim.e.recentDamageHistory ) + entity soul = victim.GetTitanSoul() + if ( IsValid( soul ) ) { - if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == victim ) - continue - - bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false - if( attackerInfo.attacker != attacker && !exists ) + table<int, bool> alreadyAssisted + + foreach( DamageHistoryStruct attackerInfo in soul.e.recentDamageHistory ) { - alreadyAssisted[attackerInfo.attacker.GetEncodedEHandle()] <- true - AddPlayerScore(attackerInfo.attacker, "TitanAssist" ) - Remote_CallFunction_NonReplay( attackerInfo.attacker, "ServerCallback_SetAssistInformation", attackerInfo.damageSourceId, attacker.GetEncodedEHandle(), victim.GetEncodedEHandle(), attackerInfo.time ) + if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == soul ) + continue + + bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false + if( attackerInfo.attacker != attacker && !exists ) + { + alreadyAssisted[attackerInfo.attacker.GetEncodedEHandle()] <- true + AddPlayerScore(attackerInfo.attacker, "TitanAssist" ) + Remote_CallFunction_NonReplay( attackerInfo.attacker, "ServerCallback_SetAssistInformation", attackerInfo.damageSourceId, attacker.GetEncodedEHandle(), soul.GetEncodedEHandle(), attackerInfo.time ) + } } } + + if( !victim.IsNPC() ) // don't let killing a npc titan plays dialogue + KilledPlayerTitanDialogue( attacker, victim ) } void function ScoreEvent_NPCKilled( entity victim, entity attacker, var damageInfo ) @@ -215,9 +248,66 @@ void function ScoreEvent_NPCKilled( entity victim, entity attacker, var damageIn AddPlayerScore( attacker, ScoreEventForNPCKilled( victim, damageInfo ), victim ) } catch ( ex ) {} + + if ( !attacker.IsPlayer() ) + return + + // mayhem/onslaught (timed killstreaks vs AI) + + // reset before checking + if ( Time() - attacker.s.lastKillTime_Mayhem > MAYHEM_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Mayhem = 0 + attacker.s.lastKillTime_Mayhem = Time() + } + if ( Time() - attacker.s.lastKillTime_Mayhem <= MAYHEM_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Mayhem++ + + if ( attacker.s.currentTimedKillstreak_Mayhem == MAYHEM_REQUIREMENT_KILLS ) + AddPlayerScore( attacker, "Mayhem" ) + } + + // reset before checking + if ( Time() - attacker.s.lastKillTime_Onslaught > ONSLAUGHT_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Onslaught = 0 + attacker.s.lastKillTime_Onslaught = Time() + } + if ( Time() - attacker.s.lastKillTime_Onslaught <= ONSLAUGHT_REQUIREMENT_TIME ) + { + attacker.s.currentTimedKillstreak_Onslaught++ + + if ( attacker.s.currentTimedKillstreak_Onslaught == ONSLAUGHT_REQUIREMENT_KILLS ) + AddPlayerScore( attacker, "Onslaught" ) + } } +void function ScoreEvent_MatchComplete( int winningTeam ) +{ + foreach( entity player in GetPlayerArray() ) + { + AddPlayerScore( player, "MatchComplete" ) + SetPlayerChallengeMatchComplete( player ) + if ( player.GetTeam() == winningTeam ) + { + AddPlayerScore( player, "MatchVictory" ) + SetPlayerChallengeMatchWon( player, true ) + } + else + SetPlayerChallengeMatchWon( player, false ) + } +} +void function ScoreEvent_RoundComplete( int winningTeam ) +{ + foreach( entity player in GetPlayerArray() ) + { + AddPlayerScore( player, "RoundComplete" ) + if ( player.GetTeam() == winningTeam ) + AddPlayerScore( player, "RoundVictory" ) + } +} void function ScoreEvent_SetEarnMeterValues( string eventName, float earned, float owned, float coreScale = 1.0 ) { @@ -231,7 +321,7 @@ void function ScoreEvent_SetupEarnMeterValuesForMixedModes() // mixed modes in t { // todo needs earn/overdrive values // player-controlled stuff - ScoreEvent_SetEarnMeterValues( "KillPilot", 0.07, 0.15 ) + ScoreEvent_SetEarnMeterValues( "KillPilot", 0.07, 0.15, 0.33 ) // 5% for titan cores ScoreEvent_SetEarnMeterValues( "KillTitan", 0.0, 0.15 ) ScoreEvent_SetEarnMeterValues( "TitanKillTitan", 0.0, 0.0 ) // unsure ScoreEvent_SetEarnMeterValues( "PilotBatteryStolen", 0.0, 0.35 ) // this actually just doesn't have overdrive in vanilla even @@ -251,3 +341,42 @@ void function ScoreEvent_SetupEarnMeterValuesForTitanModes() { // relatively sure we don't have to do anything here but leaving this function for consistency } + +// faction dialogue +void function KilledPlayerTitanDialogue( entity attacker, entity victim ) +{ + if( !attacker.IsPlayer() ) + return + entity titan + if ( victim.IsTitan() ) + titan = victim + + if( !IsValid( titan ) ) + return + string titanCharacterName = GetTitanCharacterName( titan ) + + switch( titanCharacterName ) + { + case "ion": + PlayFactionDialogueToPlayer( "kc_pilotkillIon", attacker ) + return + case "tone": + PlayFactionDialogueToPlayer( "kc_pilotkillTone", attacker ) + return + case "legion": + PlayFactionDialogueToPlayer( "kc_pilotkillLegion", attacker ) + return + case "scorch": + PlayFactionDialogueToPlayer( "kc_pilotkillScorch", attacker ) + return + case "ronin": + PlayFactionDialogueToPlayer( "kc_pilotkillRonin", attacker ) + return + case "northstar": + PlayFactionDialogueToPlayer( "kc_pilotkillNorthstar", attacker ) + return + default: + PlayFactionDialogueToPlayer( "kc_pilotkilltitan", attacker ) + return + } +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut index aa2fc108..510a9b7e 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectator.gnut @@ -170,6 +170,9 @@ void function SpectatorFunc_Default( entity player ) { player.SetObserverTarget( target ) player.StartObserverMode( OBS_MODE_CHASE ) + // the delay of 0.1 seems to fix the spec_mode command not working + // when using the keybind + player.SetSpecReplayDelay( 0.1 ) } catch ( ex ) { } } @@ -215,9 +218,12 @@ bool function ClientCommandCallback_spec_mode( entity player, array<string> args else if ( player.GetObserverMode() == OBS_MODE_IN_EYE ) { // set to third person spectate - player.SetSpecReplayDelay( 0.0 ) + + // the delay of 0.1 seems to fix the spec_mode command not working + // when using the keybind + player.SetSpecReplayDelay( 0.1 ) player.StartObserverMode( OBS_MODE_CHASE ) } return true -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut index 0e8b58f4..74a9088b 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut @@ -1,3 +1,5 @@ +untyped // because entity.s + global function Stats_Init global function AddStatCallback global function Stats_SaveStatDelayed @@ -12,67 +14,1105 @@ global function PreScoreEventUpdateStats global function PostScoreEventUpdateStats global function Stats_OnPlayerDidDamage +struct { + table< string, array<string> > refs + table< string, array< void functionref( entity, float, string ) > > callbacks + + table< entity, table< string, int > > cachedIntStatChanges + table< table< string, float > > cachedFloatStatChanges + + table< entity, float > playerKills + table< entity, float > playerKillsPvp + table< entity, float > playerDeaths + table< entity, float > playerDeathsPvp + + bool isFirstStrike = true +} file + void function Stats_Init() { + AddCallback_OnPlayerKilled( OnPlayerOrNPCKilled ) + AddCallback_OnNPCKilled( OnPlayerOrNPCKilled ) + AddCallback_OnPlayerRespawned( OnPlayerRespawned ) + AddCallback_OnClientConnected( OnClientConnected ) + AddCallback_OnClientDisconnected( OnClientDisconnected ) + AddCallback_GameStateEnter( eGameState.WinnerDetermined, OnWinnerDetermined ) + thread HandleDistanceAndTimeStats_Threaded() + thread SaveStatsPeriodically_Threaded() } -void function AddStatCallback(string statCategory, string statAlias, string statSubAlias, void functionref(entity, float, string) callback, string subRef) +void function AddStatCallback( string statCategory, string statAlias, string statSubAlias, void functionref( entity, float, string ) callback, string subRef ) { + if ( !IsValidStat( statCategory, statAlias, statSubAlias ) ) + throw format( "INVALID STAT: %s : %s : %s", statCategory, statAlias, statSubAlias ) + + + string statVar = GetStatVar( statCategory, statAlias, statSubAlias ) + if ( statVar in file.refs ) + { + file.refs[ statVar ].append( subRef ) + file.callbacks[ statVar ].append( callback ) + } + else + { + file.refs[ statVar ] <- [ subRef ] + file.callbacks[ statVar ] <- [ callback ] + } } -void function Stats_SaveStatDelayed(entity player, string statCategory, string statAlias, string statSubAlias) +// a lot of this file seems to be doing caching of stats in some way +void function Stats_SaveStatDelayed( entity player, string statCategory, string statAlias, string statSubAlias, float delay = 0.1 ) { + // idk how long the delay is meant to be but whatever + wait delay + + if ( !IsValid( player ) ) + return + + Stats_SaveStat( player, statCategory, statAlias, statSubAlias ) +} + +void function Stats_SaveAllStats( entity player ) +{ + if ( player in file.cachedIntStatChanges ) + { + foreach( string key, int val in file.cachedIntStatChanges[ player ] ) + { + player.SetPersistentVar( key, player.GetPersistentVarAsInt( key ) + val ) + } + + delete file.cachedIntStatChanges[ player ] + } + // save cached float stat change + if ( player in file.cachedFloatStatChanges ) + { + foreach( string key, float val in file.cachedFloatStatChanges[ player ] ) + { + player.SetPersistentVar( key, expect float( player.GetPersistentVar( key ) ) + val ) + } + delete file.cachedFloatStatChanges[ player ] + } } -int function PlayerStat_GetCurrentInt(entity player, string statCategory, string statAlias, string statSubAlias) +void function Stats_SaveStat( entity player, string statCategory, string statAlias, string statSubAlias ) { + string stat = GetStatVar( statCategory, statAlias, statSubAlias ) + // save cached int stat change + if ( player in file.cachedIntStatChanges && stat in file.cachedIntStatChanges[ player ] ) + { + player.SetPersistentVar( stat, player.GetPersistentVarAsInt( stat ) + file.cachedIntStatChanges[ player ][ stat ] ) + delete file.cachedIntStatChanges[ player ][ stat ] + return + } + // save cached float stat change + if ( player in file.cachedFloatStatChanges && stat in file.cachedFloatStatChanges[ player ] ) + { + player.SetPersistentVar( stat, expect float( player.GetPersistentVar( stat ) ) + file.cachedFloatStatChanges[ player ][ stat ] ) + delete file.cachedFloatStatChanges[ player ][ stat ] + return + } +} + +// this gets the cached change, not the actual value +int function PlayerStat_GetCurrentInt( entity player, string statCategory, string statAlias, string statSubAlias ) +{ + string str = GetStatVar( statCategory, statAlias, statSubAlias ) + + if ( player in file.cachedIntStatChanges && str in file.cachedIntStatChanges[ player ] ) + return file.cachedIntStatChanges[ player ][ str ] return 0 } -float function PlayerStat_GetCurrentFloat(entity player, string statCategory, string statAlias, string statSubAlias) +// this gets the cached change, not the actual value +float function PlayerStat_GetCurrentFloat( entity player, string statCategory, string statAlias, string statSubAlias ) { + string str = GetStatVar( statCategory, statAlias, statSubAlias ) + + if ( player in file.cachedFloatStatChanges && str in file.cachedFloatStatChanges[ player ] ) + return file.cachedFloatStatChanges[ player ][ str ] return 0 } -void function UpdatePlayerStat(entity player, string statCategory, string subStat, int count = 0) +void function UpdatePlayerStat( entity player, string statCategory, string subStat, int count = 1, string statAlias = "" ) { + if ( !IsValid( player ) ) + return + + Stats_IncrementStat( player, statCategory, subStat, statAlias, count.tofloat() ) +} + +void function IncrementPlayerDidPilotExecutionWhileCloaked( entity player ) +{ + UpdatePlayerStat( player, "kills_stats", "pilotExecutePilotWhileCloaked" ) +} + +void function UpdateTitanDamageStat( entity attacker, float savedDamage, var damageInfo ) +{ + if ( !IsValid( attacker ) ) + return + + Stats_IncrementStat( attacker, "titan_stats", "titanDamage", GetTitanCharacterName( attacker ), savedDamage ) +} + +void function UpdateTitanWeaponDamageStat( entity attacker, float savedDamage, var damageInfo ) +{ + if ( !IsValid( attacker ) ) + return + + string weaponName = GetPersistenceRefFromDamageInfo( damageInfo ) + if ( weaponName == "" ) + return + + Stats_IncrementStat( attacker, "weapon_stats", "titanDamage", weaponName, savedDamage ) +} + +void function UpdateTitanCoreEarnedStat( entity player, entity titan, int count = 1 ) +{ + if ( !IsValid( player ) ) + return + + if ( !IsValid( titan ) ) + return + + Stats_IncrementStat( player, "titan_stats", "coresEarned", GetTitanCharacterName( titan ), count.tofloat() ) +} + +void function PreScoreEventUpdateStats( entity attacker, entity ent ) +{ + // used to track kill streaks ending i think ( that stuff gets reset during score event update ) +} + +void function PostScoreEventUpdateStats( entity attacker, entity ent ) +{ + if ( !attacker.IsPlayer() ) + return + // used to track kill streaks starting maybe + if ( attacker.s.currentKillstreak == KILLINGSPREE_KILL_REQUIREMENT ) + { + // killingSpressAs_<chassis> + if ( attacker.IsTitan() ) + Stats_IncrementStat( attacker, "kills_stats", "killingSpressAs_" + GetTitanCharacterName( attacker ), "", 1.0 ) + + entity weapon = attacker.GetActiveWeapon() + // I guess if you dont have a valid active weapon when you get awarded a killing spree + // you dont get the stat. Too bad! + if ( !IsValid( weapon ) ) + return + Stats_IncrementStat( attacker, "weapon_kill_stats", "killingSprees", weapon.GetWeaponClassName(), 1.0 ) + } +} + +void function Stats_OnPlayerDidDamage( entity victim, var damageInfo ) +{ + // try and get the player + entity attacker = DamageInfo_GetAttacker( damageInfo ) + // get the player from their titan + if ( attacker.IsTitan() && IsPetTitan( attacker ) ) + attacker = attacker.GetTitanSoul().GetBossPlayer() + + if ( !attacker.IsPlayer() ) + return + + string weaponName = GetPersistenceRefFromDamageInfo( damageInfo ) + if ( weaponName == "" ) + return + + Stats_IncrementStat( attacker, "weapon_stats", "shotsHit", weaponName, 1.0 ) + + if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_CRITICAL ) + Stats_IncrementStat( attacker, "weapon_stats", "critHits", weaponName, 1.0 ) + if ( DamageInfo_GetCustomDamageType( damageInfo ) & DF_HEADSHOT ) + Stats_IncrementStat( attacker, "weapon_stats", "headshots", weaponName, 1.0 ) +} + +void function Stats_IncrementStat( entity player, string statCategory, string statAlias, string statSubAlias, float amount ) +{ + if ( !IsValidStat( statCategory, statAlias, statSubAlias ) ) + { + printt( "invalid stat: " + statCategory + " : " + statAlias + " : " + statSubAlias ) + return + } + + string str = GetStatVar( statCategory, statAlias, statSubAlias ) + int type = GetStatVarType( statCategory, statAlias, statSubAlias ) + + // stupid exception because respawn set this up as an int in script + // but it is actually a float, so the game will crash if we don't fix it somewhere + // i dont feel like committing all of sh_stats.gnut so im doing this instead + if ( str == "mapStats[%mapname%].hoursPlayed[%gamemode%]" ) + type = ePlayerStatType.FLOAT + + // this is rather hacky + string mode = GAMETYPE + int difficulty = GetDifficultyLevel() + if ( difficulty >= 5 ) + return + + string saveVar = Stats_GetFixedSaveVar( str, GetMapName(), mode, difficulty.tostring() ) + // check if the map and mode exist in persistence + try + { + PersistenceGetEnumIndexForItemName( "gamemodes", mode ) + PersistenceGetEnumIndexForItemName( "maps", GetMapName() ) + } + catch( ex ) + { + // if we have an invalid mode or map for persistence, and it is used in the + // persistence string, we can't save the persistence so we have to just return + if ( str != saveVar ) + { + //printt( ex, str, GetMapName(), mode ) // Commented out due to spamming logs on invalid modes (e.g. Gun Game, Infection, ...) + return + } + } + str = saveVar + + switch ( type ) + { + case ePlayerStatType.INT: + // populate table if needed + if ( !( player in file.cachedIntStatChanges ) ) + file.cachedIntStatChanges[ player ] <- {} + if ( !( str in file.cachedIntStatChanges[ player ] ) ) + file.cachedIntStatChanges[ player ][ str ] <- 0 + + file.cachedIntStatChanges[ player ][ str ] += amount.tointeger() + break + case ePlayerStatType.FLOAT: + // populate table if needed + if ( !( player in file.cachedFloatStatChanges ) ) + file.cachedFloatStatChanges[ player ] <- {} + if ( !( str in file.cachedFloatStatChanges[ player ] ) ) + file.cachedFloatStatChanges[ player ][ str ] <- 0.0 + + file.cachedFloatStatChanges[ player ][ str ] += amount + break + default: + throw "UNIMPLEMENTED STAT TYPE: " + type + } + + // amount here is never used + Stats_RunCallbacks( str, player, amount ) +} + +void function Stats_RunCallbacks( string statVar, entity player, float change ) +{ + if ( !( statVar in file.refs ) ) + return + + for( int i = 0; i < file.refs[ statVar ].len(); i++ ) + { + string ref = file.refs[ statVar ][ i ] + void functionref( entity, float, string ) callback = file.callbacks[ statVar ][ i ] + + callback( player, change, ref ) + } +} + +void function OnClientConnected( entity player ) +{ + Stats_IncrementStat( player, "game_stats", "game_joined", "", 1.0 ) +} + +void function OnClientDisconnected( entity player ) +{ + Stats_SaveAllStats( player ) + // maybe we can save this stuff, but idk if we can access persistence in this callback + if ( player in file.cachedIntStatChanges ) + delete file.cachedIntStatChanges[ player ] + + if ( player in file.cachedFloatStatChanges ) + delete file.cachedFloatStatChanges[ player ] +} + +void function OnPlayerOrNPCKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim.IsPlayer() ) + thread SetLastPosForDistanceStatValid_Threaded( victim, false ) + + HandleDeathStats( victim, attacker, damageInfo ) + + if( victim == attacker ) //Suicides are registering stats, afaik vanilla ignores them + return + + HandleKillStats( victim, attacker, damageInfo ) + HandleWeaponKillStats( victim, attacker, damageInfo ) + HandleTitanStats( victim, attacker, damageInfo ) +} + +void function HandleDeathStats( entity player, entity attacker, var damageInfo ) +{ + if ( !IsValid( player ) || !player.IsPlayer() ) + return + + if ( player in file.playerDeaths ) + file.playerDeaths[ player ]++ + else + file.playerDeaths[ player ] <- 1.0 + // total + Stats_IncrementStat( player, "deaths_stats", "total", "", 1.0 ) + + // these all rely on the attacker being valid + if ( IsValid( attacker ) ) + { + // totalPVP + // note: I'm not sure if owned entities count towards totalPVP + // such as auto-titans, turrets, etc. + if ( attacker.IsPlayer() || attacker.GetBossPlayer() ) + { + if ( player in file.playerDeathsPvp ) + file.playerDeathsPvp[ player ]++ + else + file.playerDeathsPvp[ player ] <- 1.0 + Stats_IncrementStat( player, "deaths_stats", "totalPVP", "", 1.0 ) + } + + // byPilots + if ( IsPilot( attacker ) ) + Stats_IncrementStat( player, "deaths_stats", "byPilots", "", 1.0 ) + + // byTitan_<chassis> + if ( attacker.IsTitan() && attacker.IsPlayer() ) + Stats_IncrementStat( player, "deaths_stats", "byTitan_" + GetTitanCharacterName( attacker ), "", 1.0 ) + + // bySpectres + if ( IsSpectre( attacker ) ) + Stats_IncrementStat( player, "deaths_stats", "bySpectres", "", 1.0 ) + + // byGrunts + if ( IsGrunt( attacker ) ) + Stats_IncrementStat( player, "deaths_stats", "byGrunts", "", 1.0 ) + + // byNPCTitans_<chassis> + if ( attacker.IsTitan() && attacker.IsNPC() ) + Stats_IncrementStat( player, "deaths_stats", "byNPCTitans_" + GetTitanCharacterName( attacker ), "", 1.0 ) + } + + // asPilot + if ( IsPilot( player ) ) + Stats_IncrementStat( player, "deaths_stats", "asPilot", "", 1.0 ) + + // asTitan_<chassis> + if ( player.IsTitan() ) + Stats_IncrementStat( player, "deaths_stats", "asTitan_" + GetTitanCharacterName( player ), "", 1.0 ) + + // suicides + if ( IsSuicide( attacker, player, DamageInfo_GetDamageSourceIdentifier( damageInfo ) ) ) + Stats_IncrementStat( player, "deaths_stats", "suicides", "", 1.0 ) + + // whileEjecting + if ( player.p.pilotEjecting ) + Stats_IncrementStat( player, "deaths_stats", "whileEjecting", "", 1.0 ) +} + +void function HandleWeaponKillStats( entity victim, entity attacker, var damageInfo ) +{ + if ( !IsValid( attacker ) ) + return + + // get the player and it's pet titan + entity player + entity playerPetTitan + if ( attacker.IsPlayer() ) + { + // the player is just the attacker + player = attacker + playerPetTitan = player.GetPetTitan() + } + else if ( attacker.IsTitan() && IsPetTitan( attacker ) ) + { + // the attacker is the player's auto titan + player = attacker.GetTitanSoul().GetBossPlayer() + playerPetTitan = attacker + } + else + { + // attacker could be something like an NPC, or worldspawn + return + } + + string damageSourceStr = GetPersistenceRefFromDamageInfo( damageInfo ) + // cant do weapon stats for no weapon + if ( damageSourceStr == "" ) + return + + // check things once, for performance + int damageSource = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + bool victimIsPlayer = victim.IsPlayer() + bool victimIsNPC = victim.IsNPC() + bool victimIsPilot = IsPilot( victim ) + bool victimIsTitan = victim.IsTitan() + + // total + Stats_IncrementStat( player, "weapon_kill_stats", "total", damageSourceStr, 1.0 ) + + // pilots + if ( victimIsPilot ) + Stats_IncrementStat( player, "weapon_kill_stats", "pilots", damageSourceStr, 1.0 ) + + // ejecting_pilots + if ( victimIsPilot && victim.p.pilotEjecting ) + Stats_IncrementStat( player, "weapon_kill_stats", "ejecting_pilots", damageSourceStr, 1.0 ) + + // titansTotal + if ( victimIsTitan ) + Stats_IncrementStat( player, "weapon_kill_stats", "titansTotal", damageSourceStr, 1.0 ) + // spectres + if ( IsSpectre( victim ) ) + Stats_IncrementStat( player, "weapon_kill_stats", "spectres", damageSourceStr, 1.0 ) + + // marvins + if ( IsMarvin( victim ) ) + Stats_IncrementStat( player, "weapon_kill_stats", "marvins", damageSourceStr, 1.0 ) + + // grunts + if ( IsGrunt( victim ) ) + Stats_IncrementStat( player, "weapon_kill_stats", "grunts", damageSourceStr, 1.0 ) + + // ai + if ( victimIsNPC ) + Stats_IncrementStat( player, "weapon_kill_stats", "ai", damageSourceStr, 1.0 ) + + // titans_<chassis> + if ( victimIsPlayer && victimIsTitan ) + Stats_IncrementStat( player, "weapon_kill_stats", "titans_" + GetTitanCharacterName( victim ), damageSourceStr, 1.0 ) + + // npcTitans_<chassis> + if ( victimIsNPC && victimIsTitan ) + Stats_IncrementStat( player, "weapon_kill_stats", "npcTitans_" + GetTitanCharacterName( victim ), damageSourceStr, 1.0 ) } -void function IncrementPlayerDidPilotExecutionWhileCloaked(entity player) +void function HandleKillStats( entity victim, entity attacker, var damageInfo ) { + if ( !IsValid( attacker ) ) + return + // get the player and it's pet titan + entity player + entity playerPetTitan + entity inflictor = DamageInfo_GetInflictor( damageInfo ) + + if ( IsValid( inflictor ) ) + { + if ( inflictor.IsProjectile() && IsValid( inflictor.GetOwner() ) ) // Attackers are always the final entity in the owning hierarchy, projectile owners though migh be a player's NPC minion (i.e Auto-Titans) + attacker = inflictor.GetOwner() + + else if ( inflictor.IsNPC() ) // NPCs are bypassed as Attackers if they are owned by players, instead they become just inflictors + attacker = inflictor + } + + if ( attacker.IsNPC() ) + { + if ( !attacker.IsTitan() ) // Normal NPCs case + return + + if ( !IsPetTitan( attacker ) ) // NPC Titans case + return + + player = attacker.GetTitanSoul().GetBossPlayer() + playerPetTitan = attacker + } + else if ( attacker.IsPlayer() ) // Still checks this because worldspawn might be the attacker + player = attacker + else + return + + // check things once, for performance + int damageSource = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + bool victimIsPlayer = victim.IsPlayer() + bool victimIsNPC = victim.IsNPC() + bool victimIsPilot = IsPilot( victim ) + bool victimIsTitan = victim.IsTitan() + + if ( player in file.playerKills ) + file.playerKills[ player ]++ + else + file.playerKills[ player ] <- 1.0 + // total + Stats_IncrementStat( player, "kills_stats", "total", "", 1.0 ) + + // totalPVP + if ( victimIsPlayer ) + { + if ( player in file.playerKillsPvp ) + file.playerKillsPvp[ player ]++ + else + file.playerKillsPvp[ player ] <- 1.0 + Stats_IncrementStat( player, "kills_stats", "totalPVP", "", 1.0 ) + } + + // pilots + if ( victimIsPilot ) + Stats_IncrementStat( player, "kills_stats", "pilots", "", 1.0 ) + + // spectres + if ( IsSpectre( victim ) ) + Stats_IncrementStat( player, "kills_stats", "spectres", "", 1.0 ) + + // marvins + if ( IsMarvin( victim ) ) + Stats_IncrementStat( player, "kills_stats", "marvins", "", 1.0 ) + + // grunts + if ( IsGrunt( victim ) ) + Stats_IncrementStat( player, "kills_stats", "grunts", "", 1.0 ) + + // totalTitans + if ( victimIsTitan ) + Stats_IncrementStat( player, "kills_stats", "totalTitans", "", 1.0 ) + + // totalPilots + if ( victimIsPilot ) + Stats_IncrementStat( player, "kills_stats", "totalPilots", "", 1.0 ) + + // totalNPC + if ( victimIsNPC ) + Stats_IncrementStat( player, "kills_stats", "totalNPC", "", 1.0 ) + + // totalTitansWhileDoomed + if ( victimIsTitan && attacker.IsTitan() && GetDoomedState( attacker ) ) + Stats_IncrementStat( player, "kills_stats", "totalTitansWhileDoomed", "", 1.0 ) + + // asPilot + if ( IsPilot( attacker ) ) + Stats_IncrementStat( player, "kills_stats", "asPilot", "", 1.0 ) + + // totalAssists + // assistsTotal ( weapon_kill_stats ) + // note: eww + table<int, bool> alreadyAssisted + // titans store their recentDamageHistory in the soul + entity assistVictim = ( victim.IsTitan() && IsValid( victim.GetTitanSoul() ) ) ? victim.GetTitanSoul() : victim + foreach( DamageHistoryStruct attackerInfo in assistVictim.e.recentDamageHistory ) + { + if ( !IsValid( attackerInfo.attacker ) || !attackerInfo.attacker.IsPlayer() || attackerInfo.attacker == assistVictim ) + continue + + bool exists = attackerInfo.attacker.GetEncodedEHandle() in alreadyAssisted ? true : false + if( attackerInfo.attacker != attacker && !exists ) + { + alreadyAssisted[ attackerInfo.attacker.GetEncodedEHandle() ] <- true + Stats_IncrementStat( attackerInfo.attacker, "kills_stats", "totalAssists", "", 1.0 ) + + string source = DamageSourceIDToString( attackerInfo.damageSourceId ) + + if ( IsValidStatItemString( source ) ) + Stats_IncrementStat( attackerInfo.attacker, "weapon_kill_stats", "assistsTotal", source, 1.0 ) + } + } + + // asTitan_<chassis> + if ( player.IsTitan() ) + Stats_IncrementStat( player, "kills_stats", "asTitan_" + GetTitanCharacterName( player ), "", 1.0 ) + + // firstStrikes + if ( file.isFirstStrike && attacker.IsPlayer() && victimIsPlayer ) + { + Stats_IncrementStat( player, "kills_stats", "firstStrikes", "", 1.0 ) + file.isFirstStrike = false + } + + // ejectingPilots + if ( victimIsPilot && victim.p.pilotEjecting ) + Stats_IncrementStat( player, "kills_stats", "ejectingPilots", "", 1.0 ) + + // whileEjecting + if ( attacker.IsPlayer() && attacker.p.pilotEjecting ) + Stats_IncrementStat( player, "kills_stats", "whileEjecting", "", 1.0 ) + + // cloakedPilots + if ( victimIsPilot && IsCloaked( victim ) ) + Stats_IncrementStat( player, "kills_stats", "cloakedPilots", "", 1.0 ) + + // whileCloaked + if ( attacker == player && IsCloaked( attacker ) ) + Stats_IncrementStat( player, "kills_stats", "whileCloaked", "", 1.0 ) + + // wallrunningPilots + if ( victimIsPilot && victim.IsWallRunning() ) + Stats_IncrementStat( player, "kills_stats", "wallrunningPilots", "", 1.0 ) + + // whileWallrunning + if ( attacker == player && attacker.IsWallRunning() ) + Stats_IncrementStat( player, "kills_stats", "whileWallrunning", "", 1.0 ) + + // wallhangingPilots + if ( victimIsPilot && victim.IsWallHanging() ) + Stats_IncrementStat( player, "kills_stats", "wallhangingPilots", "", 1.0 ) + + // whileWallhanging + if ( attacker == player && attacker.IsWallHanging() ) + Stats_IncrementStat( player, "kills_stats", "whileWallhanging", "", 1.0 ) + + // pilotExecution + if ( damageSource == eDamageSourceId.human_execution ) + Stats_IncrementStat( player, "kills_stats", "pilotExecution", "", 1.0 ) + + // pilotExecutePilot + if ( victimIsPilot && damageSource == eDamageSourceId.human_execution ) + Stats_IncrementStat( player, "kills_stats", "pilotExecutePilot", "", 1.0 ) + + // pilotKillsWithHoloPilotActive + if ( victimIsPilot && GetDecoyActiveCountForPlayer( player ) > 0 ) + Stats_IncrementStat( player, "kills_stats", "pilotKillsWithHoloPilotActive", "", 1.0 ) + + // pilotKillsWithAmpedWallActive + if ( victimIsPilot && GetAmpedWallsActiveCountForPlayer( player ) > 0 ) + Stats_IncrementStat( player, "kills_stats", "pilotKillsWithAmpedWallActive", "", 1.0 ) + + // pilotExecutePilotUsing_<execution> + if ( victimIsPilot && damageSource == eDamageSourceId.human_execution ) + Stats_IncrementStat( player, "kills_stats", "pilotExecutePilotUsing_" + player.p.lastExecutionUsed, "", 1.0 ) + + // pilotKickMelee + if ( damageSource == eDamageSourceId.human_melee ) + Stats_IncrementStat( player, "kills_stats", "pilotKickMelee", "", 1.0 ) + + // pilotKickMeleePilot + if ( victimIsPilot && damageSource == eDamageSourceId.human_melee ) + Stats_IncrementStat( player, "kills_stats", "pilotKickMeleePilot", "", 1.0 ) + + // titanMelee + if ( DamageIsTitanMelee( damageSource ) ) + Stats_IncrementStat( player, "kills_stats", "titanMelee", "", 1.0 ) + + // titanMeleePilot + if ( victimIsPilot && DamageIsTitanMelee( damageSource ) ) + Stats_IncrementStat( player, "kills_stats", "titanMeleePilot", "", 1.0 ) + + // titanStepCrush + if ( IsTitanCrushDamage( damageInfo ) ) + Stats_IncrementStat( player, "kills_stats", "titanStepCrush", "", 1.0 ) + + // titanStepCrushPilot + if ( victimIsPilot && IsTitanCrushDamage( damageInfo ) ) + Stats_IncrementStat( player, "kills_stats", "titanStepCrushPilot", "", 1.0 ) + + // titanExocution<capitalisedChassis> + // note: RESPAWN WHY? EXPLAIN + if ( damageSource == eDamageSourceId.titan_execution ) + { + string titanName = GetTitanCharacterName( player ) + titanName = titanName.slice( 0, 1 ).toupper() + titanName.slice( 1, titanName.len() ) + Stats_IncrementStat( player, "kills_stats", "titanExocution" + titanName, "", 1.0 ) + } + + // titanFallKill + if ( damageSource == eDamageSourceId.damagedef_titan_fall ) + Stats_IncrementStat( player, "kills_stats", "titanFallKill", "", 1.0 ) + + // petTitanKillsFollowMode + if ( attacker == playerPetTitan && player.GetPetTitanMode() == eNPCTitanMode.FOLLOW ) + Stats_IncrementStat( player, "kills_stats", "petTitanKillsFollowMode", "", 1.0 ) + + // petTitanKillsGuardMode + if ( attacker == playerPetTitan && player.GetPetTitanMode() == eNPCTitanMode.STAY ) + Stats_IncrementStat( player, "kills_stats", "petTitanKillsGuardMode", "", 1.0 ) + + // rodeo_total + if ( damageSource == eDamageSourceId.rodeo_battery_removal ) + Stats_IncrementStat( player, "kills_stats", "rodeo_total", "", 1.0 ) + + // pilot_headshots_total + if ( victimIsPilot && DamageInfo_GetCustomDamageType( damageInfo ) & DF_HEADSHOT ) + Stats_IncrementStat( player, "kills_stats", "pilot_headshots_total", "", 1.0 ) + + // evacShips + if ( IsEvacDropship( victim ) ) + Stats_IncrementStat( player, "kills_stats", "evacShips", "", 1.0 ) + + // nuclearCore + if ( damageSource == eDamageSourceId.damagedef_nuclear_core ) + Stats_IncrementStat( player, "kills_stats", "nuclearCore", "", 1.0 ) + + // meleeWhileCloaked + if ( IsCloaked( attacker ) && damageSource == eDamageSourceId.human_melee ) + Stats_IncrementStat( player, "kills_stats", "meleeWhileCloaked", "", 1.0 ) + + // titanKillsAsPilot + if ( victimIsTitan && IsPilot( attacker ) ) + Stats_IncrementStat( player, "kills_stats", "titanKillsAsPilot", "", 1.0 ) + + // pilotKillsWhileStimActive + if ( victimIsPilot && StatusEffect_Get( attacker, eStatusEffect.stim_visual_effect ) <= 0 ) + Stats_IncrementStat( player, "kills_stats", "pilotKillsWhileStimActive", "", 1.0 ) + + // pilotKillsAsTitan + if ( victimIsPilot && attacker.IsTitan() ) + Stats_IncrementStat( player, "kills_stats", "pilotKillsAsTitan", "", 1.0 ) + + // pilotKillsAsPilot + if ( victimIsPilot && IsPilot( attacker ) ) + Stats_IncrementStat( player, "kills_stats", "pilotKillsAsPilot", "", 1.0 ) + + // titanKillsAsTitan + if ( victimIsTitan && attacker.IsTitan() ) + Stats_IncrementStat( player, "kills_stats", "titanKillsAsTitan", "", 1.0 ) } -void function UpdateTitanDamageStat(entity attacker, float savedDamage, var damageInfo) +void function HandleTitanStats( entity victim, entity attacker, var damageInfo ) { + if ( !IsValid( attacker ) ) + return + + // get the player and it's pet titan + entity player + entity playerPetTitan + if ( attacker.IsPlayer() ) + { + // the player is just the attacker + player = attacker + playerPetTitan = player.GetPetTitan() + } + else if ( attacker.IsTitan() && IsPetTitan( attacker ) ) + { + // the attacker is the player's auto titan + player = attacker.GetTitanSoul().GetBossPlayer() + playerPetTitan = attacker + } + else + { + // attacker could be something like an NPC, or worldspawn + return + } + + int damageSource = DamageInfo_GetDamageSourceIdentifier( damageInfo ) + bool victimIsPlayer = victim.IsPlayer() + bool victimIsNPC = victim.IsNPC() + bool victimIsPilot = IsPilot( victim ) + bool victimIsTitan = victim.IsTitan() + bool titanIsPrime = IsTitanPrimeTitan( player ) + // pilots + if ( victimIsPilot && attacker.IsTitan() ) + Stats_IncrementStat( player, "titan_stats", "pilots", GetTitanCharacterName( attacker ), 1.0 ) + + // titansTotal + if ( victimIsTitan && attacker.IsTitan() ) + Stats_IncrementStat( player, "titan_stats", "titansTotal", GetTitanCharacterName( attacker ), 1.0 ) + + // pilotsAsPrime + if ( victimIsPilot && attacker.IsTitan() && titanIsPrime ) + Stats_IncrementStat( player, "titan_stats", "pilotsAsPrime", GetTitanCharacterName( attacker ), 1.0 ) + + // titansAsPrime + if ( victimIsTitan && attacker.IsTitan() && titanIsPrime ) + Stats_IncrementStat( player, "titan_stats", "titansAsPrime", GetTitanCharacterName( attacker ), 1.0 ) + + // executionsAsPrime + if ( damageSource == eDamageSourceId.titan_execution && attacker.IsTitan() && titanIsPrime ) + Stats_IncrementStat( player, "titan_stats", "executionsAsPrime", GetTitanCharacterName( attacker ), 1.0 ) } -void function UpdateTitanWeaponDamageStat(entity attacker, float savedDamage, var damageInfo) +void function OnPlayerRespawned( entity player ) { + thread SetLastPosForDistanceStatValid_Threaded( player, true ) +} + +void function OnWinnerDetermined() +{ + // award players for match completed, wins, and losses + foreach ( entity player in GetPlayerArray() ) + { + Stats_IncrementStat( player, "game_stats", "game_completed", "", 1.0 ) + + if ( player.GetTeam() == GetWinningTeam() ) + Stats_IncrementStat( player, "game_stats", "game_won", "", 1.0 ) + else + Stats_IncrementStat( player, "game_stats", "game_lost", "", 1.0 ) + } + + if ( IsValidGamemodeString( GAMETYPE ) ) + { + // award players with matches played on the mode + foreach ( entity player in GetPlayerArray() ) + { + Stats_IncrementStat( player, "game_stats", "mode_played", GAMETYPE, 1.0 ) + + if ( player.GetTeam() == GetWinningTeam() ) + Stats_IncrementStat( player, "game_stats", "mode_won", GAMETYPE, 1.0 ) + } + } + + // update player's KD + foreach ( entity player in GetPlayerArray() ) + { + // kd stats + // index 0 is most recent game + // index 9 is least recent game + float playerKills = ( player in file.playerKills ) ? file.playerKills[ player ] : 0.0 + float playerDeaths = ( player in file.playerDeaths ) ? file.playerDeaths[ player ] : 0.0 + float kdratio_match + if ( playerDeaths == 0.0 ) + kdratio_match = playerKills + else + kdratio_match = playerKills / playerDeaths + + float playerKillsPvp = ( player in file.playerKillsPvp ) ? file.playerKillsPvp[ player ] : 0.0 + float playerDeathsPvp = ( player in file.playerDeathsPvp ) ? file.playerDeathsPvp[ player ] : 0.0 + float kdratiopvp_match + if ( playerDeathsPvp == 0.0 ) + kdratiopvp_match = playerKillsPvp + else + kdratiopvp_match = playerKillsPvp / playerDeathsPvp + + float totalDeaths = player.GetPersistentVarAsInt( "deathStats.total" ).tofloat() + float totalKills = player.GetPersistentVarAsInt( "killStats.total" ).tofloat() + float totalDeathsPvp = player.GetPersistentVarAsInt( "deathStats.totalPVP" ).tofloat() + float totalKillsPvp = player.GetPersistentVarAsInt( "killStats.totalPVP" ).tofloat() + float kdratio_lifetime + if ( totalDeaths == 0.0 ) + kdratio_lifetime = totalKills + else + kdratio_lifetime = totalKills / totalDeaths + float kdratio_lifetimepvp + if ( totalDeathsPvp == 0.0 ) + kdratio_lifetimepvp = totalKillsPvp + else + kdratio_lifetimepvp = totalKillsPvp / totalDeathsPvp + + // shift stats by 1 to make room for new game data + for ( int i = NUM_GAMES_TRACK_KDRATIO - 2; i >= 0; --i ) + { + player.SetPersistentVar( format( "kdratio_match[%i]", ( i + 1 ) ), player.GetPersistentVar( format("kdratio_match[%i]", i ) ) ) + player.SetPersistentVar( format( "kdratiopvp_match[%i]", ( i + 1 ) ), player.GetPersistentVar( format( "kdratiopvp_match[%i]", i ) ) ) + } + // add new game data + player.SetPersistentVar( "kdratio_match[0]", kdratio_match ) + player.SetPersistentVar( "kdratiopvp_match[0]", kdratiopvp_match ) + player.SetPersistentVar( "kdratio_lifetime", kdratio_lifetime ) + player.SetPersistentVar( "kdratio_lifetime_pvp", kdratio_lifetimepvp ) + } + + // award mvp and top 3 in each team + if ( !IsFFAGame() ) + { + string gamemode = GameRules_GetGameMode() + int functionref( entity, entity ) compareFunc = GameMode_GetScoreCompareFunc( gamemode ) + + for( int team = 0; team < MAX_TEAMS; team++ ) + { + array<entity> players = GetPlayerArrayOfTeam( team ) + if ( compareFunc == null ) + { + printt( "gamemode doesn't have a compare func to get the top 3" ) + return + } + players.sort( compareFunc ) + int maxAwards = int( min( players.len(), 3 ) ) + for ( int i = 0; i < maxAwards; i++ ) + { + if ( i == 0 ) + Stats_IncrementStat( players[ i ], "game_stats", "mvp", "", 1.0 ) + Stats_IncrementStat( players[ i ], "game_stats", "top3OnTeam", "", 1.0 ) + } + } + + } +} +void function SetLastPosForDistanceStatValid_Threaded( entity player, bool val ) +{ + WaitFrame() + if ( !IsValid( player ) ) + return + player.p.lastPosForDistanceStatValid = val } -void function UpdateTitanCoreEarnedStat( entity player, entity titan ) +// Respawn did this through stuff found in _entitystructs.gnut (stuff like stats_wallrunTime) +// but their implementation seems kinda bad. The advantage it has over this method is not polling +// every 0.25 seconds, and using movement callbacks and stuff instead. However, since i can't find +// callbacks for things like changing weapon, i would have to poll for that *anyway* and thus, +// there is no point in doing things Respawn's way here +void function HandleDistanceAndTimeStats_Threaded() { + // just to be safe + if ( IsLobby() ) + return + + while ( GetGameState() < eGameState.Playing ) + WaitFrame() + + float lastTickTime = Time() + + while( true ) + { + // track distance stats + foreach ( entity player in GetPlayerArray() ) + { + if ( !IsValid( player ) ) + continue + + if ( player.p.lastPosForDistanceStatValid ) + { + // not 100% sure on using Distance2D over Distance tbh + float distInches = Distance2D( player.p.lastPosForDistanceStat, player.GetOrigin() ) + float distMiles = distInches / 63360.0 + + // more generic distance stats + Stats_IncrementStat( player, "distance_stats", "total", "", distMiles ) + if ( player.IsTitan() ) + { + Stats_IncrementStat( player, "distance_stats", "asTitan_" + GetTitanCharacterName( player ), "", distMiles ) + Stats_IncrementStat( player, "distance_stats", "asTitan", "", distMiles ) + } + else + Stats_IncrementStat( player, "distance_stats", "asPilot", "", distMiles ) + + + string state = "" + // specific distance stats + if ( player.IsWallRunning() ) + state = "wallrunning" + else if ( PlayerIsRodeoingTitan( player ) ) + { + if ( player.GetTitanSoulBeingRodeoed().GetTeam() == player.GetTeam() ) + state = "onFriendlyTitan" + else + state = "onEnemyTitan" + } + else if ( player.IsZiplining() ) + state = "ziplining" + else if ( !player.IsOnGround() ) + state = "inAir" + + if ( state != "" ) + Stats_IncrementStat( player, "distance_stats", state, "", distMiles ) + } + + player.p.lastPosForDistanceStat = player.GetOrigin() + } + + float timeSeconds = Time() - lastTickTime + float timeHours = timeSeconds / 3600.0 + + // track time stats + foreach ( entity player in GetPlayerArray() ) + { + // first tick i dont count + if ( timeSeconds == 0 ) + break + + // more generic time stats + Stats_IncrementStat( player, "time_stats", "hours_total", "", timeHours ) + if ( player.IsTitan() ) + { + Stats_IncrementStat( player, "time_stats", "hours_as_titan_" + GetTitanCharacterName( player ), "", timeHours ) + Stats_IncrementStat( player, "time_stats", "hours_as_titan", "", timeHours ) + } + else + Stats_IncrementStat( player, "time_stats", "hours_as_pilot", "", timeHours ) + + string state = "" + // specific time stats + if ( !IsAlive( player ) ) + state = "hours_dead" + else if ( player.IsWallHanging() ) + state = "hours_wallhanging" + else if ( player.IsWallRunning() ) + state = "hours_wallrunning" + else if ( !player.IsOnGround() ) + state = "hours_inAir" + if ( state != "" ) + Stats_IncrementStat( player, "time_stats", state, "", timeHours ) + + // weapon time stats + entity activeWeapon = player.GetActiveWeapon() + if ( IsValid( activeWeapon ) ) + { + if ( IsValidStatItemString( activeWeapon.GetWeaponClassName() ) ) + Stats_IncrementStat( player, "weapon_stats", "hoursUsed", activeWeapon.GetWeaponClassName(), timeHours ) + + foreach( entity weapon in player.GetMainWeapons() ) + { + if ( IsValidStatItemString( weapon.GetWeaponClassName() ) ) + Stats_IncrementStat( player, "weapon_stats", "hoursEquipped", weapon.GetWeaponClassName(), timeHours ) + } + } + + // map time stats + Stats_IncrementStat( player, "game_stats", "hoursPlayed", "", timeHours ) + } + + lastTickTime = Time() + // not rly worth doing this every frame, just a couple of times per second should be fine + wait 0.25 + } +} + +// this is kinda shit +void function SaveStatsPeriodically_Threaded() +{ + while( true ) + { + foreach( entity player in GetPlayerArray() ) + { + if ( IsValid( player ) ) + Stats_SaveAllStats( player ) + } + wait 5 + } } -void function PreScoreEventUpdateStats(entity attacker, entity ent) +bool function IsValidGamemodeString( string mode ) { + int gameModeCount = PersistenceGetEnumCount( "gameModes" ) + for ( int modeIndex = 0; modeIndex < gameModeCount; modeIndex++ ) + { + string gameModeName = PersistenceGetEnumItemNameForIndex( "gameModes", modeIndex ) + + if ( gameModeName == mode ) + return true + } + return false } -void function PostScoreEventUpdateStats(entity attacker, entity ent) +bool function IsValidStatItemString( string item ) { + foreach( str in shGlobalMP.statsItemsList ) + { + if ( str == item ) + return true + } + return false } -void function Stats_OnPlayerDidDamage(entity player, var damageInfo) +string function GetPersistenceRefFromDamageInfo( var damageInfo ) { + string damageSourceString = DamageSourceIDToString( DamageInfo_GetDamageSourceIdentifier( damageInfo ) ) + + foreach( str in shGlobalMP.statsItemsList ) + { + if ( str == damageSourceString ) + return damageSourceString + } + return "" +} + +bool function DamageIsTitanMelee( int damageSourceId ) +{ + switch( damageSourceId ) + { + case eDamageSourceId.melee_titan_punch: + case eDamageSourceId.melee_titan_punch_ion: + case eDamageSourceId.melee_titan_punch_legion: + case eDamageSourceId.melee_titan_punch_tone: + case eDamageSourceId.melee_titan_punch_scorch: + case eDamageSourceId.melee_titan_punch_northstar: + case eDamageSourceId.melee_titan_punch_fighter: + case eDamageSourceId.melee_titan_sword: + case eDamageSourceId.melee_titan_sword_aoe: + return true + default: + return false + } + unreachable } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut index 341493ba..8d859ba6 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut @@ -339,7 +339,8 @@ void function PlayerWatchesWargamesIntro( entity player ) void function DelayedGamemodeAnnouncement( entity player ) { wait 1.0 - TryGameModeAnnouncement( player ) + if ( IsValid( player ) && IsAlive( player ) ) + TryGameModeAnnouncement( player ) } void function PlaySound_SimPod_DoorShut( entity playerFirstPersonProxy ) // stolen from sp_training diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut index 5bf150c0..d64e3a5b 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut @@ -130,7 +130,7 @@ entity function FindSpawnPoint( entity player, bool isTitan, bool useStartSpawnp { int team = player.GetTeam() if ( HasSwitchedSides() ) - team = GetOtherTeam( team ) + team = ( team == TEAM_MILITIA ) ? TEAM_IMC : TEAM_MILITIA array<entity> spawnpoints if ( useStartSpawnpoint ) @@ -181,29 +181,19 @@ entity function GetBestSpawnpoint( entity player, array<entity> spawnpoints ) foreach ( entity spawnpoint in spawnpoints ) { if ( IsSpawnpointValid( spawnpoint, player.GetTeam() ) ) - { validSpawns.append( spawnpoint ) - - if ( validSpawns.len() == 3 ) // arbitrary small sample size - break - } } - if ( validSpawns.len() == 0 ) + if ( !validSpawns.len() ) { // no valid spawns, very bad, so dont care about spawns being valid anymore print( "found no valid spawns! spawns may be subpar!" ) foreach ( entity spawnpoint in spawnpoints ) - { validSpawns.append( spawnpoint ) - - if ( validSpawns.len() == 3 ) // arbitrary small sample size - break - } } // last resort - if ( validSpawns.len() == 0 ) + if ( !validSpawns.len() ) { print( "map has literally 0 spawnpoints, as such everything is fucked probably, attempting to use info_player_start if present" ) entity start = GetEnt( "info_player_start" ) @@ -215,7 +205,7 @@ entity function GetBestSpawnpoint( entity player, array<entity> spawnpoints ) } } - return validSpawns[ RandomInt( validSpawns.len() ) ] // slightly randomize it + return validSpawns.getrandom() // slightly randomize it } bool function IsSpawnpointValid( entity spawnpoint, int team ) @@ -232,15 +222,18 @@ bool function IsSpawnpointValid( entity spawnpoint, int team ) return false } + if( IsFFAGame() && !spawnpoint.IsVisibleToEnemies( team ) ) + return true + int compareTeam = spawnpoint.GetTeam() - if ( HasSwitchedSides() && ( compareTeam == TEAM_MILITIA || compareTeam == TEAM_IMC ) ) - compareTeam = GetOtherTeam( compareTeam ) - + if ( HasSwitchedSides() ) + compareTeam = ( compareTeam == TEAM_MILITIA ) ? TEAM_IMC : TEAM_MILITIA + foreach ( bool functionref( entity, int ) customValidationRule in file.customSpawnpointValidationRules ) if ( !customValidationRule( spawnpoint, team ) ) return false - if ( spawnpoint.GetTeam() > 0 && compareTeam != team && !IsFFAGame() ) + if ( spawnpoint.GetTeam() > 0 && compareTeam != team ) return false if ( spawnpoint.IsOccupied() ) @@ -261,10 +254,12 @@ bool function IsSpawnpointValid( entity spawnpoint, int team ) return false } - array<entity> projectiles = GetProjectileArrayEx( "any", TEAM_ANY, TEAM_ANY, spawnpoint.GetOrigin(), 600 ) - foreach ( entity projectile in projectiles ) - if ( projectile.GetTeam() != team ) - return false + const minEnemyDist = 1200.0 + array< entity > spawnBlockers = GetPlayerArrayEx( "any", TEAM_ANY, spawnpoint.GetTeam(), spawnpoint.GetOrigin(), minEnemyDist ) + spawnBlockers.extend( GetProjectileArrayEx( "any", TEAM_ANY, spawnpoint.GetTeam(), spawnpoint.GetOrigin(), minEnemyDist ) ) + spawnBlockers.extend( GetNPCArrayEx( "any", TEAM_ANY, spawnpoint.GetTeam(), spawnpoint.GetOrigin(), minEnemyDist ) ) + if ( spawnBlockers.len() ) + return false // los check return !spawnpoint.IsVisibleToEnemies( team ) @@ -396,11 +391,9 @@ void function InitPreferSpawnNodes() // frontline void function RateSpawnpoints_Frontline( int checkClass, array<entity> spawnpoints, int team, entity player ) { + float rating = RandomFloatRange( 0.0, 100.0 ) foreach ( entity spawnpoint in spawnpoints ) - { - float rating = spawnpoint.CalculateFrontlineRating() - spawnpoint.CalculateRating( checkClass, player.GetTeam(), rating, rating > 0 ? rating * 0.25 : rating ) - } + spawnpoint.CalculateRating( checkClass, player.GetTeam(), rating, rating ) } // spawnzones diff --git a/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut index 9f05a0cd..78cfdb27 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut @@ -41,6 +41,9 @@ global function Battery_StopFXAndHideIconForPlayer global function RemovePlayerAirControl //This function should really be in a server only SP & MP utility script file. No such file exists as of right now. global function RestorePlayerAirControl //This function should really be in a server only SP & MP utility script file. No such file exists as of right now. +// needs these +global function Rodeo_TakeBatteryAwayFromPilot + #if DEV global function SetDebugRodeoPrint global function GetDebugRodeoPrint @@ -336,7 +339,7 @@ void function RodeoBatteryRemoval( entity pilot ) if ( !playerHadBattery ) { - AddPlayerScore( pilot, "PilotBatteryStolen" ) + AddPlayerScore( pilot, "PilotBatteryStolen", pilot ) entity battery = Rodeo_CreateBatteryPack( titan ) Rodeo_PilotPicksUpBattery( pilot, battery ) thread BatteryThiefHighlight( pilot ) @@ -1853,7 +1856,7 @@ void function Rodeo_OnTouchBatteryPack_Internal( entity player, entity batteryPa Battery_StopFX( batteryPack ) //Will be turned on again when player loses cloak Rodeo_PilotPicksUpBattery( player, batteryPack ) - AddPlayerScore( player, "PilotBatteryPickup" ) + AddPlayerScore( player, "PilotBatteryPickup", player ) // MessageToPlayer( player, eEventNotifications.Rodeo_PilotPickedUpBattery ) return } @@ -1878,7 +1881,7 @@ void function Rodeo_PilotAddsBatteryToFriendlyTitan( entity rider, entity titan Rodeo_ApplyBatteryToTitan( battery, titan ) //This destroys the battery - AddPlayerScore( rider, "PilotBatteryApplied" ) + AddPlayerScore( rider, "PilotBatteryApplied", rider ) EmitSoundOnEntityOnlyToPlayer( rider, rider, PILOT_APPLIES_BATTERY_TO_TITAN_HEALTH_RESTORED_SOUND ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts.nut b/Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts.nut index d15220e4..7a7498b8 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts.nut @@ -785,7 +785,7 @@ bool function IsSettingPrimeTitanWithoutSetFile( entity player, string loadoutTy bool function SkipItemLockedCheck( entity player, string ref, string parentRef, string loadoutProperty ) //Hack: Skip entitlement related unlock checks for now. Can fail.
{
- if ( DevEverythingUnlocked() )
+ if ( DevEverythingUnlocked( player ) )
return true
//if ( IsItemInEntitlementUnlock( ref ) && IsLobby() ) //TODO: Look into restricting this to lobby only? But entitlement checks can fail randomly...
@@ -2379,10 +2379,8 @@ bool function IsValidPilotLoadoutProperty( string propertyName ) case "weapon3Mod2":
case "weapon3Mod3":
case "ordnance":
- case "special":
case "passive1":
case "passive2":
- case "melee":
case "skinIndex":
case "camoIndex":
case "primarySkinIndex":
@@ -2403,7 +2401,6 @@ bool function IsValidTitanLoadoutProperty( string propertyName ) {
case "name":
case "titanClass":
- case "setFile":
case "primaryMod":
case "special":
case "antirodeo":
@@ -3266,6 +3263,24 @@ string function Loadouts_GetSetFileForRequestedClass( entity player ) return loadout.race
}
+ #if DEV
+ // these are #if DEV'd until they work as their function names describe they should
+ // atm these only exist to allow the #if DEV'd calls to them for bot code in this file to compile on retail
+ // bots don't work in retail at all, so this doesn't matter for us really, but these should be unDEV'd and api'd properly once they are functional
+
+ PilotLoadoutDef function GetRandomPilotLoadout()
+ {
+ PilotLoadoutDef loadout
+ return loadout
+ }
+
+ TitanLoadoutDef function GetRandomTitanLoadout( string setFile )
+ {
+ TitanLoadoutDef loadout
+ return loadout
+ }
+ #endif
+
bool function Loadouts_TryGivePilotLoadout( entity player )
{
if ( !Loadouts_CanGivePilotLoadout( player ) )
@@ -3978,7 +3993,7 @@ bool function IsValidTitanLoadoutIndex( int loadoutIndex ) bool function HasPrimeToMatchExecutionType( entity player, int itemType )
{
- if ( DevEverythingUnlocked() )
+ if ( DevEverythingUnlocked( player ) )
return true
switch( itemType )
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut index b26e48ca..f8597744 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut @@ -1,11 +1,5 @@ globalize_all_functions -// whether the server is a modded, northstar server -bool function IsNorthstarServer() -{ - return GetConVarBool( "ns_is_modded_server" ) -} - // whether the game should return to the lobby on GameRules_EndMatch() bool function ShouldReturnToLobby() { diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_powerup.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_powerup.gnut new file mode 100644 index 00000000..c390b5f5 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_powerup.gnut @@ -0,0 +1,294 @@ +global function SH_PowerUp_Init +global function GetPowerUpFromIndex +global function GetPowerUpFromItemRef + +//Proto Use Functions +global function PowerUp_Func_GiveEPG +global function PowerUp_Func_GiveHELL +global function PowerUp_Func_GiveLSTAR +global function PowerUp_Func_GiveSHOTGUN +global function PowerUp_Func_GiveArmorSmall +global function PowerUp_Func_GiveArmorMedium +global function PowerUp_Func_GiveArmorLarge +global function PowerUp_Func_TitanBuildTime +global function PowerUp_Func_PilotUpgrade +global function PowerUp_Func_GiveTicks + +global struct PowerUp +{ + int index + string name + asset icon + asset model + asset baseModel + string itemRef + vector modelOffset + vector modelAngles + float respawnDelay + vector glowColor + bool titanPickup + int maxInWorld + void functionref( entity ) destroyFunc + bool functionref() spawnFunc +} + +const bool TITAN_PICKUP = true +const bool PILOT_PICKUP = false + +struct +{ + array<PowerUp> powerUps +}file + +const TEST_MODEL = $"models/communication/terminal_com_station.mdl" +const TEST_ICON = $"vgui/HUD/coop/minimap_coop_nuke_titan" + +void function SH_PowerUp_Init() +{ + #if SERVER || CLIENT + PrecacheWeapon( "mp_weapon_epg" ) + PrecacheWeapon( "mp_weapon_arena1" ) + PrecacheWeapon( "mp_weapon_arena2" ) + PrecacheWeapon( "mp_weapon_arena3" ) + PrecacheWeapon( "mp_weapon_lstar" ) + PrecacheWeapon( "mp_weapon_shotgun_doublebarrel" ) + PrecacheWeapon( "mp_weapon_frag_drone" ) + #endif + + file.powerUps.resize( ePowerUps.count ) + CreatePowerUp( ePowerUps.weaponEPG, "mp_weapon_epg", "EPG", 60.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveEPG, <255,0,0>, PILOT_PICKUP, $"vgui/HUD/op_ammo_mini", $"models/weapons/auto_rocket_launcher_ARL/w_ARL.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.weaponHELL, "mp_weapon_arena3", "HELL", 90.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveHELL, <255,0,0>, PILOT_PICKUP, $"vgui/HUD/op_ammo_mini", $"models/weapons/defender/w_defender.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.weaponLSTAR, "mp_weapon_lstar", "LSTAR", 45.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveLSTAR, <255,0,0>, PILOT_PICKUP, $"vgui/HUD/op_ammo_mini", $"models/weapons/lstar/w_lstar.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.weaponSHOTGUN, "mp_weapon_shotgun_doublebarrel", "Shrapnel Shotgun", 30.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveSHOTGUN, <255,0,0>, PILOT_PICKUP, $"vgui/HUD/op_ammo_mini", $"models/weapons/mastiff_stgn/w_mastiff.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.armorSmall, "mp_loot_armor_small", "Armor +5", 30.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveArmorSmall, <0,0,255>, PILOT_PICKUP, $"vgui/HUD/op_health_mini", $"models/gameplay/health_pickup_small.mdl", $"models/containers/plastic_pallet_01.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.armorMedium, "mp_loot_armor_medium", "Armor +25", 60.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveArmorMedium, <0,0,255>, PILOT_PICKUP, $"vgui/HUD/op_health_mini", $"models/gameplay/health_pickup_small.mdl", $"models/containers/plastic_pallet_01.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.armorLarge, "mp_loot_armor_large", "Armor +50", 120.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveArmorLarge, <0,0,255>, PILOT_PICKUP, $"vgui/HUD/op_health_mini", $"models/gameplay/health_pickup_large.mdl", $"models/containers/plastic_pallet_01.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.titanTimeReduction, "mp_loot_titan_build_credit", "Titan Build Time", 20.0, 2, FRAShouldSpawnPowerUp, PowerUp_Func_TitanBuildTime, <0,255,0>, PILOT_PICKUP, $"vgui/HUD/op_drone_mini", $"models/titans/medium/titan_medium_battery_static.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.LTS_TitanTimeReduction, "mp_loot_titan_build_credit_lts", "Titan Build Time", 60.0, 0, LTSShouldSpawnPowerUp, PowerUp_Func_TitanBuildTime, <0,255,0>, PILOT_PICKUP, $"vgui/HUD/op_drone_mini", $"models/titans/medium/titan_medium_battery_static.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.pilotUpgrade, "mp_loot_pilot_upgrade", "Can of Spinach", 120.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_PilotUpgrade, <0,255,0>, PILOT_PICKUP, $"vgui/HUD/op_drone_mini", $"models/humans/pilots/pilot_light_ged_m.mdl", $"models/communication/flag_base.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) + CreatePowerUp( ePowerUps.ticks, "mp_weapon_frag_drone", "Ticks", 60.0, 0, DefaultShouldSpawnPowerUp, PowerUp_Func_GiveTicks, <255,0,0>, PILOT_PICKUP, $"vgui/HUD/op_ammo_mini", $"models/robots/drone_frag/frag_drone_proj.mdl", $"models/robots/drone_frag/frag_drone_proj.mdl", < 0, 0, 32 >, < 0, 0, 0 > ) +} + +bool function FRAShouldSpawnPowerUp() +{ + return GAMETYPE == FREE_AGENCY +} + +bool function LTSShouldSpawnPowerUp() +{ + if ( HasIronRules() ) + return false + + // modified for fw + //return ( GAMETYPE == LAST_TITAN_STANDING || GAMETYPE == LTS_BOMB ) + return ( GAMETYPE == LAST_TITAN_STANDING || GAMETYPE == LTS_BOMB || GAMETYPE == FORT_WAR ) +} + +bool function DefaultShouldSpawnPowerUp() +{ + return GetCurrentPlaylistVarInt( "power_ups_enabled", 0 ) == 1 +} + +void function CreatePowerUp( int enumIndex, string item, string displayName, float respawnTime, int worldLimit, bool functionref() shouldSpawnFunction, void functionref( entity ) destroyFunction, vector color, bool canTitanPickup, asset worldIcon, asset worldModel, asset worldBase, vector worldModelOffset, vector worldModelAngle ) +{ + PowerUp power + power.index = enumIndex + power.name = displayName + power.icon = worldIcon + power.model = worldModel + power.baseModel = worldBase + power.itemRef = item + power.modelOffset = worldModelOffset + power.modelAngles = worldModelAngle + power.respawnDelay = respawnTime + power.destroyFunc = destroyFunction + power.spawnFunc = shouldSpawnFunction + power.glowColor = color + power.titanPickup = canTitanPickup + power.maxInWorld = worldLimit + file.powerUps[enumIndex] = power + + #if CLIENT + PrecacheHUDMaterial( worldIcon ) + #else + PrecacheModel( worldModel ) + PrecacheModel( worldBase ) + #if R1_VGUI_MINIMAP + Minimap_PrecacheMaterial( worldIcon ) + #endif + #endif +} + +PowerUp function GetPowerUpFromIndex( int index ) +{ + return file.powerUps[index] +} + +PowerUp function GetPowerUpFromItemRef( string ref ) +{ + foreach( power in file.powerUps ) + { + if ( power.itemRef == ref ) + return power + } + + Assert( false, "Power Up not found") + unreachable +} + +////////////////////////////////////////////// +// PROTO USE FUNCTIONS - Maybe should be a bunch of new item_ classes with their own healthkit callbacks? +////////////////////////////////////////////// +void function PowerUp_Func_GiveEPG( entity player ) +{ + #if SERVER + if ( player.IsTitan() ) + return + GiveWeaponPowerUp( player, "mp_weapon_arena2" ) + #endif +} + +void function PowerUp_Func_GiveHELL( entity player ) +{ + #if SERVER + if ( player.IsTitan() ) + return + GiveWeaponPowerUp( player, "mp_weapon_arena3" ) + #endif +} + +void function PowerUp_Func_GiveLSTAR( entity player ) +{ + #if SERVER + if ( player.IsTitan() ) + return + GiveWeaponPowerUp( player, "mp_weapon_arena1" ) + #endif +} + +void function PowerUp_Func_GiveSHOTGUN( entity player ) +{ + #if SERVER + if ( player.IsTitan() ) + return + GiveWeaponPowerUp( player, "mp_weapon_shotgun_doublebarrel" ) + #endif +} + +void function PowerUp_Func_GiveTicks( entity player ) +{ + #if SERVER + if ( player.IsTitan() ) + return + player.TakeOffhandWeapon( OFFHAND_ORDNANCE ) + player.GiveOffhandWeapon( "mp_weapon_frag_drone", OFFHAND_ORDNANCE ) + thread RestoreDefaultOffhandWeapon( player ) + #endif +} + +#if SERVER +void function RestoreDefaultOffhandWeapon( entity player ) +{ + player.EndSignal( "OnDeath" ) + player.EndSignal( "OnDestroy" ) + + while( true ) + { + player.WaitSignal( "ThrowGrenade" ) + + if ( player.IsTitan() ) + continue + + entity weapon = player.GetOffhandWeapon( OFFHAND_ORDNANCE ) + if ( weapon.GetWeaponPrimaryClipCount() == 0 ) + { + player.TakeOffhandWeapon( OFFHAND_ORDNANCE ) + int loadoutIndex = GetActivePilotLoadoutIndex( player ) + PilotLoadoutDef loadout = GetPilotLoadoutFromPersistentData( player, loadoutIndex ) + player.GiveOffhandWeapon( loadout.ordnance, OFFHAND_ORDNANCE ) + return + } + } +} + +void function GiveWeaponPowerUp( entity player, string newWeapon ) +{ + array<entity> weapons = player.GetMainWeapons() + string weaponToSwitch = player.GetLatestPrimaryWeapon().GetWeaponClassName() + + if ( player.GetActiveWeapon() != player.GetAntiTitanWeapon() ) + { + foreach ( weapon in weapons ) + { + string weaponClassName = weapon.GetWeaponClassName() + if ( weaponClassName == newWeapon ) + { + weaponToSwitch = weaponClassName + break + } + } + } + + player.TakeWeaponNow( weaponToSwitch ) + player.GiveWeapon( newWeapon ) + player.SetActiveWeaponByName( newWeapon ) +} +#endif + +void function PowerUp_Func_GiveArmorSmall( entity player ) +{ + GiveArmor( player, 5 ) +} + +void function PowerUp_Func_GiveArmorMedium( entity player ) +{ + GiveArmor( player, 25 ) +} + +void function PowerUp_Func_GiveArmorLarge( entity player ) +{ + GiveArmor( player, 50 ) +} + +void function GiveArmor( entity player, int amount ) +{ + #if SERVER + if ( player.IsTitan() ) + return + int currentShieldHealth = player.GetShieldHealth() + int currentMaxShieldHealth = player.GetShieldHealthMax() + player.SetShieldHealth( min( 200, amount + currentShieldHealth ) ) + player.SetShieldHealthMax( min( 200, amount + currentMaxShieldHealth ) ) + #endif +} + +void function PowerUp_Func_TitanBuildTime( entity player ) +{ + #if SERVER + entity battery = Rodeo_CreateBatteryPack() + battery.SetOrigin( player.GetOrigin() ) + #endif +} + + + +void function PowerUp_Func_PilotUpgrade( entity player ) +{ + #if SERVER + if ( player.IsTitan() ) + return + + int loadoutIndex = GetPersistentSpawnLoadoutIndex( player, "pilot" ) + + PilotLoadoutDef loadout = GetPilotLoadoutFromPersistentData( player, loadoutIndex ) + + loadout.primary = "mp_weapon_arena2" + loadout.secondary = "mp_weapon_mgl" + loadout.ordnance = "mp_weapon_grenade_emp" + + UpdateDerivedPilotLoadoutData( loadout ) + + GivePilotLoadout( player, loadout ) + SetActivePilotLoadoutIndex( player, loadoutIndex ) + #endif +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut b/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut new file mode 100644 index 00000000..3297643e --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_progression.nut @@ -0,0 +1,1154 @@ +global function Progression_Init +global function ProgressionEnabledForPlayer +#if CLIENT || UI +global function Progression_SetPreference +global function Progression_GetPreference +global function UpdateCachedLoadouts_Delayed +#endif + +#if SP // literally just stub the global functions and call it a day + +void function Progression_Init() {} +bool function ProgressionEnabledForPlayer( entity player ) { return false } +#if CLIENT || UI +void function Progression_SetPreference( bool enabled ) {} +bool function Progression_GetPreference() { return false } +void function UpdateCachedLoadouts_Delayed() {} +#endif // CLIENT || UI + +#else // MP || UI basically + +// SO FOR SOME GOD DAMN REASON, PUTTING THESE INTO ONE STRUCT +// AND PUTTING THE #if STUFF AROUND THE VARS CAUSES A COMPILE +// ERROR, SO I HAVE TO DO THIS AWFULNESS + +#if SERVER +struct { + table<entity, bool> progressionEnabled +} file +#else // UI || CLIENT +struct { + bool isUpdatingCachedLoadouts = false +} file +#endif + + +void function Progression_Init() +{ + #if SERVER + AddCallback_OnClientDisconnected( OnClientDisconnected ) + AddClientCommandCallback( "ns_progression", ClientCommand_SetProgression ) + AddClientCommandCallback( "ns_resettitanaegis", ClientCommand_ResetTitanAegis ) + AddCallback_GameStateEnter( eGameState.Playing, OnPlaying ) + #elseif CLIENT + AddCallback_OnClientScriptInit( OnClientScriptInit ) + #endif +} + +bool function ProgressionEnabledForPlayer( entity player ) +{ + #if SERVER + if ( player in file.progressionEnabled ) + return file.progressionEnabled[player] + + return false + #else // CLIENT || UI + return GetConVarBool( "ns_progression_enabled" ) + #endif +} + +#if SERVER +void function OnPlaying() +{ + SetUIVar( level, "penalizeDisconnect", false ) // dont show the "you will lose merits thing" +} + +void function OnClientDisconnected( entity player ) +{ + // cleanup table when player leaves + if ( player in file.progressionEnabled ) + delete file.progressionEnabled[player] +} + +bool function ClientCommand_SetProgression( entity player, array<string> args ) +{ + if ( args.len() != 1 ) + return false + if ( args[0] != "0" && args[0] != "1" ) + return false + + file.progressionEnabled[player] <- args[0] == "1" + + // loadout validation when progression is turned on + if ( file.progressionEnabled[player] ) + ValidateEquippedItems( player ) + + return true +} + +/// Resets a specific Titan's Aegis rank back to `0` +/// * `player` - The player entity to perform the action on +/// * `args` - The arguments passed from the client command. `args[0]` should be a string corresponding to the chassis name of the Titan to reset. +/// Valid chassis are: ion, tone, vanguard, northstar, ronin, legion, and scorch. +/// +/// Returns `true` on success and `false` on missing args. +bool function ClientCommand_ResetTitanAegis( entity player, array<string> args ) +{ + if ( !args.len() ) + return false + + string titanRef = args[0].tolower() + if( !PersistenceEnumValueIsValid( "titanClasses", titanRef ) ) + return false + + int suitIndex = PersistenceGetEnumIndexForItemName( "titanClasses", titanRef ) + + player.SetPersistentVar( "titanFDUnlockPoints[" + suitIndex + "]", 0 ) + player.SetPersistentVar( "previousFDUnlockPoints[" + suitIndex + "]", 0 ) + player.SetPersistentVar( "fdTitanXP[" + suitIndex + "]", 0 ) + player.SetPersistentVar( "fdPreviousTitanXP[" + suitIndex + "]", 0 ) + + // Refresh Highest Aegis Titan since we might get all of them back to 1 if players wants + RecalculateHighestTitanFDLevel( player ) + + return true +} +#endif + +#if CLIENT +void function OnClientScriptInit( entity player ) +{ + // unsure if this is needed, just being safe + if ( player != GetLocalClientPlayer() ) + return + + Progression_SetPreference( GetConVarBool( "ns_progression_enabled" ) ) + UpdateCachedLoadouts_Delayed() +} +#endif + +#if CLIENT || UI +void function Progression_SetPreference( bool enabled ) +{ + SetConVarBool( "ns_progression_enabled", enabled ) + + #if CLIENT + GetLocalClientPlayer().ClientCommand( "ns_progression " + enabled.tointeger() ) + #else // UI + ClientCommand( "ns_progression " + enabled.tointeger() ) + #endif +} + +bool function Progression_GetPreference() +{ + return GetConVarBool( "ns_progression_enabled" ) +} + +void function UpdateCachedLoadouts_Delayed() +{ + if ( file.isUpdatingCachedLoadouts ) + return + + file.isUpdatingCachedLoadouts = true + + #if UI + RunClientScript( "UpdateCachedLoadouts_Delayed" ) // keep client and UI synced + #else // CLIENT + RunUIScript( "UpdateCachedLoadouts_Delayed" ) // keep client and UI synced + #endif + + thread UpdateCachedLoadouts_Threaded() +} + +void function UpdateCachedLoadouts_Threaded() +{ + wait 1.0 // give the server time to network our new persistence + + UpdateCachedLoadouts() + + // below here is just making all the menu models update properly and such + + #if UI + uiGlobal.pilotSpawnLoadoutIndex = GetPersistentSpawnLoadoutIndex( GetUIPlayer(), "pilot" ) + uiGlobal.titanSpawnLoadoutIndex = GetPersistentSpawnLoadoutIndex( GetUIPlayer(), "titan" ) + #endif + + #if CLIENT + entity player = GetLocalClientPlayer() + ClearAllTitanPreview( player ) + ClearAllPilotPreview( player ) + UpdateTitanModel( player, GetPersistentSpawnLoadoutIndex( player, "titan" ) ) + UpdatePilotModel( player, GetPersistentSpawnLoadoutIndex( player, "pilot" ) ) + #endif + + file.isUpdatingCachedLoadouts = false +} +#endif + +#if SERVER +void function ValidateEquippedItems( entity player ) +{ + printt( "VALIDATING EQUIPPED ITEMS FOR PLAYER: " + player.GetPlayerName() ) + + // banner + CallingCard card = PlayerCallingCard_GetActive( player ) + if ( IsItemLocked( player, card.ref ) ) + { + printt( "- BANNER CARD IS LOCKED, RESETTING" ) + PlayerCallingCard_SetActiveByRef( player, "callsign_16_col" ) // copied from _persistentdata.gnut + } + + // patch + CallsignIcon icon = PlayerCallsignIcon_GetActive( player ) + if ( IsItemLocked( player, icon.ref ) ) + { + printt( "- BANNER PATCH IS LOCKED, RESETTING" ) + PlayerCallsignIcon_SetActiveByRef( player, "gc_icon_titanfall" ) // copied from _persistentdata.gnut + } + + // faction + int factionIndex = player.GetPersistentVarAsInt( "factionChoice" ) + string factionRef = PersistenceGetEnumItemNameForIndex( "faction", factionIndex ) + if ( IsItemLocked( player, factionRef ) ) + { + printt( "- FACTION IS LOCKED, RESETTING" ) + player.SetPersistentVar( "factionChoice", "faction_marauder" ) // im so sorry that i am setting you to use sarah, you don't deserve this + } + + // boost + BurnReward reward = BurnReward_GetById( player.GetPersistentVarAsInt( "burnmeterSlot" ) ) + if ( IsItemLocked( player, reward.ref ) ) + { + printt( "- BOOST IS LOCKED, RESETTING" ) + player.SetPersistentVar( "burnmeterSlot", BurnReward_GetByRef( "burnmeter_amped_weapons" ).id ) + } + + // titan loadouts + int selectedTitanLoadoutIndex = player.GetPersistentVarAsInt( "titanSpawnLoadout.index" ) + for ( int titanLoadoutIndex = 0; titanLoadoutIndex < NUM_PERSISTENT_TITAN_LOADOUTS; titanLoadoutIndex++ ) + { + printt( "- VALIDATING TITAN LOADOUT: " + titanLoadoutIndex ) + + bool isSelected = titanLoadoutIndex == selectedTitanLoadoutIndex + TitanLoadoutDef loadout = GetTitanLoadout( player, titanLoadoutIndex ) + TitanLoadoutDef defaultLoadout = shGlobal.defaultTitanLoadouts[titanLoadoutIndex] + + printt( " - CHASSIS: " + loadout.titanClass ) + + // passive1 - "Titan Kit" (things like overcore) + if ( loadout.passive1 != defaultLoadout.passive1 && IsSubItemLocked( player, loadout.passive1, loadout.titanClass ) ) + { + printt( " - TITAN KIT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].passive1", defaultLoadout.passive1 ) + } + + // passive2 - "<chassis> Kit" (things like zero point tripwire) + if ( loadout.passive2 != defaultLoadout.passive2 && IsSubItemLocked( player, loadout.passive2, loadout.titanClass ) ) + { + printt( " - CHASSIS KIT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].passive2", defaultLoadout.passive2 ) + } + + // passive3 - "Titanfall Kit" (warpfall/dome shield) + if ( loadout.passive3 != defaultLoadout.passive3 && IsSubItemLocked( player, loadout.passive3, loadout.titanClass ) ) + { + printt( " - TITANFALL KIT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].passive3", defaultLoadout.passive3 ) + } + + // passive4 - monarch core 1 + if ( loadout.passive4 != defaultLoadout.passive4 && IsSubItemLocked( player, loadout.passive4, loadout.titanClass ) ) + { + printt( " - MONARCH CORE 1 KIT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].passive4", defaultLoadout.passive4 ) + } + + // passive5 - monarch core 2 + if ( loadout.passive5 != defaultLoadout.passive5 && IsSubItemLocked( player, loadout.passive5, loadout.titanClass ) ) + { + printt( " - MONARCH CORE 2 KIT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].passive5", defaultLoadout.passive5 ) + } + + // passive6 - monarch core 3 + if ( loadout.passive6 != defaultLoadout.passive6 && IsSubItemLocked( player, loadout.passive6, loadout.titanClass ) ) + { + printt( " - MONARCH CORE 3 KIT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].passive6", defaultLoadout.passive6 ) + } + + // titanExecution + if ( !IsRefValid( loadout.titanExecution ) || !IsValidTitanExecution( titanLoadoutIndex, "titanExecution", "", loadout.titanExecution ) ) + { + printt( " - TITAN EXECUTION IS INVALID FOR CHASSIS, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].titanExecution", defaultLoadout.titanExecution ) + } + else if ( IsItemLocked( player, loadout.titanExecution ) ) + { + printt( " - TITAN EXECUTION EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].titanExecution", defaultLoadout.titanExecution ) + } + else if ( GetItemData( loadout.titanExecution ).reqPrime && IsItemLocked( player, loadout.primeTitanRef ) ) + { + printt( " - PRIME TITAN EXECUTION EQUIPPED WHEN PRIME TITAN IS LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].titanExecution", defaultLoadout.titanExecution ) + } + + // skinIndex + // camoIndex + if ( loadout.skinIndex == TITAN_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN_TITAN ) + if ( loadout.camoIndex >= camoSkins.len() || loadout.camoIndex < 0 ) + { + printt( " - INVALID TITAN CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.camoIndex] + if ( IsSubItemLocked( player, camoSkin.ref, loadout.titanClass ) ) + { + printt( " - TITAN CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + } + } + else if ( loadout.skinIndex == 0 ) + { + if ( loadout.camoIndex != 0 ) + { + printt( " - INVALID TITAN CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + } + else + { + string ref = GetSkinRefFromTitanClassAndPersistenceValue( loadout.titanClass, loadout.skinIndex ) + if ( ref == INVALID_REF ) + { + printt( " - INVALID TITAN WARPAINT, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + else if ( IsSubItemLocked( player, ref, loadout.titanClass ) ) + { + printt( " - TITAN WARPAINT EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + } + + // decalIndex + string noseArtRef = GetNoseArtRefFromTitanClassAndPersistenceValue( loadout.titanClass, loadout.decalIndex ) + if ( loadout.decalIndex != defaultLoadout.decalIndex && IsSubItemLocked( player, noseArtRef, loadout.titanClass ) ) + { + printt( " - NOSE ART EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].decalIndex", defaultLoadout.decalIndex ) + } + + // primarySkinIndex + // primaryCamoIndex + if ( loadout.primarySkinIndex == WEAPON_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN ) + if ( loadout.primaryCamoIndex >= camoSkins.len() || loadout.primaryCamoIndex < 0 ) + { + printt( " - INVALID WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.primaryCamoIndex] + if ( IsSubItemLocked( player, camoSkin.ref, loadout.titanClass ) ) + { + printt( " - WEAPON CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + } + } + else if ( loadout.primarySkinIndex == 0 && loadout.primaryCamoIndex != 0 ) + { + // titan weapons do not have skins, if we ever do add them lots of stuff will + //need a refactor outside of here so with that being said, i cannot be bothered + printt( " - INVALID WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + + + // isPrime + if ( loadout.isPrime == "titan_is_prime" && IsItemLocked( player, loadout.primeTitanRef ) ) + { + printt( " - PRIME TITAN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].isPrime", defaultLoadout.isPrime ) + } + + // primeSkinIndex + // primeCamoIndex + if ( loadout.primeSkinIndex == TITAN_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN_TITAN ) + if ( loadout.primeCamoIndex >= camoSkins.len() || loadout.primeCamoIndex < 0 ) + { + printt( " - INVALID TITAN CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeSkinIndex", defaultLoadout.primeSkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeCamoIndex", defaultLoadout.primeCamoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.primeCamoIndex] + if ( IsSubItemLocked( player, camoSkin.ref, loadout.titanClass ) ) + { + printt( " - TITAN CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeSkinIndex", defaultLoadout.primeSkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeCamoIndex", defaultLoadout.primeCamoIndex ) + } + } + } + else if ( loadout.primeSkinIndex == 0 ) + { + if ( loadout.primeCamoIndex != 0 ) + { + printt( " - INVALID TITAN CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeSkinIndex", defaultLoadout.primeSkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeCamoIndex", defaultLoadout.primeCamoIndex ) + } + } + else + { + printt( " - INVALID PRIME TITAN SKIN, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeSkinIndex", defaultLoadout.primeSkinIndex ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeCamoIndex", defaultLoadout.primeCamoIndex ) + } + + // primeDecalIndex + string primeNoseArtRef = GetNoseArtRefFromTitanClassAndPersistenceValue( loadout.titanClass, loadout.primeDecalIndex ) + if ( loadout.primeDecalIndex != defaultLoadout.primeDecalIndex && IsSubItemLocked( player, primeNoseArtRef, loadout.titanClass ) ) + { + printt( " - PRIME NOSE ART EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].primeDecalIndex", defaultLoadout.primeDecalIndex ) + } + + // showArmBadge - equipped and shouldnt be able to + if ( loadout.showArmBadge && !CanEquipArmBadge( player, loadout.titanClass ) ) + { + printt( " - ARM BADGE EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "titanLoadouts[" + titanLoadoutIndex + "].showArmBadge", defaultLoadout.showArmBadge ) + } + + // equipped titan loadout - equipped titan class is locked + if ( isSelected && IsItemLocked( player, loadout.titanClass ) ) + { + printt( " - SELECTED TITAN CLASS IS LOCKED, RESETTING" ) + player.SetPersistentVar( "titanSpawnLoadout.index", 0 ) + selectedTitanLoadoutIndex = 0 + } + } + + if ( selectedTitanLoadoutIndex < 0 || selectedTitanLoadoutIndex >= NUM_PERSISTENT_TITAN_LOADOUTS ) + { + printt( "- SELECTED TITAN CLASS IS INVALID, RESETTING" ) + player.SetPersistentVar( "titanSpawnLoadout.index", 0 ) + selectedTitanLoadoutIndex = 0 + } + + Remote_CallFunction_NonReplay( player, "ServerCallback_UpdateTitanModel", selectedTitanLoadoutIndex ) + + // pilot loadouts + for ( int pilotLoadoutIndex = 0; pilotLoadoutIndex < NUM_PERSISTENT_PILOT_LOADOUTS; pilotLoadoutIndex++ ) + { + printt( "- VALIDATING PILOT LOADOUT: " + pilotLoadoutIndex ) + + bool isSelected = pilotLoadoutIndex == player.GetPersistentVarAsInt( "pilotSpawnLoadout.index" ) + PilotLoadoutDef loadout = GetPilotLoadout( player, pilotLoadoutIndex ) + PilotLoadoutDef defaultLoadout = shGlobal.defaultPilotLoadouts[pilotLoadoutIndex] + + // note: for readability, I have added {} around the different items, + // so that you can collapse them in visual studio code (and other good IDEs) + + // tactical + { + if ( !IsRefValid( loadout.suit ) ) + { + printt( " - TACTICAL IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].suit", defaultLoadout.suit ) + } + else if ( IsItemLocked( player, loadout.suit ) ) + { + printt( " - TACTICAL IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].suit", defaultLoadout.suit ) + } + } + + // ordnance + { + if ( !IsRefValid( loadout.ordnance ) ) + { + printt( " - ORDNANCE IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].ordnance", defaultLoadout.ordnance ) + } + else if ( IsItemLocked( player, loadout.ordnance ) ) + { + printt( " - ORDNANCE IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].ordnance", defaultLoadout.ordnance ) + } + } + + // race ( gender ) + { + if ( !IsRefValid( loadout.race ) ) + { + printt( " - GENDER IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].race", defaultLoadout.race ) + } + else if ( IsItemLocked( player, loadout.race ) ) + { + printt( " - GENDER IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].race", defaultLoadout.race ) + } + } + + // camoIndex + // skinIndex + { + if ( loadout.skinIndex == PILOT_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN_PILOT ) + if ( loadout.camoIndex >= camoSkins.len() || loadout.camoIndex < 0 ) + { + printt( " - INVALID PILOT CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.camoIndex] + if ( IsItemLocked( player, camoSkin.ref ) ) + { + printt( " - PILOT CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + } + } + else if ( loadout.skinIndex == 0 ) + { + if ( loadout.camoIndex != 0 ) + { + printt( " - INVALID PILOT CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + } + else + { + // pilots can't have skins other than 0 and 1 right? + printt( " - INVALID PILOT SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].skinIndex", defaultLoadout.skinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].camoIndex", defaultLoadout.camoIndex ) + } + } + + // primary weapon + { + if ( !IsRefValid( loadout.primary ) || GetItemType( loadout.primary ) != eItemTypes.PILOT_PRIMARY ) + { + printt( " - PRIMARY WEAPON IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primary", defaultLoadout.primary ) + } + else if ( IsItemLocked( player, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primary", defaultLoadout.primary ) + } + } + + // primary weapon mods + { + // mod1 + if ( loadout.primaryMod1 == "" ) + { + // do nothing + } + else if ( !HasSubitem( loadout.primary, loadout.primaryMod1 ) ) + { + printt( " - PRIMARY WEAPON MOD 1 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod1", defaultLoadout.primaryMod1 ) + } + else if ( IsSubItemLocked( player, loadout.primaryMod1, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON MOD 1 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod1", defaultLoadout.primaryMod1 ) + } + // mod2 + if ( loadout.primaryMod2 == "" ) + { + // do nothing + } + else if ( IsSubItemLocked( player, "primarymod2", loadout.primary ) ) + { + printt( " - PRIMARY WEAPON MOD 2 SLOT IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod2", defaultLoadout.primaryMod2 ) + } + else if ( !HasSubitem( loadout.primary, loadout.primaryMod2 ) ) + { + printt( " - PRIMARY WEAPON MOD 2 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod2", defaultLoadout.primaryMod2 ) + } + else if ( IsSubItemLocked( player, loadout.primaryMod2, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON MOD 2 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod2", defaultLoadout.primaryMod2 ) + } + else if ( loadout.primaryMod2 == loadout.primaryMod1 && loadout.primaryMod2 != "" ) + { + printt( " - PRIMARY WEAPON MOD 2 IS DUPLICATE, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod2", defaultLoadout.primaryMod2 ) + } + else if ( loadout.primaryAttachment == "threat_scope" ) + { + printt( " - PRIMARY WEAPON MOD 2 IS SET WITH THREAT SCOPE, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod2", defaultLoadout.primaryMod2 ) + } + // attachment + if ( loadout.primaryAttachment == "" ) + { + // do nothing + } + else if ( !HasSubitem( loadout.primary, loadout.primaryAttachment ) ) + { + printt( " - PRIMARY WEAPON ATTACHMENT IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryAttachment", defaultLoadout.primaryAttachment ) + } + else if ( IsSubItemLocked( player, loadout.primaryAttachment, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON ATTACHMENT IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryAttachment", defaultLoadout.primaryAttachment ) + } + // mod3 (pro screen) + if ( loadout.primaryMod3 == "" ) + { + // do nothing + } + else if ( loadout.primaryMod3 == "pro_screen" ) + { + // fuck you and your three mod slot stuff + printt( " - PRIMARY WEAPON PRO SCREEN IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod3", defaultLoadout.primaryMod3 ) + } + else if ( IsSubItemLocked( player, loadout.primaryMod3, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON PRO SCREEN IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryMod3", defaultLoadout.primaryMod3 ) + } + } + + // primary weapon camoIndex + // primary weapon skinIndex + { + if ( loadout.primarySkinIndex == WEAPON_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN ) + if ( loadout.primaryCamoIndex >= camoSkins.len() || loadout.primaryCamoIndex < 0 ) + { + printt( " - INVALID PRIMARY WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.primaryCamoIndex] + if ( IsSubItemLocked( player, camoSkin.ref, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + } + } + else if ( loadout.primarySkinIndex == 0 ) + { + if ( loadout.primaryCamoIndex != 0 ) + { + printt( " - INVALID PRIMARY WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + } + else + { + string warpaintRef = GetWeaponWarpaintRefByIndex( loadout.primarySkinIndex, loadout.primary ) + if ( warpaintRef == INVALID_REF || IsSubItemLocked( player, warpaintRef, loadout.primary ) ) + { + printt( " - PRIMARY WEAPON SKIN LOCKED/INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primarySkinIndex", defaultLoadout.primarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].primaryCamoIndex", defaultLoadout.primaryCamoIndex ) + } + } + } + + // secondary weapon + { + if ( !IsRefValid( loadout.secondary ) || GetItemType( loadout.secondary ) != eItemTypes.PILOT_SECONDARY ) + { + printt( " - SECONDARY WEAPON IS LOCKED, RESETTING" ) + string ref = defaultLoadout.secondary + if ( loadout.secondary == ref ) // item dupes swap + { + ref = defaultLoadout.weapon3 + } + else if ( ItemsInSameMenuCategory( loadout.secondary, ref ) ) // category dupes assign value to other slot and swap + { + ref = defaultLoadout.weapon3 + } + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondary", ref ) + } + else if ( IsItemLocked( player, loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON IS LOCKED, RESETTING" ) + string ref = defaultLoadout.secondary + if ( loadout.weapon3 == ref ) // item dupes swap + { + ref = defaultLoadout.weapon3 + } + else if ( ItemsInSameMenuCategory( loadout.weapon3, ref ) ) // category dupes assign value to other slot and swap + { + ref = defaultLoadout.weapon3 + } + + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondary", ref ) + } + } + + // secondary weapon mods + { + // mod1 + if ( loadout.secondaryMod1 == "" ) + { + // do nothing + } + else if ( !HasSubitem( loadout.secondary, loadout.secondaryMod1 ) ) + { + printt( " - SECONDARY WEAPON MOD 1 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod1", defaultLoadout.secondaryMod1 ) + } + else if ( IsSubItemLocked( player, loadout.secondaryMod1, loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON MOD 1 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod1", defaultLoadout.secondaryMod1 ) + } + // mod2 + if ( loadout.secondaryMod2 == "" ) + { + // do nothing + } + else if ( IsSubItemLocked( player, "secondarymod2", loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON MOD 2 SLOT IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod2", defaultLoadout.secondaryMod2 ) + } + else if ( !HasSubitem( loadout.secondary, loadout.secondaryMod2 ) ) + { + printt( " - SECONDARY WEAPON MOD 2 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod2", defaultLoadout.secondaryMod2 ) + } + else if ( IsSubItemLocked( player, loadout.secondaryMod2, loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON MOD 2 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod2", defaultLoadout.secondaryMod2 ) + } + else if ( loadout.secondaryMod2 == loadout.secondaryMod1 && loadout.secondaryMod2 != "" ) + { + printt( " - SECONDARY WEAPON MOD 2 IS DUPLICATE, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod2", defaultLoadout.secondaryMod2 ) + } + // mod3 (pro screen) + if ( loadout.secondaryMod3 == "" ) + { + // do nothing + } + else if ( loadout.secondaryMod3 == "pro_screen" ) + { + // fuck you and your three mod slot stuff + printt( " - SECONDARY WEAPON PRO SCREEN IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod3", defaultLoadout.secondaryMod3 ) + } + else if ( IsSubItemLocked( player, "secondarymod3", loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON PRO SCREEN IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryMod3", defaultLoadout.secondaryMod3 ) + } + } + + // secondary weapon camoIndex + // secondary weapon skinIndex + { + if ( loadout.secondarySkinIndex == WEAPON_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN ) + if ( loadout.secondaryCamoIndex >= camoSkins.len() || loadout.secondaryCamoIndex < 0 ) + { + printt( " - INVALID SECONDARY WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondarySkinIndex", defaultLoadout.secondarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryCamoIndex", defaultLoadout.secondaryCamoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.secondaryCamoIndex] + if ( IsSubItemLocked( player, camoSkin.ref, loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondarySkinIndex", defaultLoadout.secondarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryCamoIndex", defaultLoadout.secondaryCamoIndex ) + } + } + } + else if ( loadout.secondarySkinIndex == 0 ) + { + if ( loadout.secondaryCamoIndex != 0 ) + { + printt( " - INVALID SECONDARY WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondarySkinIndex", defaultLoadout.secondarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryCamoIndex", defaultLoadout.secondaryCamoIndex ) + } + } + else + { + string warpaintRef = GetWeaponWarpaintRefByIndex( loadout.secondarySkinIndex, loadout.secondary ) + if ( warpaintRef == INVALID_REF || IsSubItemLocked( player, warpaintRef, loadout.secondary ) ) + { + printt( " - SECONDARY WEAPON SKIN LOCKED/INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondarySkinIndex", defaultLoadout.secondarySkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].secondaryCamoIndex", defaultLoadout.secondaryCamoIndex ) + } + } + } + + // weapon3 + // note: these are always eItemTypes.PILOT_SECONDARY + { + if ( !IsRefValid( loadout.weapon3 ) || GetItemType( loadout.weapon3 ) != eItemTypes.PILOT_SECONDARY ) + { + printt( " - WEAPON3 WEAPON IS LOCKED, RESETTING" ) + string ref = defaultLoadout.weapon3 + if ( loadout.weapon3 == ref ) // item dupes swap + { + ref = defaultLoadout.secondary + } + else if ( ItemsInSameMenuCategory( loadout.weapon3, ref ) ) // category dupes assign value to other slot and swap + { + ref = defaultLoadout.secondary + } + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3", ref ) + } + else if ( IsItemLocked( player, loadout.weapon3 ) ) + { + printt( " - TERTIARY WEAPON IS LOCKED, RESETTING" ) + string ref = defaultLoadout.weapon3 + if ( loadout.secondary == ref ) // item dupes swap + { + ref = defaultLoadout.secondary + } + else if ( ItemsInSameMenuCategory( loadout.secondary, ref ) ) // category dupes assign value to other slot and swap + { + ref = defaultLoadout.secondary + } + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3", ref ) + } + } + + // weapon3 mods + { + // mod1 + if ( loadout.weapon3Mod1 == "" ) + { + // do nothing + } + else if ( !HasSubitem( loadout.weapon3, loadout.weapon3Mod1 ) ) + { + printt( " - WEAPON3 MOD 1 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod1", defaultLoadout.weapon3Mod1 ) + } + else if ( IsSubItemLocked( player, loadout.weapon3Mod1, loadout.weapon3 ) ) + { + printt( " - WEAPON3 MOD 1 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod1", defaultLoadout.weapon3Mod1 ) + } + // mod2 + if ( loadout.weapon3Mod2 == "" ) + { + // do nothing + } + else if ( IsSubItemLocked( player, "secondarymod2", loadout.weapon3 ) ) + { + printt( " - WEAPON3 MOD 2 SLOT IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod2", defaultLoadout.weapon3Mod2 ) + } + else if ( !HasSubitem( loadout.weapon3, loadout.weapon3Mod2 ) ) + { + printt( " - WEAPON3 MOD 2 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod2", defaultLoadout.weapon3Mod2 ) + } + else if ( IsSubItemLocked( player, loadout.weapon3Mod2, loadout.weapon3 ) ) + { + printt( " - WEAPON3 MOD 2 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod2", defaultLoadout.weapon3Mod2 ) + } + else if ( loadout.weapon3Mod2 == loadout.weapon3Mod1 && loadout.weapon3Mod2 != "" ) + { + printt( " - WEAPON3 MOD 2 IS DUPLICATE, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod2", defaultLoadout.weapon3Mod2 ) + } + // mod3 (pro screen) + if ( loadout.weapon3Mod3 == "" ) + { + // do nothing + } + else if ( loadout.weapon3Mod3 != "pro_screen" ) + { + // fuck you and your three mod slot stuff + printt( " - WEAPON3 PRO SCREEN IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod3", defaultLoadout.weapon3Mod3 ) + } + else if ( IsSubItemLocked( player, "secondarymod3", loadout.weapon3 ) ) + { + printt( " - WEAPON3 PRO SCREEN IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3Mod3", defaultLoadout.weapon3Mod3 ) + } + } + + // weapon3 camoIndex + // weapon3 skinIndex + { + if ( loadout.weapon3SkinIndex == WEAPON_SKIN_INDEX_CAMO ) + { + array<ItemData> camoSkins = GetAllItemsOfType( eItemTypes.CAMO_SKIN ) + if ( loadout.weapon3CamoIndex >= camoSkins.len() || loadout.weapon3CamoIndex < 0 ) + { + printt( " - INVALID TERTIARY WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3SkinIndex", defaultLoadout.weapon3SkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3CamoIndex", defaultLoadout.weapon3CamoIndex ) + } + else + { + ItemData camoSkin = camoSkins[loadout.weapon3CamoIndex] + if ( IsSubItemLocked( player, camoSkin.ref, loadout.weapon3 ) ) + { + printt( " - TERTIARY WEAPON CAMO/SKIN EQUIPPED WHEN LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3SkinIndex", defaultLoadout.weapon3SkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3CamoIndex", defaultLoadout.weapon3CamoIndex ) + } + } + } + else if ( loadout.weapon3SkinIndex == 0 ) + { + if ( loadout.weapon3CamoIndex != 0 ) + { + printt( " - INVALID TERTIARY WEAPON CAMO/SKIN, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3SkinIndex", defaultLoadout.weapon3SkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3CamoIndex", defaultLoadout.weapon3CamoIndex ) + } + } + else + { + string warpaintRef = GetWeaponWarpaintRefByIndex( loadout.weapon3SkinIndex, loadout.weapon3 ) + if ( warpaintRef == INVALID_REF || IsSubItemLocked( player, warpaintRef, loadout.weapon3 ) ) + { + printt( " - TERTIARY WEAPON SKIN LOCKED/INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3SkinIndex", defaultLoadout.weapon3SkinIndex ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].weapon3CamoIndex", defaultLoadout.weapon3CamoIndex ) + } + } + } + + // kit 1 + { + if ( !IsRefValid( loadout.passive1 ) || GetItemType( loadout.passive1 ) != eItemTypes.PILOT_PASSIVE1 ) + { + printt( " - KIT 1 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].passive1", defaultLoadout.passive1 ) + } + else if ( IsItemLocked( player, loadout.passive1 ) ) + { + printt( " - KIT 1 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].passive1", defaultLoadout.passive1 ) + } + } + + // kit 2 + { + if ( !IsRefValid( loadout.passive2 ) || GetItemType( loadout.passive2 ) != eItemTypes.PILOT_PASSIVE2 ) + { + printt( " - KIT 2 IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].passive2", defaultLoadout.passive2 ) + } + else if ( IsItemLocked( player, loadout.passive2 ) ) + { + printt( " - KIT 2 IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].passive2", defaultLoadout.passive2 ) + } + } + + // execution + // note: not sure why defaultLoadout has this set to "", but neck snap should be default + { + if ( !IsRefValid( loadout.execution ) || GetItemType( loadout.execution ) != eItemTypes.PILOT_EXECUTION ) + { + printt( " - EXECUTION IS INVALID, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].execution", "execution_neck_snap" ) + } + else if ( IsItemLocked( player, loadout.execution ) ) + { + printt( " - EXECUTION IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotLoadouts[" + pilotLoadoutIndex + "].execution", "execution_neck_snap" ) + } + } + + // equipped pilot loadout + { + if ( isSelected && IsItemLocked( player, "pilot_loadout_" + ( pilotLoadoutIndex + 1 ) ) ) + { + printt( " - SELECTED PILOT LOADOUT IS LOCKED, RESETTING" ) + player.SetPersistentVar( "pilotSpawnLoadout.index", 0 ) + Remote_CallFunction_NonReplay( player, "ServerCallback_UpdatePilotModel", 0 ) + } + } + } + + Remote_CallFunction_NonReplay( player, "ServerCallback_UpdatePilotModel", player.GetPersistentVarAsInt( "pilotSpawnLoadout.index" ) ) + + printt( "ITEM VALIDATION COMPLETE FOR PLAYER: " + player.GetPlayerName() ) +} + +// basically just PopulateTitanLoadoutFromPersistentData but without validation, we are doing the validation in a better way +// that doesnt just kick the player and reset the entire loadout, since we want to only reset parts of the loadout that we need +TitanLoadoutDef function GetTitanLoadout( entity player, int loadoutIndex ) +{ + TitanLoadoutDef loadout + + loadout.name = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "name" ) + loadout.titanClass = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "titanClass" ) + loadout.primaryMod = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "primaryMod" ) + loadout.special = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "special" ) + loadout.antirodeo = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "antirodeo" ) + loadout.passive1 = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "passive1" ) + loadout.passive2 = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "passive2" ) + loadout.passive3 = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "passive3" ) + loadout.passive4 = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "passive4" ) + loadout.passive5 = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "passive5" ) + loadout.passive6 = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "passive6" ) + loadout.camoIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "camoIndex" ) + loadout.skinIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "skinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + loadout.decalIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "decalIndex" ) + loadout.primaryCamoIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "primaryCamoIndex" ) + loadout.primarySkinIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "primarySkinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + loadout.titanExecution = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "titanExecution" ) + loadout.showArmBadge = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "showArmBadge" ) + + //Prime Titan related vars + loadout.isPrime = GetPersistentLoadoutValue( player, "titan", loadoutIndex, "isPrime" ) + loadout.primeCamoIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "primeCamoIndex" ) + loadout.primeSkinIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "primeSkinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + loadout.primeDecalIndex = GetPersistentLoadoutValueInt( player, "titan", loadoutIndex, "primeDecalIndex" ) + + UpdateDerivedTitanLoadoutData( loadout ) + OverwriteLoadoutWithDefaultsForSetFile( loadout ) + + return loadout +} + +// basically just PopulatePilotLoadoutFromPersistentData but without validation, we are doing the validation in a better way +// that doesnt just kick the player and reset the entire loadout, since we want to only reset parts of the loadout that we need +PilotLoadoutDef function GetPilotLoadout( entity player, int loadoutIndex ) +{ + PilotLoadoutDef loadout + + loadout.name = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "name" ) + loadout.suit = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "suit" ) + loadout.race = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "race" ) + loadout.execution = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "execution" ) + loadout.primary = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "primary" ) + loadout.primaryAttachment = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "primaryAttachment" ) + loadout.primaryMod1 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "primaryMod1" ) + loadout.primaryMod2 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "primaryMod2" ) + loadout.primaryMod3 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "primaryMod3" ) + loadout.secondary = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "secondary" ) + loadout.secondaryMod1 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "secondaryMod1" ) + loadout.secondaryMod2 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "secondaryMod2" ) + loadout.secondaryMod3 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "secondaryMod3" ) + loadout.weapon3 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "weapon3" ) + loadout.weapon3Mod1 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "weapon3Mod1" ) + loadout.weapon3Mod2 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "weapon3Mod2" ) + loadout.weapon3Mod3 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "weapon3Mod3" ) + loadout.ordnance = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "ordnance" ) + loadout.passive1 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "passive1" ) + loadout.passive2 = GetPersistentLoadoutValue( player, "pilot", loadoutIndex, "passive2" ) + loadout.camoIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "camoIndex" ) + loadout.skinIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "skinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + loadout.primaryCamoIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "primaryCamoIndex" ) + loadout.primarySkinIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "primarySkinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + loadout.secondaryCamoIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "secondaryCamoIndex" ) + loadout.secondarySkinIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "secondarySkinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + loadout.weapon3CamoIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "weapon3CamoIndex" ) + loadout.weapon3SkinIndex = GetPersistentLoadoutValueInt( player, "pilot", loadoutIndex, "weapon3SkinIndex" ) //Important: Skin index needs to be gotten after camoIndex for loadout validation purposes + + UpdateDerivedPilotLoadoutData( loadout ) + + return loadout +} + +bool function CanEquipArmBadge( entity player, string titanClass ) +{ + string skinRef + switch ( titanClass ) + { + case "ion": + skinRef = "ion_skin_fd" + break + case "scorch": + skinRef = "scorch_skin_fd" + break + case "northstar": + skinRef = "northstar_skin_fd" + break + case "ronin": + skinRef = "ronin_skin_fd" + break + case "tone": + skinRef = "tone_skin_fd" + break + case "legion": + skinRef = "legion_skin_fd" + break + case "vanguard": + skinRef = "monarch_skin_fd" + break + } + + return !IsSubItemLocked( player, skinRef, titanClass ) +} + +string function GetWeaponWarpaintRefByIndex( int skinIndex, string parentRef ) +{ + ItemData parentItem = GetItemData( parentRef ) + foreach ( subItem in parentItem.subitems ) + { + if ( GetSubitemType( parentRef, subItem.ref ) != eItemTypes.WEAPON_SKIN ) + continue + if ( subItem.i.skinIndex != skinIndex ) + continue + + return subItem.ref + } + + return INVALID_REF +} +#endif // SERVER + +#endif // MP diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_server_to_client_stringcommands.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_server_to_client_stringcommands.gnut index a51e528f..18df6a6f 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_server_to_client_stringcommands.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_server_to_client_stringcommands.gnut @@ -1,6 +1,4 @@ #if CLIENT -global function ServerToClientStringCommands_Init - global function AddServerToClientStringCommandCallback global function NSClientCodeCallback_RecievedServerToClientStringCommand #endif @@ -14,11 +12,6 @@ struct { table< string, array< void functionref( array<string> args ) > > callbacks } file -void function ServerToClientStringCommands_Init() -{ - getroottable().rawset( "NSClientCodeCallback_RecievedServerToClientStringCommand", NSClientCodeCallback_RecievedServerToClientStringCommand ) -} - void function AddServerToClientStringCommandCallback( string command, void functionref( array<string> args ) callback ) { if ( !( command in file.callbacks ) ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_store.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_store.gnut new file mode 100644 index 00000000..371cc1c7 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_store.gnut @@ -0,0 +1,933 @@ + +global function Store_Init +global function Store_GetCustomizationRefs +global function Store_GetPatchRefs +global function Store_GetBannerRefs +global function Store_GetCamoRefs + +global struct CamoRef +{ + string ref + string pilotRef + string titanRef +} + +struct RefData +{ + string ref + string parentRef +} + +struct +{ + table< int, array<string> > customizationRefs + table< int, array<string> > patchRefs + table< int, array<string> > bannerRefs + table< int, array<CamoRef> > camoRefs + table< int, array<RefData> > limitedEditionFDRefData +} file + +void function Store_Init() +{ + #if SERVER + AddClientCommandCallback( "SetHasSeenStore", ClientCommand_SetHasSeenStore ) + AddClientCommandCallback( "StoreSetNewItemStatus", ClientCommand_StoreSetNewItemStatus ) + #endif + + file.customizationRefs[ ET_DLC1_ION ] <- [] + file.customizationRefs[ ET_DLC1_ION ].append( "ion_skin_10" ) + file.customizationRefs[ ET_DLC1_ION ].append( "ion_nose_art_17" ) + file.customizationRefs[ ET_DLC1_ION ].append( "ion_nose_art_18" ) + file.customizationRefs[ ET_DLC1_ION ].append( "ion_nose_art_19" ) + file.customizationRefs[ ET_DLC1_ION ].append( "ion_nose_art_20" ) + file.customizationRefs[ ET_DLC1_ION ].append( "ion_nose_art_21" ) + file.customizationRefs[ ET_DLC3_ION ] <- [] + file.customizationRefs[ ET_DLC3_ION ].append( "ion_skin_11" ) + file.customizationRefs[ ET_DLC3_ION ].append( "ion_nose_art_22" ) + file.customizationRefs[ ET_DLC3_ION ].append( "ion_nose_art_23" ) + file.customizationRefs[ ET_DLC3_ION ].append( "ion_nose_art_24" ) + file.customizationRefs[ ET_DLC3_ION ].append( "ion_nose_art_25" ) + file.customizationRefs[ ET_DLC3_ION ].append( "ion_nose_art_26" ) + file.customizationRefs[ ET_DLC5_ION ] <- [] + file.customizationRefs[ ET_DLC5_ION ].append( "ion_skin_07" ) + file.customizationRefs[ ET_DLC5_ION ].append( "ion_nose_art_27" ) + file.customizationRefs[ ET_DLC5_ION ].append( "ion_nose_art_28" ) + file.customizationRefs[ ET_DLC5_ION ].append( "ion_nose_art_29" ) + file.customizationRefs[ ET_DLC5_ION ].append( "ion_nose_art_30" ) + file.customizationRefs[ ET_DLC5_ION ].append( "ion_nose_art_31" ) + + file.customizationRefs[ ET_DLC1_SCORCH ] <- [] + file.customizationRefs[ ET_DLC1_SCORCH ].append( "scorch_skin_07" ) + file.customizationRefs[ ET_DLC1_SCORCH ].append( "scorch_nose_art_15" ) + file.customizationRefs[ ET_DLC1_SCORCH ].append( "scorch_nose_art_16" ) + file.customizationRefs[ ET_DLC1_SCORCH ].append( "scorch_nose_art_17" ) + file.customizationRefs[ ET_DLC1_SCORCH ].append( "scorch_nose_art_18" ) + file.customizationRefs[ ET_DLC1_SCORCH ].append( "scorch_nose_art_19" ) + file.customizationRefs[ ET_DLC3_SCORCH ] <- [] + file.customizationRefs[ ET_DLC3_SCORCH ].append( "scorch_skin_08" ) + file.customizationRefs[ ET_DLC3_SCORCH ].append( "scorch_nose_art_20" ) + file.customizationRefs[ ET_DLC3_SCORCH ].append( "scorch_nose_art_21" ) + file.customizationRefs[ ET_DLC3_SCORCH ].append( "scorch_nose_art_22" ) + file.customizationRefs[ ET_DLC3_SCORCH ].append( "scorch_nose_art_23" ) + file.customizationRefs[ ET_DLC3_SCORCH ].append( "scorch_nose_art_24" ) + file.customizationRefs[ ET_DLC5_SCORCH ] <- [] + file.customizationRefs[ ET_DLC5_SCORCH ].append( "scorch_skin_06" ) + file.customizationRefs[ ET_DLC5_SCORCH ].append( "scorch_nose_art_25" ) + file.customizationRefs[ ET_DLC5_SCORCH ].append( "scorch_nose_art_26" ) + file.customizationRefs[ ET_DLC5_SCORCH ].append( "scorch_nose_art_27" ) + file.customizationRefs[ ET_DLC5_SCORCH ].append( "scorch_nose_art_28" ) + file.customizationRefs[ ET_DLC5_SCORCH ].append( "scorch_nose_art_29" ) + + file.customizationRefs[ ET_DLC1_NORTHSTAR ] <- [] + file.customizationRefs[ ET_DLC1_NORTHSTAR ].append( "northstar_skin_10" ) + file.customizationRefs[ ET_DLC1_NORTHSTAR ].append( "northstar_nose_art_18" ) + file.customizationRefs[ ET_DLC1_NORTHSTAR ].append( "northstar_nose_art_19" ) + file.customizationRefs[ ET_DLC1_NORTHSTAR ].append( "northstar_nose_art_20" ) + file.customizationRefs[ ET_DLC1_NORTHSTAR ].append( "northstar_nose_art_21" ) + file.customizationRefs[ ET_DLC1_NORTHSTAR ].append( "northstar_nose_art_22" ) + file.customizationRefs[ ET_DLC3_NORTHSTAR ] <- [] + file.customizationRefs[ ET_DLC3_NORTHSTAR ].append( "northstar_skin_11" ) + file.customizationRefs[ ET_DLC3_NORTHSTAR ].append( "northstar_nose_art_23" ) + file.customizationRefs[ ET_DLC3_NORTHSTAR ].append( "northstar_nose_art_24" ) + file.customizationRefs[ ET_DLC3_NORTHSTAR ].append( "northstar_nose_art_25" ) + file.customizationRefs[ ET_DLC3_NORTHSTAR ].append( "northstar_nose_art_26" ) + file.customizationRefs[ ET_DLC3_NORTHSTAR ].append( "northstar_nose_art_27" ) + file.customizationRefs[ ET_DLC5_NORTHSTAR ] <- [] + file.customizationRefs[ ET_DLC5_NORTHSTAR ].append( "northstar_skin_06" ) + file.customizationRefs[ ET_DLC5_NORTHSTAR ].append( "northstar_nose_art_28" ) + file.customizationRefs[ ET_DLC5_NORTHSTAR ].append( "northstar_nose_art_29" ) + file.customizationRefs[ ET_DLC5_NORTHSTAR ].append( "northstar_nose_art_30" ) + file.customizationRefs[ ET_DLC5_NORTHSTAR ].append( "northstar_nose_art_31" ) + file.customizationRefs[ ET_DLC5_NORTHSTAR ].append( "northstar_nose_art_32" ) + + file.customizationRefs[ ET_DLC1_RONIN ] <- [] + file.customizationRefs[ ET_DLC1_RONIN ].append( "ronin_skin_10" ) + file.customizationRefs[ ET_DLC1_RONIN ].append( "ronin_nose_art_16" ) + file.customizationRefs[ ET_DLC1_RONIN ].append( "ronin_nose_art_17" ) + file.customizationRefs[ ET_DLC1_RONIN ].append( "ronin_nose_art_18" ) + file.customizationRefs[ ET_DLC1_RONIN ].append( "ronin_nose_art_19" ) + file.customizationRefs[ ET_DLC1_RONIN ].append( "ronin_nose_art_20" ) + file.customizationRefs[ ET_DLC3_RONIN ] <- [] + file.customizationRefs[ ET_DLC3_RONIN ].append( "ronin_skin_11" ) + file.customizationRefs[ ET_DLC3_RONIN ].append( "ronin_nose_art_21" ) + file.customizationRefs[ ET_DLC3_RONIN ].append( "ronin_nose_art_22" ) + file.customizationRefs[ ET_DLC3_RONIN ].append( "ronin_nose_art_23" ) + file.customizationRefs[ ET_DLC3_RONIN ].append( "ronin_nose_art_24" ) + file.customizationRefs[ ET_DLC3_RONIN ].append( "ronin_nose_art_25" ) + file.customizationRefs[ ET_DLC5_RONIN ] <- [] + file.customizationRefs[ ET_DLC5_RONIN ].append( "ronin_skin_07" ) + file.customizationRefs[ ET_DLC5_RONIN ].append( "ronin_nose_art_26" ) + file.customizationRefs[ ET_DLC5_RONIN ].append( "ronin_nose_art_27" ) + file.customizationRefs[ ET_DLC5_RONIN ].append( "ronin_nose_art_28" ) + file.customizationRefs[ ET_DLC5_RONIN ].append( "ronin_nose_art_29" ) + file.customizationRefs[ ET_DLC5_RONIN ].append( "ronin_nose_art_30" ) + + file.customizationRefs[ ET_DLC1_TONE ] <- [] + file.customizationRefs[ ET_DLC1_TONE ].append( "tone_skin_06" ) + file.customizationRefs[ ET_DLC1_TONE ].append( "tone_nose_art_17" ) + file.customizationRefs[ ET_DLC1_TONE ].append( "tone_nose_art_18" ) + file.customizationRefs[ ET_DLC1_TONE ].append( "tone_nose_art_19" ) + file.customizationRefs[ ET_DLC1_TONE ].append( "tone_nose_art_20" ) + file.customizationRefs[ ET_DLC1_TONE ].append( "tone_nose_art_21" ) + file.customizationRefs[ ET_DLC3_TONE ] <- [] + file.customizationRefs[ ET_DLC3_TONE ].append( "tone_skin_07" ) + file.customizationRefs[ ET_DLC3_TONE ].append( "tone_nose_art_22" ) + file.customizationRefs[ ET_DLC3_TONE ].append( "tone_nose_art_23" ) + file.customizationRefs[ ET_DLC3_TONE ].append( "tone_nose_art_24" ) + file.customizationRefs[ ET_DLC3_TONE ].append( "tone_nose_art_25" ) + file.customizationRefs[ ET_DLC3_TONE ].append( "tone_nose_art_26" ) + file.customizationRefs[ ET_DLC5_TONE ] <- [] + file.customizationRefs[ ET_DLC5_TONE ].append( "tone_skin_08" ) + file.customizationRefs[ ET_DLC5_TONE ].append( "tone_nose_art_27" ) + file.customizationRefs[ ET_DLC5_TONE ].append( "tone_nose_art_28" ) + file.customizationRefs[ ET_DLC5_TONE ].append( "tone_nose_art_29" ) + file.customizationRefs[ ET_DLC5_TONE ].append( "tone_nose_art_30" ) + file.customizationRefs[ ET_DLC5_TONE ].append( "tone_nose_art_31" ) + + file.customizationRefs[ ET_DLC1_LEGION ] <- [] + file.customizationRefs[ ET_DLC1_LEGION ].append( "legion_skin_07" ) + file.customizationRefs[ ET_DLC1_LEGION ].append( "legion_nose_art_17" ) + file.customizationRefs[ ET_DLC1_LEGION ].append( "legion_nose_art_18" ) + file.customizationRefs[ ET_DLC1_LEGION ].append( "legion_nose_art_19" ) + file.customizationRefs[ ET_DLC1_LEGION ].append( "legion_nose_art_20" ) + file.customizationRefs[ ET_DLC1_LEGION ].append( "legion_nose_art_21" ) + file.customizationRefs[ ET_DLC3_LEGION ] <- [] + file.customizationRefs[ ET_DLC3_LEGION ].append( "legion_skin_08" ) + file.customizationRefs[ ET_DLC3_LEGION ].append( "legion_nose_art_22" ) + file.customizationRefs[ ET_DLC3_LEGION ].append( "legion_nose_art_23" ) + file.customizationRefs[ ET_DLC3_LEGION ].append( "legion_nose_art_24" ) + file.customizationRefs[ ET_DLC3_LEGION ].append( "legion_nose_art_25" ) + file.customizationRefs[ ET_DLC3_LEGION ].append( "legion_nose_art_26" ) + file.customizationRefs[ ET_DLC5_LEGION ] <- [] + file.customizationRefs[ ET_DLC5_LEGION ].append( "legion_skin_09" ) + file.customizationRefs[ ET_DLC5_LEGION ].append( "legion_nose_art_27" ) + file.customizationRefs[ ET_DLC5_LEGION ].append( "legion_nose_art_28" ) + file.customizationRefs[ ET_DLC5_LEGION ].append( "legion_nose_art_29" ) + file.customizationRefs[ ET_DLC5_LEGION ].append( "legion_nose_art_30" ) + file.customizationRefs[ ET_DLC5_LEGION ].append( "legion_nose_art_31" ) + + file.patchRefs[ ET_DLC1_CALLSIGN ] <- [] + file.patchRefs[ ET_DLC3_CALLSIGN ] <- [] + file.patchRefs[ ET_DLC5_CALLSIGN ] <- [] + + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_64" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_aces" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_alien" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_apex" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_ares" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_controller" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_drone" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_heartbreaker" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_hexes" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_kodai" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_lastimosa" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_lawai" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_mcor" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_phoenix" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_pilot" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_robot" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_sentry" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_super_spectre" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_vinson" ) + file.patchRefs[ ET_DLC1_CALLSIGN ].append( "gc_icon_wonyeon" ) + + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_balance" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_boot" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_bt_eye" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_buzzsaw" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_crossed_lighting" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_flying_bullet" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_hammer2" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_keyboard" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_lightbulb" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_narwhal" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_peace" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_pilot2" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_robot_eye" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_srs" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_starline" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_taco" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_thumbdown" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_thumbup" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_treble" ) + file.patchRefs[ ET_DLC3_CALLSIGN ].append( "gc_icon_vanguard" ) + + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_monarch_dlc5" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_militia" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_militia_alt" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_imc" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_hammond" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_tri_chevron" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_pilot_circle" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_x" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_nessie" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_spicy" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_crown" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_pawn" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_excite" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_duck" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_sock" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_rabbit" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_peanut" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_clock" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_shamrock" ) + file.patchRefs[ ET_DLC5_CALLSIGN ].append( "gc_icon_trident" ) + + file.bannerRefs[ ET_DLC1_CALLSIGN ] <- [] + file.bannerRefs[ ET_DLC3_CALLSIGN ] <- [] + file.bannerRefs[ ET_DLC5_CALLSIGN ] <- [] + + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_106_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_107_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_108_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_109_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_110_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_111_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_112_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_113_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_114_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_115_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_116_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_117_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_118_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_119_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_120_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_121_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_122_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_123_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_124_col" ) + file.bannerRefs[ ET_DLC1_CALLSIGN ].append( "callsign_125_col" ) + + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_143_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_144_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_145_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_146_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_147_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_148_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_149_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_150_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_151_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_152_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_153_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_154_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_155_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_156_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_157_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_158_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_159_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_160_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_161_col" ) + file.bannerRefs[ ET_DLC3_CALLSIGN ].append( "callsign_162_col" ) + + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_166_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_167_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_168_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_169_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_170_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_171_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_172_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_173_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_174_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_175_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_176_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_177_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_178_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_179_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_180_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_181_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_182_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_183_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_184_col" ) + file.bannerRefs[ ET_DLC5_CALLSIGN ].append( "callsign_185_col" ) + + file.camoRefs[ ET_DLC1_CAMO ] <- [] + file.camoRefs[ ET_DLC3_CAMO ] <- [] + file.camoRefs[ ET_DLC5_CAMO ] <- [] + + for ( int i = 101; i <= 120; i++ ) + { + AddCamoRef( ET_DLC1_CAMO, i ) + } + + for ( int i = 121; i <= 140; i++ ) + { + AddCamoRef( ET_DLC3_CAMO, i ) + } + + // You did it reddit! + int numRefs = file.camoRefs[ ET_DLC3_CAMO ].len() + CamoRef tempRef = file.camoRefs[ ET_DLC3_CAMO ][numRefs - 1] + file.camoRefs[ ET_DLC3_CAMO ][numRefs - 1] = file.camoRefs[ ET_DLC3_CAMO ][numRefs - 2] + file.camoRefs[ ET_DLC3_CAMO ][numRefs - 2] = tempRef + + for ( int i = 141; i <= 160; i++ ) + { + AddCamoRef( ET_DLC5_CAMO, i ) + } + + file.limitedEditionFDRefData[ ET_DLC7_ION_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_ION_WARPAINT ].append( CreateRefData( "ion_skin_fd", "ion" ) ) + file.limitedEditionFDRefData[ ET_DLC7_ION_WARPAINT ].append( CreateRefData( "callsign_fd_ion_dynamic" ) ) + + file.limitedEditionFDRefData[ ET_DLC7_SCORCH_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_SCORCH_WARPAINT ].append( CreateRefData( "scorch_skin_fd", "scorch" ) ) + file.limitedEditionFDRefData[ ET_DLC7_SCORCH_WARPAINT ].append( CreateRefData( "callsign_fd_scorch_dynamic" ) ) + + file.limitedEditionFDRefData[ ET_DLC7_NORTHSTAR_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_NORTHSTAR_WARPAINT ].append( CreateRefData( "northstar_skin_fd", "northstar" ) ) + file.limitedEditionFDRefData[ ET_DLC7_NORTHSTAR_WARPAINT ].append( CreateRefData( "callsign_fd_northstar_dynamic" ) ) + + file.limitedEditionFDRefData[ ET_DLC7_RONIN_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_RONIN_WARPAINT ].append( CreateRefData( "ronin_skin_fd", "ronin" ) ) + file.limitedEditionFDRefData[ ET_DLC7_RONIN_WARPAINT ].append( CreateRefData( "callsign_fd_ronin_dynamic" ) ) + + file.limitedEditionFDRefData[ ET_DLC7_TONE_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_TONE_WARPAINT ].append( CreateRefData( "tone_skin_fd", "tone" ) ) + file.limitedEditionFDRefData[ ET_DLC7_TONE_WARPAINT ].append( CreateRefData( "callsign_fd_tone_dynamic" ) ) + + file.limitedEditionFDRefData[ ET_DLC7_LEGION_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_LEGION_WARPAINT ].append( CreateRefData( "legion_skin_fd", "legion" ) ) + file.limitedEditionFDRefData[ ET_DLC7_LEGION_WARPAINT ].append( CreateRefData( "callsign_fd_legion_dynamic" ) ) + + file.limitedEditionFDRefData[ ET_DLC7_MONARCH_WARPAINT ] <- [] + file.limitedEditionFDRefData[ ET_DLC7_MONARCH_WARPAINT ].append( CreateRefData( "monarch_skin_fd", "vanguard" ) ) + file.limitedEditionFDRefData[ ET_DLC7_MONARCH_WARPAINT ].append( CreateRefData( "callsign_fd_monarch_dynamic" ) ) +} + +RefData function CreateRefData( string ref, string parentRef = "" ) +{ + RefData data + data.ref = ref + data.parentRef = parentRef + + return data +} + +array<string> function Store_GetCustomizationRefs( int entitlementId ) +{ + return file.customizationRefs[ entitlementId ] +} + +array<string> function Store_GetPatchRefs( int entitlementId ) +{ + return file.patchRefs[ entitlementId ] +} + +array<string> function Store_GetBannerRefs( int entitlementId ) +{ + return file.bannerRefs[ entitlementId ] +} + +array<CamoRef> function Store_GetCamoRefs( int entitlementId ) +{ + return file.camoRefs[ entitlementId ] +} + +void function AddCamoRef( int entitlementId, int index ) +{ + CamoRef cref + cref.ref = "camo_skin" + index + cref.pilotRef = "pilot_camo_skin" + index + cref.titanRef = "titan_camo_skin" + index + file.camoRefs[ entitlementId ].append( cref ) +} + +#if SERVER +bool function ClientCommand_SetHasSeenStore( entity player, array<string> args ) +{ + player.SetPersistentVar( "hasSeenStore", true ) + + return true +} + +// TODO: refParam is problematic, because it assumes an entitlement maps to a single ref which is not the case for limited edition frontier defense entitlements +void function StoreUpdatePIN( entity player, int entitlementId, string refParam ) +{ + printt( "StoreUpdatePIN", entitlementId, refParam) + + switch ( entitlementId ) + { + case ET_DLC1_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc1_bundle", 0 ) + break + + case ET_DLC3_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc3_bundle", 0 ) + break + + case ET_DLC5_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc5_bundle", 0 ) + break + + case ET_PRIME_TITANS_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "sprime_titans_bundle", 0 ) + break + + case ET_DLC1_PRIME_ION: + case ET_DLC1_PRIME_SCORCH: + case ET_DLC3_PRIME_NORTHSTAR: + case ET_DLC3_PRIME_LEGION: + case ET_DLC5_PRIME_TONE: + case ET_DLC5_PRIME_RONIN: + Assert( refParam != "" ) + if ( refParam == "" || !ItemDefined( refParam ) ) + return + + PIN_BuyItemWithRealMoney( player, false, refParam, 0 ) + break + + case ET_DLC1_ION: + case ET_DLC1_SCORCH: + case ET_DLC1_NORTHSTAR: + case ET_DLC1_RONIN: + case ET_DLC1_TONE: + case ET_DLC1_LEGION: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "customization_" + refParam, 0 ) + break + + case ET_DLC3_ION: + case ET_DLC3_SCORCH: + case ET_DLC3_NORTHSTAR: + case ET_DLC3_RONIN: + case ET_DLC3_TONE: + case ET_DLC3_LEGION: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc3_customization_" + refParam, 0 ) + break + + case ET_DLC5_ION: + case ET_DLC5_SCORCH: + case ET_DLC5_NORTHSTAR: + case ET_DLC5_RONIN: + case ET_DLC5_TONE: + case ET_DLC5_LEGION: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc5_customization_" + refParam, 0 ) + break + + case ET_DLC1_CAMO: + PIN_BuyItemWithRealMoney( player, false, "dlc_camos", 0 ) + break + + case ET_DLC3_CAMO: + PIN_BuyItemWithRealMoney( player, false, "dlc3_camos", 0 ) + break + + case ET_DLC5_CAMO: + PIN_BuyItemWithRealMoney( player, false, "dlc5_camos", 0 ) + break + + case ET_DLC1_CALLSIGN: + PIN_BuyItemWithRealMoney( player, false, "dlc_callsigns", 0 ) + break + + case ET_DLC3_CALLSIGN: + PIN_BuyItemWithRealMoney( player, false, "dlc3_callsigns", 0 ) + break + + case ET_DLC5_CALLSIGN: + PIN_BuyItemWithRealMoney( player, false, "dlc5_callsigns", 0 ) + break + + case ET_DLC7_TITAN_WARPAINT_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc7_frontier_titan_warpaint_bundle", 0 ) + break + + case ET_DLC7_ION_WARPAINT: + case ET_DLC7_SCORCH_WARPAINT: + case ET_DLC7_NORTHSTAR_WARPAINT: + case ET_DLC7_RONIN_WARPAINT: + case ET_DLC7_TONE_WARPAINT: + case ET_DLC7_LEGION_WARPAINT: + case ET_DLC7_MONARCH_WARPAINT: + PIN_BuyItemWithRealMoney( player, false, "dlc7_frontier_titan_warpaint_" + file.limitedEditionFDRefData[ entitlementId ][0].ref, 0 ) + break + + case ET_DLC7_WEAPON_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc7_weapon_warpaint_bundle", 0 ) + break + + case ET_DLC7_R201_WARPAINT: + case ET_DLC7_G2A5_WARPAINT: + case ET_DLC7_FLATLINE_WARPAINT: + case ET_DLC7_CAR_WARPAINT: + case ET_DLC7_ALTERNATOR_WARPAINT: + case ET_DLC7_EVA8_WARPAINT: + case ET_DLC7_WINGMAN_WARPAINT: + case ET_DLC7_ARCHER_WARPAINT: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc7_weapon_warpaint_" + refParam, 0 ) + break + + case ET_DLC8_WEAPON_WARPAINT_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc8_weapon_warpaint_bundle", 0 ) + break + + case ET_DLC8_R201_WARPAINT: + case ET_DLC8_HEMLOK_WARPAINT: + case ET_DLC8_R97_WARPAINT: + case ET_DLC8_KRABER_WARPAINT: + case ET_DLC8_SPITFIRE_WARPAINT: + case ET_DLC8_DEVOTION_WARPAINT: + case ET_DLC8_MOZAMBIQUE_WARPAINT: + case ET_DLC8_THUNDERBOLT_WARPAINT: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc8_weapon_warpaint_" + refParam, 0 ) + break + + case ET_JUMPSTARTERBUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc10_jump_starter_pack", 0 ) + + case ET_DLC9_WEAPON_WARPAINT_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc9_weapon_warpaint_bundle", 0 ) + break + + case ET_DLC9_LSTAR_WARPAINT: + case ET_DLC9_MASTIFF_WARPAINT: + case ET_DLC9_SIDEWINDER_WARPAINT: + case ET_DLC9_R201_WARPAINT: + case ET_DLC9_CAR_WARPAINT: + case ET_DLC9_SPITFIRE_WARPAINT: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc9_weapon_warpaint_" + refParam, 0 ) + break + + case ET_DLC10_WEAPON_WARPAINT_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc10_weapon_warpaint_bundle", 0 ) + break + + case ET_DLC10_R101_WARPAINT: + case ET_DLC10_FLATLINE_WARPAINT: + case ET_DLC10_VOLT_WARPAINT: + case ET_DLC10_ALTERNATOR_WARPAINT: + case ET_DLC10_SOFTBALL_WARPAINT: + case ET_DLC10_EPG1_WARPAINT: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc10_weapon_warpaint_" + refParam, 0 ) + break + + case ET_DLC11_WEAPON_WARPAINT_BUNDLE: + PIN_BuyItemWithRealMoney( player, false, "dlc11_weapon_warpaint_bundle", 0 ) + break + + case ET_DLC11_DMR_WARPAINT: + case ET_DLC11_DOUBLETAKE_WARPAINT: + case ET_DLC11_G2A5_WARPAINT: + case ET_DLC11_COLDWAR_WARPAINT: + case ET_DLC11_R97_WARPAINT: + case ET_DLC11_R101_WARPAINT: + Assert( refParam != "" ) + if ( refParam == "" ) + return + + PIN_BuyItemWithRealMoney( player, false, "dlc11_weapon_warpaint_" + refParam, 0 ) + break + } +} + +bool function ClientCommand_StoreSetNewItemStatus( entity player, array<string> args ) +{ + // fix crash + if( args.len() < 1 ) + return true + + int entitlementId = int( args[0] ) + string refParam + string parentRefParam + + if ( args.len() >= 2 ) + refParam = args[1] + + if ( args.len() >= 3 ) + parentRefParam = args[2] + + StoreUpdatePIN( player, entitlementId, refParam ) + StoreSetNewItemStatus( player, entitlementId, refParam, parentRefParam ) + + return true +} + +bool function StoreSetNewItemStatus( entity player, int entitlementId, string refParam, string parentRefParam ) +{ + string e = entitlementId == ET_JUMPSTARTERBUNDLE ? "ET_JUMPSTARTERBUNDLE" : string( entitlementId ) + printt( "!!!!!!!!!!! StoreSetNewItemStatus() running for entitlement:", e ) + + switch ( entitlementId ) + { + case 3: + // Prime Titans + SetItemNewStatus( player, "ion_prime", "", true ) + SetItemNewStatus( player, "scorch_prime", "", true ) + + // Customization Packs + table< string, array<string> > dlc1BundleCustomizationRefs + dlc1BundleCustomizationRefs[ "ion" ] <- file.customizationRefs[ ET_DLC1_ION ] + dlc1BundleCustomizationRefs[ "tone" ] <- file.customizationRefs[ ET_DLC1_TONE ] + dlc1BundleCustomizationRefs[ "scorch" ] <- file.customizationRefs[ ET_DLC1_SCORCH ] + dlc1BundleCustomizationRefs[ "legion" ] <- file.customizationRefs[ ET_DLC1_LEGION ] + dlc1BundleCustomizationRefs[ "ronin" ] <- file.customizationRefs[ ET_DLC1_RONIN ] + dlc1BundleCustomizationRefs[ "northstar" ] <- file.customizationRefs[ ET_DLC1_NORTHSTAR ] + + foreach ( parentRef, childRefs in dlc1BundleCustomizationRefs ) + { + foreach ( ref in childRefs ) + { + if ( !SubitemDefined( parentRef, ref ) ) + return false + + SetItemNewStatus( player, ref, parentRef, true ) + } + } + + // Callsigns + foreach ( ref in file.patchRefs[ ET_DLC1_CALLSIGN ] ) + { + SetItemNewStatus( player, ref, "", true ) + } + + break + + case ET_DLC3_BUNDLE: + // Prime Titans + SetItemNewStatus( player, "northstar_prime", "", true ) + SetItemNewStatus( player, "legion_prime", "", true ) + + // Customization Packs + table< string, array<string> > dlc3BundleCustomizationRefs + dlc3BundleCustomizationRefs[ "ion" ] <- file.customizationRefs[ ET_DLC3_ION ] + dlc3BundleCustomizationRefs[ "tone" ] <- file.customizationRefs[ ET_DLC3_TONE ] + dlc3BundleCustomizationRefs[ "scorch" ] <- file.customizationRefs[ ET_DLC3_SCORCH ] + dlc3BundleCustomizationRefs[ "legion" ] <- file.customizationRefs[ ET_DLC3_LEGION ] + dlc3BundleCustomizationRefs[ "ronin" ] <- file.customizationRefs[ ET_DLC3_RONIN ] + dlc3BundleCustomizationRefs[ "northstar" ] <- file.customizationRefs[ ET_DLC3_NORTHSTAR ] + + foreach ( parentRef, childRefs in dlc3BundleCustomizationRefs ) + { + foreach ( ref in childRefs ) + { + if ( !SubitemDefined( parentRef, ref ) ) + return false + + SetItemNewStatus( player, ref, parentRef, true ) + } + } + + // Callsigns + foreach ( ref in file.patchRefs[ ET_DLC3_CALLSIGN ] ) + { + SetItemNewStatus( player, ref, "", true ) + } + + break + + case ET_DLC5_BUNDLE: + // Prime Titans + SetItemNewStatus( player, "ronin_prime", "", true ) + SetItemNewStatus( player, "tone_prime", "", true ) + + // Customization Packs + table< string, array<string> > dlc5BundleCustomizationRefs + dlc5BundleCustomizationRefs[ "ion" ] <- file.customizationRefs[ ET_DLC5_ION ] + dlc5BundleCustomizationRefs[ "tone" ] <- file.customizationRefs[ ET_DLC5_TONE ] + dlc5BundleCustomizationRefs[ "scorch" ] <- file.customizationRefs[ ET_DLC5_SCORCH ] + dlc5BundleCustomizationRefs[ "legion" ] <- file.customizationRefs[ ET_DLC5_LEGION ] + dlc5BundleCustomizationRefs[ "ronin" ] <- file.customizationRefs[ ET_DLC5_RONIN ] + dlc5BundleCustomizationRefs[ "northstar" ] <- file.customizationRefs[ ET_DLC5_NORTHSTAR ] + + foreach ( parentRef, childRefs in dlc5BundleCustomizationRefs ) + { + foreach ( ref in childRefs ) + { + if ( !SubitemDefined( parentRef, ref ) ) + return false + + SetItemNewStatus( player, ref, parentRef, true ) + } + } + + // Callsigns + foreach ( ref in file.patchRefs[ ET_DLC5_CALLSIGN ] ) + { + SetItemNewStatus( player, ref, "", true ) + } + + break + + case ET_PRIME_TITANS_BUNDLE: + SetItemNewStatus( player, "ion_prime", "", true ) + SetItemNewStatus( player, "scorch_prime", "", true ) + SetItemNewStatus( player, "northstar_prime", "", true ) + SetItemNewStatus( player, "legion_prime", "", true ) + SetItemNewStatus( player, "ronin_prime", "", true ) + SetItemNewStatus( player, "tone_prime", "", true ) + break + + case ET_DLC1_PRIME_ION: + case ET_DLC1_PRIME_SCORCH: + case ET_DLC3_PRIME_NORTHSTAR: + case ET_DLC3_PRIME_LEGION: + case ET_DLC5_PRIME_TONE: + case ET_DLC5_PRIME_RONIN: + Assert( refParam != "" ) + if ( refParam == "" || !ItemDefined( refParam ) ) + return false + + SetItemNewStatus( player, refParam, "", true ) + break + + case ET_DLC1_ION: + case ET_DLC3_ION: + case ET_DLC5_ION: + case ET_DLC1_SCORCH: + case ET_DLC3_SCORCH: + case ET_DLC5_SCORCH: + case ET_DLC1_NORTHSTAR: + case ET_DLC3_NORTHSTAR: + case ET_DLC5_NORTHSTAR: + case ET_DLC1_RONIN: + case ET_DLC3_RONIN: + case ET_DLC5_RONIN: + case ET_DLC1_TONE: + case ET_DLC3_TONE: + case ET_DLC5_TONE: + case ET_DLC1_LEGION: + case ET_DLC3_LEGION: + case ET_DLC5_LEGION: + Assert( refParam != "" ) + if ( refParam == "" ) + return false + + foreach ( ref in file.customizationRefs[ entitlementId ] ) + { + if ( !SubitemDefined( refParam, ref ) ) + return false + + SetItemNewStatus( player, ref, refParam, true ) + } + break + + case ET_DLC1_CAMO: + case ET_DLC3_CAMO: + case ET_DLC5_CAMO: + // Not implemented, way too many camos would show as new + break + + case ET_DLC1_CALLSIGN: + case ET_DLC3_CALLSIGN: + case ET_DLC5_CALLSIGN: + foreach ( ref in file.patchRefs[ entitlementId ] ) + { + SetItemNewStatus( player, ref, "", true ) + } + + foreach ( ref in file.bannerRefs[ entitlementId ] ) + { + SetItemNewStatus( player, ref, "", true ) + } + break + + case ET_DLC7_TITAN_WARPAINT_BUNDLE: + array<int> childEntitlements = GetChildEntitlements( entitlementId ) + + foreach ( entitlement in childEntitlements ) + { + foreach ( data in file.limitedEditionFDRefData[ entitlement ] ) + SetItemNewStatus( player, data.ref, data.parentRef, true ) + } + break + + case ET_DLC7_ION_WARPAINT: + case ET_DLC7_SCORCH_WARPAINT: + case ET_DLC7_NORTHSTAR_WARPAINT: + case ET_DLC7_RONIN_WARPAINT: + case ET_DLC7_TONE_WARPAINT: + case ET_DLC7_LEGION_WARPAINT: + case ET_DLC7_MONARCH_WARPAINT: + foreach ( data in file.limitedEditionFDRefData[ entitlementId ] ) + SetItemNewStatus( player, data.ref, data.parentRef, true ) + break + + case ET_DLC7_R201_WARPAINT: + case ET_DLC7_G2A5_WARPAINT: + case ET_DLC7_FLATLINE_WARPAINT: + case ET_DLC7_CAR_WARPAINT: + case ET_DLC7_ALTERNATOR_WARPAINT: + case ET_DLC7_EVA8_WARPAINT: + case ET_DLC7_WINGMAN_WARPAINT: + case ET_DLC7_ARCHER_WARPAINT: + case ET_DLC8_R201_WARPAINT: + case ET_DLC8_HEMLOK_WARPAINT: + case ET_DLC8_R97_WARPAINT: + case ET_DLC8_KRABER_WARPAINT: + case ET_DLC8_SPITFIRE_WARPAINT: + case ET_DLC8_DEVOTION_WARPAINT: + case ET_DLC8_MOZAMBIQUE_WARPAINT: + case ET_DLC8_THUNDERBOLT_WARPAINT: + case ET_DLC9_LSTAR_WARPAINT: + case ET_DLC9_MASTIFF_WARPAINT: + case ET_DLC9_SIDEWINDER_WARPAINT: + case ET_DLC9_R201_WARPAINT: + case ET_DLC9_CAR_WARPAINT: + case ET_DLC9_SPITFIRE_WARPAINT: + case ET_DLC10_R101_WARPAINT: + case ET_DLC10_FLATLINE_WARPAINT: + case ET_DLC10_VOLT_WARPAINT: + case ET_DLC10_ALTERNATOR_WARPAINT: + case ET_DLC10_SOFTBALL_WARPAINT: + case ET_DLC10_EPG1_WARPAINT: + case ET_DLC11_DMR_WARPAINT: + case ET_DLC11_DOUBLETAKE_WARPAINT: + case ET_DLC11_G2A5_WARPAINT: + case ET_DLC11_COLDWAR_WARPAINT: + case ET_DLC11_R97_WARPAINT: + case ET_DLC11_R101_WARPAINT: + Assert( refParam != "" ) + if ( refParam == "" || !ItemDefined( refParam ) ) + return false + + Assert( parentRefParam != "" ) + if ( parentRefParam == "" || !ItemDefined( parentRefParam ) ) + return false + + SetItemNewStatus( player, refParam, parentRefParam, true ) + break + + case ET_DLC7_WEAPON_BUNDLE: + SetItemNewStatus( player, "skin_rspn101_wasteland", "mp_weapon_rspn101", true ) + SetItemNewStatus( player, "skin_g2_masterwork", "mp_weapon_g2", true ) + SetItemNewStatus( player, "skin_vinson_blue_fade", "mp_weapon_vinson", true ) + SetItemNewStatus( player, "skin_car_crimson_fury", "mp_weapon_car", true ) + SetItemNewStatus( player, "skin_alternator_patriot", "mp_weapon_alternator_smg", true ) + SetItemNewStatus( player, "skin_shotgun_badlands", "mp_weapon_shotgun", true ) + SetItemNewStatus( player, "skin_wingman_aqua_fade", "mp_weapon_wingman", true ) + SetItemNewStatus( player, "skin_rocket_launcher_psych_spectre", "mp_weapon_rocket_launcher", true ) + break + + case ET_DLC8_WEAPON_WARPAINT_BUNDLE: + SetItemNewStatus( player, "skin_rspn101_patriot", "mp_weapon_rspn101", true ) + SetItemNewStatus( player, "skin_hemlok_mochi", "mp_weapon_hemlok", true ) + SetItemNewStatus( player, "skin_r97_purple_fade", "mp_weapon_r97", true ) + SetItemNewStatus( player, "skin_kraber_masterwork", "mp_weapon_sniper", true ) + SetItemNewStatus( player, "skin_spitfire_lead_farmer", "mp_weapon_lmg", true ) + SetItemNewStatus( player, "skin_devotion_rspn_customs", "mp_weapon_esaw", true ) + SetItemNewStatus( player, "skin_mozambique_crimson_fury", "mp_weapon_shotgun_pistol", true ) + SetItemNewStatus( player, "skin_thunderbolt_8bit", "mp_weapon_arc_launcher", true ) + break + + case ET_DLC9_WEAPON_WARPAINT_BUNDLE: + SetItemNewStatus( player, "skin_lstar_heatsink", "mp_weapon_lstar", true ) + SetItemNewStatus( player, "skin_mastiff_crimson_fury", "mp_weapon_mastiff", true ) + SetItemNewStatus( player, "skin_sidewinder_masterwork", "mp_weapon_smr", true ) + SetItemNewStatus( player, "skin_rspn101_halloween", "mp_weapon_rspn101", true ) + SetItemNewStatus( player, "skin_car_halloween", "mp_weapon_car", true ) + SetItemNewStatus( player, "skin_spitfire_halloween", "mp_weapon_lmg", true ) + break + + case ET_DLC10_WEAPON_WARPAINT_BUNDLE: + SetItemNewStatus( player, "skin_rspn101_og_blue_fade", "mp_weapon_rspn101_og", true ) + SetItemNewStatus( player, "skin_vinson_badlands", "mp_weapon_vinson", true ) + SetItemNewStatus( player, "skin_volt_heatsink", "mp_weapon_hemlok_smg", true ) + SetItemNewStatus( player, "skin_alternator_headhunter", "mp_weapon_alternator_smg", true ) + SetItemNewStatus( player, "skin_softball_masterwork", "mp_weapon_softball", true ) + SetItemNewStatus( player, "skin_epg_mrvn", "mp_weapon_epg", true ) + break + + case ET_DLC11_WEAPON_WARPAINT_BUNDLE: + SetItemNewStatus( player, "skin_dmr_phantom", "mp_weapon_dmr", true ) + SetItemNewStatus( player, "skin_doubletake_masterwork", "mp_weapon_doubletake", true ) + SetItemNewStatus( player, "skin_g2_purple_fade", "mp_weapon_g2", true ) + SetItemNewStatus( player, "skin_coldwar_heatsink", "mp_weapon_pulse_lmg", true ) + SetItemNewStatus( player, "skin_r97_sky", "mp_weapon_r97", true ) + SetItemNewStatus( player, "skin_rspn101_crimson_fury", "mp_weapon_rspn101", true ) + break + + case ET_JUMPSTARTERBUNDLE: + UnlockUltimateEdition( player ) + break + } + + return true +} +#endif diff --git a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut index 7f356a18..2ca051cf 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_utility_all.gnut @@ -348,6 +348,14 @@ string function GetMapDisplayDesc( string mapname ) return "#" + mapname + "_CLASSIC_DESC" } +/// Sends a string message to player +/// * `baseString` - The input string to search through +/// * `searchString` - Find this substring... +/// * `replaceString` - ...and replace with this substring +/// * `replaceAll` - Whether to replace all occurences or just the first +/// * `caseInsensitive` - Whether to consider casing (upper/lower) +/// +/// Returns the updated string string function StringReplace( string baseString, string searchString, string replaceString, bool replaceAll = false, bool caseInsensitive = false ) { bool loopedOnce = false @@ -362,7 +370,7 @@ string function StringReplace( string baseString, string searchString, string re source = part1 + replaceString + part2 loopedOnce = true - findResult = source.find( searchString ) + findResult = source.find( searchString, findResult + replaceString.len() ) } return baseString @@ -386,8 +394,12 @@ float function RoundToNearestMultiplier( float value, float multiplier ) return value } -function DevEverythingUnlocked() +function DevEverythingUnlocked( entity player = null ) { + // check if player has opted into progression or not + if ( player != null && ProgressionEnabledForPlayer( player ) ) + return false + return EverythingUnlockedConVarEnabled() } @@ -1528,7 +1540,23 @@ array<string> function GetAvailableTitanRefs( entity player ) return availableTitanRefs } +/// Gets the highest Titan FD level and stores it in the corresponding persistent var. +/// * `player` - The player entity to perform the action on #if MP +void function RecalculateHighestTitanFDLevel( entity player ) +{ + int enumCount = PersistenceGetEnumCount( "titanClasses" ) + int highestAegis = 0 + for ( int i = 0; i < enumCount; i++ ) + { + string enumName = PersistenceGetEnumItemNameForIndex( "titanClasses", i ) + int aegisLevel = FD_TitanGetLevelForXP( enumName, FD_TitanGetXP( player, enumName ) ) + if ( highestAegis < aegisLevel ) + highestAegis = aegisLevel + } + player.SetPersistentVar( "fdStats.highestTitanFDLevel", highestAegis ) +} + string function GetTitanRefForLoadoutIndex( entity player, int loadoutIndex ) { TitanLoadoutDef loadout = GetTitanLoadoutFromPersistentData( player, loadoutIndex ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut index c9d986bc..57361362 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut @@ -21,7 +21,6 @@ global function ReplacementTitan global function TryAnnounceTitanfallWarningToEnemyTeam global function GetTitanForPlayer - global function ShouldSetTitanRespawnTimer global function PauseTitanTimers @@ -33,6 +32,7 @@ global function SetReplacementTitanGamemodeRules global function SetRequestTitanGamemodeRules global function CreateTitanForPlayerAndHotdrop +global function SetRequestTitanAllowedCallback struct { array<int> ETATimeThresholds = [ 120, 60, 30, 15 ] @@ -53,6 +53,8 @@ struct { bool functionref( entity ) ReplacementTitanGamemodeRules bool functionref( entity, vector ) RequestTitanGamemodeRules + bool functionref( entity player, array< string > args ) RequestTitanAllowedCallback + } file const nagInterval = 40 @@ -87,6 +89,10 @@ function ReplacementTitans_Init() FlagInit( "LevelHasRoof" ) } +void function SetRequestTitanAllowedCallback( bool functionref( entity player, array<string> args ) RequestTitanAllowedCallback ) +{ + file.RequestTitanAllowedCallback = RequestTitanAllowedCallback +} void function ReplacementTitan_InitPlayer( entity player ) { @@ -424,6 +430,7 @@ function TryETATitanReadyAnnouncement( entity player ) TryReplacementTitanReadyAnnouncement( player ) return } + //This entire loop is probably too complicated now for what it's doing. Simplify next game! //Loop might be pretty hard to read, a particular iteration of the loop is written in comments below @@ -524,6 +531,9 @@ function req() bool function ClientCommand_RequestTitan( entity player, array<string> args ) { + if( file.RequestTitanAllowedCallback != null && !file.RequestTitanAllowedCallback( player, args ) ) + return true + ReplacementTitan( player ) //Separate function because other functions will call ReplacementTitan return true } @@ -877,6 +887,20 @@ void function CreateTitanForPlayerAndHotdrop( entity player, Point spawnPoint, T player.Signal( "titan_impact" ) thread TitanNPC_WaitForBubbleShield_StartAutoTitanBehavior( titan ) + thread PlayerEarnMeter_ReplacementTitanThink( player, titan ) +} + +void function PlayerEarnMeter_ReplacementTitanThink( entity player, entity titan ) +{ + player.EndSignal( "OnDestroy" ) + OnThreadEnd( + function(): ( player ) + { + if( IsValid( player ) ) + PlayerEarnMeter_Reset( player ) + } + ) + titan.WaitSignal( "OnDestroy" ) } void function CleanupTitanFallDisablingEntity( entity titanFallDisablingEntity, entity titan ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut index 933e9988..6972d5ff 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut @@ -4,6 +4,7 @@ global function HullTraceDropPoint global function DebugTitanfall global function TitanFindDropNodes global function TitanHulldropSpawnpoint +global function SetRecalculateTitanReplacementPointCallback global const TITANDROP_LOS_DIST = 2000 // 2D distance at which we do the line of sight check to see where the player wants to call in the titan global const TITANDROP_MIN_FOV = 10 @@ -19,8 +20,15 @@ global const TITANDROP_FALLBACK_DIST = 150 // if the ground search hits, we go t struct { int replacementSpawnpointsID + Point functionref(Point originalPoint, entity player) recalculateTitanReplacementPointCallback } file + +void function SetRecalculateTitanReplacementPointCallback(Point functionref(Point originalPoint, entity player) recalculateTitanReplacementPointCallback) +{ + file.recalculateTitanReplacementPointCallback = recalculateTitanReplacementPointCallback +} + void function ReplacementTitansDrop_Init() { AddSpawnCallback( "info_spawnpoint_titan", AddDroppoint ) @@ -117,7 +125,10 @@ Point function GetTitanReplacementPoint( entity player, bool forDebugging = fals vector playerEyeAngles = player.EyeAngles() vector playerOrg = player.GetOrigin() - return CalculateTitanReplacementPoint( playerOrg, playerEyePos, playerEyeAngles, forDebugging ) + Point tempPoint = CalculateTitanReplacementPoint( playerOrg, playerEyePos, playerEyeAngles, forDebugging) + if( file.recalculateTitanReplacementPointCallback != null ) + tempPoint = file.recalculateTitanReplacementPointCallback( tempPoint, player ) + return tempPoint } Point function CalculateTitanReplacementPoint( vector playerOrg, vector playerEyePos, vector playerEyeAngles, bool forDebugging = false ) @@ -165,6 +176,7 @@ Point function CalculateTitanReplacementPoint( vector playerOrg, vector playerEy Point point point.origin = dropPoint point.angles = yawAngles + return point } } @@ -215,7 +227,8 @@ Point function CalculateTitanReplacementPoint( vector playerOrg, vector playerEy Point point point.origin = nodeOrigin point.angles = Vector( 0, yaw, 0 ) - return point + + return point } vector function GetPathNodeSearchPosWithLookPos( vector playerOrg, vector playerEyePos, vector playerEyeForward, vector playerLookPos, bool debug ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut index d600cb03..396d5624 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut @@ -1010,7 +1010,7 @@ void function AddCreditToTitanCoreBuilder( entity titan, float credit ) if ( IsValid( bossPlayer ) && !coreWasAvailable && IsCoreChargeAvailable( bossPlayer, soul ) ) { - AddPlayerScore( bossPlayer, "TitanCoreEarned" ) + AddPlayerScore( bossPlayer, "TitanCoreEarned", bossPlayer ) // this will show the "Core Earned" callsign event #if MP UpdateTitanCoreEarnedStat( bossPlayer, titan ) PIN_PlayerAbilityReady( bossPlayer, "core" ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut index 5f72385e..d0a2d5e4 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut @@ -68,6 +68,11 @@ bool function ClientCommand_TitanEject( entity player, array<string> args ) if ( !PlayerCanEject( player ) ) return true + // check array length before accessing index to avoid oob access + // prevents crashing a server by just calling `TitanEject` without arguments + if( args.len() < 1 ) + return true + int ejectPressCount = args[ 0 ].tointeger() if ( ejectPressCount < 3 ) return true diff --git a/Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut index 4bfeb4f8..847881b5 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut @@ -1,14 +1,39 @@ global function AddTitanXP +global function AddFDTitanXP void function AddTitanXP( entity player, int amount ) { string titan = GetActiveTitanLoadout( player ).titanClass int oldLevel = TitanGetLevel( player, titan ) + int TitanXPMatch = player.GetPersistentVarAsInt( "xp_match[" + XP_TYPE.TITAN_LEVELED + "]" ) // increment xp player.SetPersistentVar( "titanXP[" + titan + "]", min( TitanGetXP( player, titan ) + amount, TitanGetMaxXP( titan ) ) ) + Remote_CallFunction_NonReplay( player, "ServerCallback_TitanXPAdded", shTitanXP.titanClasses.find( titan ), TitanGetXP( player, titan ), amount ) // level up notif if ( TitanGetLevel( player, titan ) != oldLevel ) + { Remote_CallFunction_NonReplay( player, "ServerCallback_TitanLeveledUp", shTitanXP.titanClasses.find( titan ), TitanGetGen( player, titan ), TitanGetLevel( player, titan ) ) + AddPlayerScore( player, "TitanLevelUp" ) + IncrementPlayerChallengeTitanLeveledUp( player ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.TITAN_LEVELED + "]", TitanXPMatch + 1 ) + + if( ProgressionEnabledForPlayer( player ) ) + AwardRandomItemsForTitanLevels( player, titan, oldLevel, TitanGetLevel( player, titan ) ) + } +} + +void function AddFDTitanXP( entity player, int fdXPamount ) +{ + string titanRef = GetActiveTitanLoadout( player ).titanClass + + player.SetPersistentVar( "fdTitanXP[" + titanRef + "]", FD_TitanGetPreviousXP( player, titanRef ) + fdXPamount ) + int startingLevel = FD_TitanGetLevelForXP( titanRef, FD_TitanGetPreviousXP( player, titanRef ) ) + int endingLevel = FD_TitanGetLevelForXP( titanRef, FD_TitanGetXP( player, titanRef ) ) + + Player_GiveFDUnlockPoints( player, endingLevel - startingLevel ) + + if( ProgressionEnabledForPlayer( player ) ) + AwardRandomItemsForFDTitanLevels( player, titanRef, startingLevel, endingLevel ) }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut index 8e100257..0b0084b3 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut @@ -6,14 +6,24 @@ void function AddWeaponXP( entity player, int amount ) entity activeWeapon = player.GetActiveWeapon() string weaponClassname = activeWeapon.GetWeaponClassName() int oldLevel = WeaponGetLevel( player, weaponClassname ) + int WeaponXPMatch = player.GetPersistentVarAsInt( "xp_match[" + XP_TYPE.WEAPON_LEVELED + "]" ) // increment xp player.SetPersistentVar( GetItemPersistenceStruct( weaponClassname ) + ".weaponXP", min( WeaponGetXP( player, weaponClassname ) + amount, WeaponGetMaxXP( weaponClassname ) ) ) + Remote_CallFunction_NonReplay( player, "ServerCallback_WeaponXPAdded", shWeaponXP.weaponClassNames.find( weaponClassname ), WeaponGetXP( player, weaponClassname ), amount ) // level up notif if ( WeaponGetLevel( player, weaponClassname ) != oldLevel ) + { Remote_CallFunction_NonReplay( player, "ServerCallback_WeaponLeveledUp", shWeaponXP.weaponClassNames.find( weaponClassname ), WeaponGetGen( player, weaponClassname ), WeaponGetLevel( player, weaponClassname ) ) - + AddPlayerScore( player, "WeaponLevelUp" ) + IncrementPlayerChallengeWeaponLeveledUp( player ) + player.SetPersistentVar( "xp_match[" + XP_TYPE.WEAPON_LEVELED + "]", WeaponXPMatch + 1 ) + + if( ProgressionEnabledForPlayer( player ) ) + AwardRandomItemsForWeaponLevels( player, weaponClassname, oldLevel, WeaponGetLevel( player, weaponClassname ) ) + } + // proscreen if ( player == activeWeapon.GetProScreenOwner() ) { |