1 #using scripts\codescripts\struct;
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\challenges_shared;
5 #using scripts\shared\drown;
6 #using scripts\shared\scoreevents_shared;
7 #using scripts\shared\system_shared;
8 #using scripts\shared\util_shared;
9 #using scripts\shared\weapons\_weapon_utils;
11 #using scripts\mp\_util;
12 #using scripts\mp\_challenges;
13 #using scripts\mp\gametypes\_globallogic;
14 #using scripts\mp\gametypes\_globallogic_score;
15 #using scripts\mp\gametypes\_loadout;
17 #insert scripts\shared\shared.gsh;
19 #using scripts\mp\_util;
21 #insert scripts\mp\_bonuscard.gsh;
22 #insert scripts\mp\_contracts.gsh;
24 #define DEFAULT_DAILY_CRYPTOKEYS 10 // look for dvar loot_cryptokeyCost
25 #define DEFAULT_WEEKLY_CRYPTOKEYS 30 // look for dvar loot_cryptokeyCost
26 #define DEFAULT_CRYPTOKEY_LOOTXP 100
28 #define ATTACHMENT_COUNT_FOR_LOADED_WEAPON_KILL 4
30 #define MAX_CONTRACT_SLOTS 10 // should coincide with contracts array size on mp_stats.ddl
31 #define FIRST_UNASSIGNED_CONTRACT_SLOT 3
32 #define DEFAULT_DEBUG_CONTRACT_SLOT MAX_CONTRACT_SLOTS - 1
35 #define CONTRACT_TABLE "gamedata/tables/mp/mp_contractTable.csv"
37 #define TARGET_VALUE_COL 2
38 #define NAME_STRING_COL 3
39 #define TITLE_OVERRIDE_COL 4
40 #define CONTRACT_TYPE 5
42 #define CALLING_CARD_STAT_COL 7 // mp_stats.ddl, PlayerStatsList[ <stat_name> ]
43 #define WEAPON_CAMO_STAT_COL 8 // mp_stats.ddl, PlayerStatsList[ <stat_name> ]
44 #define ABSOLUTE_STAT_PATH_COL 9 // mp_stats.ddl
49 #define BIG_TOTAL_WINS_INDEX 1
50 #define BIG_OBJECTIVE_WINS_INDEX 2
51 #define BIG_MEDALS_SPECIALIST_ABILITIES_INDEX 3
52 #define BIG_KILLS_INDEX 4
53 #define BIG_SCORE_INDEX 5
54 #define ATTACKER_DEFENDER_KILLS_INDEX 6
55 #define BIG_KILLS_SPECIALIST_WEAPON_INDEX 7
56 #define BIG_KILLS_KILLSTREAK_INDEX 8
59 #define TOTAL_WINS_INDEX 1000
60 #define ARENA_WINS_INDEX 1001
61 #define TDM_WINS_INDEX 1002
62 #define BALL_WINS_INDEX 1003
63 #define ESCORT_WINS_INDEX 1004
64 #define CONF_WINS_INDEX 1005
65 #define SD_WINS_INDEX 1006
66 #define KOTH_WINS_INDEX 1007
67 #define DOM_WINS_INDEX 1008
68 #define SCORE_INDEX 1009
69 #define KILLS_KILLSTREAK_INDEX 1010
70 #define KILLSTREAK_SCORE_INDEX 1011
71 #define KILLS_SPECIALIST_WEAPON_INDEX 1012
72 #define MEDALS_SPECIALIST_ABILITIES_INDEX 1013
73 #define SPECIALIST_KILLED_INDEX 1014
74 #define KILLS_INDEX 1015
75 #define HEADSHOTS_INDEX 1016
76 #define KILLED_DEFENDER_INDEX 1017
77 #define KILLED_ATTACKER_INDEX 1018
78 #define AR_KILL_INDEX 1019
79 #define SMG_KILL_INDEX 1020
80 #define SNIPER_KILL_INDEX 1021
81 #define LMG_KILL_INDEX 1022
82 #define SHOTGUN_KILL_INDEX 1023
83 #define PISTOL_KILL_INDEX 1024
84 #define LOADED_WEAPON_KILL_INDEX 1025
85 #define CTF_WINS_INDEX 1026
86 #define DEM_WINS_INDEX 1027
87 #define DM_WINS_INDEX 1028
88 #define CLEAN_WINS_INDEX 1029
91 #define HUGE_SMG_KILL_INDEX 3000
92 #define HUGE_AR_KILL_INDEX 3001
93 #define HUGE_SHOTGUN_KILL_INDEX 3002
94 #define HUGE_LMG_KILL_INDEX 3003
95 #define HUGE_SNIPER_KILL_INDEX 3004
96 #define HUGE_MELEE_WEAPON_KILL_INDEX 3005
97 #define HUGE_KILLS_SPECIALIST_WEAPON_INDEX 3006
98 #define HUGE_TOTAL_WINS_INDEX 3007
99 #define HUGE_TOTAL_WINS_INDEX_2 3008
100 #define HUGE_TOTAL_WINS_INDEX_3 3009
101 #define HUGE_TOTAL_WINS_INDEX_GRAND_SLAM 3010
102 #define HUGE_TOTAL_WINS_INDEX_4 3011
103 #define HUGE_TOTAL_WINS_INDEX_5 3012
104 #define HUGE_TOTAL_WINS_INDEX_6 3013
105 #define HUGE_TOTAL_WINS_INDEX_7 3014
106 #define HUGE_TOTAL_WINS_INDEX_8 3015
108 #namespace contracts;
110 #precache( "eventstring", "mp_daily_challenge_complete" );
111 #precache( "eventstring", "mp_weekly_challenge_complete" );
112 #precache( "eventstring", "mp_special_contract_complete" );
123 if ( !isdefined( level.ChallengesCallbacks ) )
125 level.ChallengesCallbacks = [];
178 if ( GetDvarInt(
"contracts_enabled_mp", 1 ) == 0 )
188 player.pers[
"contracts"] = [];
199 player.pers[
"contracts"][contract_index] = SpawnStruct();
200 player.pers[
"contracts"][contract_index].slot = slot;
202 player.pers[
"contracts"][contract_index].table_row = table_row;
213 if ( !isPlayer(
self ) )
216 if ( !isdefined(
self.pers[
"contracts"] ) )
219 if ( !isdefined(
self.pers[
"contracts"][challenge_index] ) )
223 if (
self.pers[
"contracts"][challenge_index].table_row == -1 )
233 if ( !isdefined( player ) || !isplayer( player ) )
241 if ( !isdefined( player ) || !isplayer( player ) )
252 if ( !isdefined( player ) || !isplayer( player ) )
260 if ( !isdefined( player ) || !isplayer( player ) )
272 if ( killstreak_purchased )
280 victim = data.victim;
281 attacker = data.attacker;
283 weapon = data.weapon;
286 if ( !isdefined( weapon ) || ( weapon == level.weaponNone ) )
289 if ( !isdefined( player ) || !isplayer( player ) )
295 if ( weapon.isHeroWeapon ===
true )
302 isKillstreak = isdefined( data.eInflictor ) && isdefined( data.eInflictor.killstreakid );
303 if ( !isKillstreak && isdefined( level.isKillstreakWeapon ) )
305 isKillstreakWeapon = [[level.isKillstreakWeapon]]( weapon );
308 if ( isKillstreak || ( isKillstreakWeapon ===
true ) )
314 statItemIndex = weapon.statIndex;
316 if ( player isItemPurchased( statItemIndex ) )
320 switch ( weaponClass )
322 case "weapon_assault":
332 case "weapon_sniper":
347 case "weapon_pistol":
359 total_unlocked = player GetTotalUnlockedWeaponAttachments( weapon );
377 slot =
self.pers[
"contracts"][contract_index].slot;
378 target_value =
self.pers[
"contracts"][contract_index].target_value;
381 new_progress = old_progress + delta;
383 if ( new_progress > target_value )
384 new_progress = target_value;
386 if ( new_progress != old_progress )
389 just_completed =
false;
390 if ( old_progress < target_value && target_value <= new_progress )
392 just_completed =
true;
395 event = &
"mp_weekly_challenge_complete";
396 display_rewards =
false;
400 event = &
"mp_daily_challenge_complete";
401 display_rewards =
true;
414 foreach ( c_index,c_data
in self.pers[
"contracts"] )
416 if ( c_data.slot == other_slot )
420 display_rewards =
true;
433 event = &
"mp_special_contract_complete";
434 display_rewards =
true;
436 absolute_stat_path =
self.pers[
"contracts"][contract_index].absolute_stat_path;
437 if ( absolute_stat_path !=
"" )
442 calling_card_stat =
self.pers[
"contracts"][contract_index].calling_card_stat;
443 if ( calling_card_stat !=
"" )
448 weapon_camo_stat =
self.pers[
"contracts"][contract_index].weapon_camo_stat;
449 if ( weapon_camo_stat !=
"" )
458 self LUINotifyEvent( event, 2, contract_index, display_rewards );
464 return self GetDStat(
"contracts", slot, stat_name );
469 return self SetDStat(
"contracts", slot, stat_name, stat_value );
476 return self AddPlayerStat( stat_name, stat_value );
481 stat_path_array = StrTok( stat_path,
" " );
489 switch( stat_path_array.size )
492 string_path_5 = stat_path_array[4];
493 if( StrIsNumber( string_path_5 ) )
495 string_path_5 = Int( string_path_5 );
498 string_path_4 = stat_path_array[3];
499 if( StrIsNumber( string_path_4 ) )
501 string_path_4 = Int( string_path_4 );
504 string_path_3 = stat_path_array[2];
505 if( StrIsNumber( string_path_3 ) )
507 string_path_3 = Int( string_path_3 );
510 string_path_2 = stat_path_array[1];
511 if( StrIsNumber( string_path_2 ) )
513 string_path_2 = Int( string_path_2 );
516 string_path_1 = stat_path_array[0];
517 if( StrIsNumber( string_path_1 ) )
519 string_path_1 = Int( string_path_1 );
523 switch( stat_path_array.size )
526 return self SetDStat( string_path_1, stat_value );
529 return self SetDStat( string_path_1, string_path_2, stat_value );
532 return self SetDStat( string_path_1, string_path_2, string_path_3, stat_value );
535 return self SetDStat( string_path_1, string_path_2, string_path_3, string_path_4, stat_value );
538 return self SetDStat( string_path_1, string_path_2, string_path_3, string_path_4, string_path_5, stat_value );
541 AssertMsg(
"Stat path depth of " + stat_path_array.size +
" is too large. Limit to 5 deep" );
548 if ( !isdefined(
self ) )
554 current_amount =
VAL(
self GetDStat(
"mp_loot_xp_due" ), 0 );
555 new_amount = current_amount + amount;
556 self SetDStat(
"mp_loot_xp_due", new_amount );
561 if ( !isdefined( weapon ) )
564 if ( isdefined( weapon.isHeroWeapon ) && !weapon.isHeroWeapon )
567 switch( weapon.name )
570 case "hero_minigun_body3":
573 case "hero_flamethrower":
576 case "hero_lightninggun":
577 case "hero_lightninggun_arc":
580 case "hero_chemicalgelgun":
581 case "hero_firefly_swarm":
584 case "hero_pineapplegun":
585 case "hero_pineapple_grenade":
588 case "hero_armblade":
591 case "hero_bowlauncher":
592 case "hero_bowlauncher2":
593 case "hero_bowlauncher3":
594 case "hero_bowlauncher4":
597 case "hero_gravityspikes":
600 case "hero_annihilator":
610 if ( !isdefined( ability ) )
613 switch( ability.name )
618 case "gadget_heat_wave":
621 case "gadget_flashback":
624 case "gadget_resurrect":
633 case "gadget_vision_pulse":
636 case "gadget_speed_burst":
639 case "gadget_combat_efficiency":
681 switch ( level.gametype )
753 if ( !isdefined( player.pers[
"contracts"] ) )
796 if ( !isdefined( player.pers[
"contracts"][contract_index] ) )
800 target_value = player.pers[
"contracts"][contract_index].target_value;
802 return ( progress >= target_value );
819 contract_count =
self GetDStat(
"blackjack_contract_count" );
820 reward_count = GetDvarInt(
"weekly_contract_blackjack_contract_reward_count", 1 );
821 self SetDStat(
"blackjack_contract_count", contract_count + reward_count );