diff --git a/.gitmodules b/.gitmodules index 1e8e1fd..03c64ab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,4 +47,7 @@ [submodule "deps/gsc-tool"] path = deps/gsc-tool url = https://github.com/xensik/gsc-tool.git - branch = xlabs + branch = dev +[submodule "deps/fmt"] + path = deps/fmt + url = https://github.com/fmtlib/fmt.git diff --git a/data/maps/mp/gametypes/_damage.gsc b/data/maps/mp/gametypes/_damage.gsc index 486c953..8332d39 100644 --- a/data/maps/mp/gametypes/_damage.gsc +++ b/data/maps/mp/gametypes/_damage.gsc @@ -1,5 +1,5 @@ // S1 GSC SOURCE -// Decompiled by https://github.com/xensik/gsc-tool +// Dumped by https://github.com/xensik/gsc-tool isswitchingteams() { @@ -104,7 +104,7 @@ handlesuicidedeath( var_0, var_1 ) [[ level.onsuicidedeath ]]( self ); if ( isdefined( self.friendlydamage ) ) - self _meth_826E( &"MP_FRIENDLY_FIRE_WILL_NOT" ); + self iprintlnbold( &"MP_FRIENDLY_FIRE_WILL_NOT" ); self.pers["suicideSpawnDelay"] = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "suicidespawndelay" ); } @@ -303,7 +303,7 @@ isplayerweapon( var_0 ) if ( weaponclass( var_0 ) == "turret" ) return 0; - if ( objective_current( var_0 ) == "primary" || objective_current( var_0 ) == "altmode" ) + if ( weaponinventorytype( var_0 ) == "primary" || weaponinventorytype( var_0 ) == "altmode" ) return 1; return 0; @@ -326,7 +326,7 @@ callback_playergrenadesuicide( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_8 = 1; if ( var_8 ) - var_0 _meth_82C8(); + var_0 laststanddie(); [[ level.callbackplayerlaststand ]]( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, 0 ); } @@ -393,9 +393,9 @@ playerkilled_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, v if ( isdefined( common_scripts\utility::getfx( "exo_knife_blood" ) ) ) { if ( isdefined( var_7 ) && isdefined( var_6 ) && isdefined( gethitloctag( var_7 ) ) ) - announcement( var_2 gettagorigin( gethitloctag( var_7 ) ), var_6 ); + playimpactheadfatalfx( var_2 gettagorigin( gethitloctag( var_7 ) ), var_6 ); else - announcement( var_2 gettagorigin( "j_neck" ), anglestoforward( var_2 gettagangles( "j_neck" ) ) ); + playimpactheadfatalfx( var_2 gettagorigin( "j_neck" ), anglestoforward( var_2 gettagangles( "j_neck" ) ) ); } } @@ -581,7 +581,7 @@ playerkilled_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, v } if ( !maps\mp\_utility::practiceroundgame() ) - canspawn( var_2, var_1, var_5, var_4 ); + obituary( var_2, var_1, var_5, var_4 ); var_24 = 0; var_2 logprintplayerdeath( self.lifeid, var_1, var_3, var_4, var_5, var_13, var_7 ); @@ -613,7 +613,7 @@ playerkilled_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, v else { if ( var_4 == "MOD_GRENADE" && var_0 == var_1 || var_4 == "MOD_IMPACT" || var_4 == "MOD_GRENADE_SPLASH" || var_4 == "MOD_EXPLOSIVE" ) - addattacker( var_2, var_1, var_0, var_5, var_3, ( 0.0, 0.0, 0.0 ), var_6, var_7, var_8, var_4 ); + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); var_24 = 1; @@ -1313,9 +1313,9 @@ dofinalkillcam() case "sentry_minigun_mp": var_3 maps\mp\gametypes\_missions::processchallenge( "ch_absentee" ); break; - case "ac130_25mm_mp": - case "ac130_105mm_mp": case "ac130_40mm_mp": + case "ac130_105mm_mp": + case "ac130_25mm_mp": var_3 maps\mp\gametypes\_missions::processchallenge( "ch_deathfromabove" ); break; case "remotemissile_projectile_mp": @@ -1387,32 +1387,32 @@ getkillcamentity( var_0, var_1, var_2 ) { case "boost_slam_mp": return var_1; - case "bomb_site_mp": - case "bouncingbetty_mp": - case "explosive_drone_mp": - case "orbital_carepackage_pod_mp": - case "orbital_carepackage_droppod_mp": - case "artillery_mp": - case "stealth_bomb_mp": - case "agent_mp": - case "refraction_turret_mp": - case "orbital_carepackage_pod_plane_mp": - case "remotemissile_projectile_cluster_child_mp": case "iw5_dlcgun12loot6_mp": + case "remotemissile_projectile_cluster_child_mp": + case "orbital_carepackage_pod_plane_mp": + case "refraction_turret_mp": + case "agent_mp": + case "stealth_bomb_mp": + case "artillery_mp": + case "orbital_carepackage_droppod_mp": + case "orbital_carepackage_pod_mp": + case "explosive_drone_mp": + case "bouncingbetty_mp": + case "bomb_site_mp": return var_1.killcament; case "killstreak_laser2_mp": if ( isdefined( var_1.samturret ) && isdefined( var_1.samturret.killcament ) ) return var_1.samturret.killcament; break; - case "ball_drone_gun_mp": case "ball_drone_projectile_mp": + case "ball_drone_gun_mp": if ( isplayer( var_0 ) && isdefined( var_0.balldrone ) && isdefined( var_0.balldrone.turret ) && isdefined( var_0.balldrone.turret.killcament ) ) return var_0.balldrone.turret.killcament; break; - case "ugv_missile_mp": case "drone_assault_remote_turret_mp": + case "ugv_missile_mp": if ( isdefined( var_1.killcament ) ) return var_1.killcament; else @@ -1422,9 +1422,9 @@ getkillcamentity( var_0, var_1, var_2 ) return var_1; else return undefined; - case "killstreak_solar_mp": - case "dam_turret_mp": case "warbird_missile_mp": + case "dam_turret_mp": + case "killstreak_solar_mp": if ( isdefined( var_1 ) && isdefined( var_1.killcament ) ) return var_1.killcament; @@ -1436,9 +1436,9 @@ getkillcamentity( var_0, var_1, var_2 ) return undefined; case "orbital_laser_fov_mp": return undefined; - case "sentry_minigun_mp": - case "remote_energy_turret_mp": case "killstreakmahem_mp": + case "remote_energy_turret_mp": + case "sentry_minigun_mp": if ( isdefined( var_1 ) && isdefined( var_1.remotecontrolled ) ) return undefined; @@ -1448,13 +1448,13 @@ getkillcamentity( var_0, var_1, var_2 ) return var_1.killcament; break; - case "ac130_25mm_mp": - case "ac130_105mm_mp": - case "ac130_40mm_mp": - case "ugv_turret_mp": - case "remote_turret_mp": - case "detroit_tram_turret_mp": case "killstreak_terrace_mp": + case "detroit_tram_turret_mp": + case "remote_turret_mp": + case "ugv_turret_mp": + case "ac130_40mm_mp": + case "ac130_105mm_mp": + case "ac130_25mm_mp": return undefined; case "iw5_dlcgun12loot8_mp": if ( isdefined( var_1.killcament ) ) @@ -1592,8 +1592,8 @@ ishardwrireprotected( var_0 ) switch ( var_0 ) { - case "killstreak_strike_missile_gas_mp": case "mp_lab_gas": + case "killstreak_strike_missile_gas_mp": return 1; } @@ -2144,8 +2144,8 @@ shouldweaponfeedback( var_0 ) { switch ( var_0 ) { - case "artillery_mp": case "stealth_bomb_mp": + case "artillery_mp": return 0; } @@ -2237,12 +2237,12 @@ is_countered_by_hardwired( var_0 ) { switch ( var_0 ) { - case "stun_grenade_mp": - case "paint_grenade_mp": - case "emp_grenade_mp": - case "stun_grenade_var_mp": - case "emp_grenade_var_mp": case "paint_grenade_var_mp": + case "emp_grenade_var_mp": + case "stun_grenade_var_mp": + case "emp_grenade_mp": + case "paint_grenade_mp": + case "stun_grenade_mp": return 1; } @@ -2267,7 +2267,7 @@ finishplayerdamagewrapper( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_ if ( var_11 || maps\mp\_utility::isrocketcorpse() ) { if ( !isdefined( var_7 ) ) - var_7 = ( 0.0, 0.0, 0.0 ); + var_7 = ( 0, 0, 0 ); if ( !isdefined( var_1 ) && !isdefined( var_0 ) ) { @@ -2391,7 +2391,7 @@ callback_playerlaststand( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 var_11.iconname = level.specialty_finalstand_icon; } - var_11.glowcolor = ( 1.0, 0.0, 0.0 ); + var_11.glowcolor = ( 1, 0, 0 ); var_11.sound = "mp_last_stand"; var_11.duration = 2.0; self.health = 1; @@ -2573,14 +2573,14 @@ laststandtimer( var_0, var_1 ) } wait(var_0 / 3); - var_3.color = ( 1.0, 0.64, 0.0 ); + var_3.color = ( 1, 0.64, 0 ); while ( var_2.inuse ) wait 0.05; maps\mp\_utility::playdeathsound(); wait(var_0 / 3); - var_3.color = ( 1.0, 0.0, 0.0 ); + var_3.color = ( 1, 0, 0 ); while ( var_2.inuse ) wait 0.05; @@ -2731,29 +2731,29 @@ gethitlocheight( var_0 ) { switch ( var_0 ) { - case "head": - case "helmet": case "neck": + case "helmet": + case "head": return 60; - case "gun": - case "torso_upper": - case "right_arm_upper": - case "left_arm_upper": - case "right_arm_lower": - case "left_arm_lower": - case "right_hand": case "left_hand": + case "right_hand": + case "left_arm_lower": + case "right_arm_lower": + case "left_arm_upper": + case "right_arm_upper": + case "torso_upper": + case "gun": return 48; case "torso_lower": return 40; - case "right_leg_upper": case "left_leg_upper": + case "right_leg_upper": return 32; - case "right_leg_lower": case "left_leg_lower": + case "right_leg_lower": return 10; - case "right_foot": case "left_foot": + case "right_foot": return 5; } @@ -3058,7 +3058,7 @@ reviveholdthink_cleanup( var_0, var_1, var_2 ) { common_scripts\utility::waittill_any_ents( self, "death", var_2, "death" ); - if ( !_func_294( var_2 ) ) + if ( !isremovedentity( var_2 ) ) var_2 delete(); if ( isdefined( var_0 ) && maps\mp\_utility::isreallyalive( var_0 ) ) @@ -3240,17 +3240,17 @@ _obituary( var_0, var_1, var_2, var_3 ) if ( var_7 == "spectator" ) { - var_6 _meth_826E( &"MP_OBITUARY_NEUTRAL", var_1.name, var_0.name ); + var_6 iprintln( &"MP_OBITUARY_NEUTRAL", var_1.name, var_0.name ); continue; } if ( var_7 == var_4 ) { - var_6 _meth_826E( &"MP_OBITUARY_ENEMY", var_1.name, var_0.name ); + var_6 iprintln( &"MP_OBITUARY_ENEMY", var_1.name, var_0.name ); continue; } - var_6 _meth_826E( &"MP_OBITUARY_FRIENDLY", var_1.name, var_0.name ); + var_6 iprintln( &"MP_OBITUARY_FRIENDLY", var_1.name, var_0.name ); } } @@ -3358,10 +3358,10 @@ processdamagetaken( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_ switch ( var_13 ) { - case "paint_grenade_mp": - case "smoke_grenade_mp": - case "paint_grenade_var_mp": case "smoke_grenade_var_mp": + case "paint_grenade_var_mp": + case "smoke_grenade_mp": + case "paint_grenade_mp": return; } @@ -3467,23 +3467,23 @@ handlemissiledamage( var_0, var_1, var_2 ) switch ( var_0 ) { - case "bomb_site_mp": - case "remotemissile_projectile_mp": - case "remotemissile_projectile_cluster_parent_mp": - case "remotemissile_projectile_gas_mp": - case "orbital_carepackage_pod_mp": - case "orbital_carepackage_droppod_mp": - case "stinger_mp": - case "stealth_bomb_mp": - case "orbital_carepackage_pod_plane_mp": - case "remotemissile_projectile_cluster_child_mp": - case "dam_turret_mp": - case "warbird_missile_mp": - case "remotemissile_projectile_cluster_child_hellfire_mp": - case "remotemissile_projectile_secondary_mp": - case "airstrike_missile_mp": - case "orbitalsupport_105mm_mp": case "orbitalsupport_missile_mp": + case "orbitalsupport_105mm_mp": + case "airstrike_missile_mp": + case "remotemissile_projectile_secondary_mp": + case "remotemissile_projectile_cluster_child_hellfire_mp": + case "warbird_missile_mp": + case "dam_turret_mp": + case "remotemissile_projectile_cluster_child_mp": + case "orbital_carepackage_pod_plane_mp": + case "stealth_bomb_mp": + case "stinger_mp": + case "orbital_carepackage_droppod_mp": + case "orbital_carepackage_pod_mp": + case "remotemissile_projectile_gas_mp": + case "remotemissile_projectile_cluster_parent_mp": + case "remotemissile_projectile_mp": + case "bomb_site_mp": self.largeprojectiledamage = 1; var_3 = self.maxhealth + 1; break; @@ -3504,16 +3504,16 @@ handlemissiledamage( var_0, var_1, var_2 ) var_3 = self.maxhealth * var_5; break; - case "turretheadrocket_mp": - case "ugv_missile_mp": - case "assaultdrone_c4_mp": - case "killstreakmahem_mp": case "killstreak_orbital_laser_mp": + case "killstreakmahem_mp": + case "assaultdrone_c4_mp": + case "ugv_missile_mp": + case "turretheadrocket_mp": self.largeprojectiledamage = 0; var_3 = self.maxhealth + 1; break; - case "orbitalsupport_40mm_mp": case "orbitalsupport_40mmbuddy_mp": + case "orbitalsupport_40mm_mp": self.largeprojectiledamage = 0; var_3 *= 2; break; @@ -3535,9 +3535,9 @@ handlegrenadedamage( var_0, var_1, var_2 ) { switch ( var_3 ) { - case "frag_grenade_mp": - case "semtex_mp": case "explosive_drone_mp": + case "semtex_mp": + case "frag_grenade_mp": var_2 *= 4; break; default: @@ -3600,7 +3600,7 @@ onkillstreakkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 ) if ( var_0 == self.owner ) return; - if ( !_func_285( self.owner, var_0 ) ) + if ( !isalliedsentient( self.owner, var_0 ) ) var_8 = var_0; } diff --git a/data/maps/mp/gametypes/_gamelogic.gsc b/data/maps/mp/gametypes/_gamelogic.gsc index dea374c..05384fb 100644 --- a/data/maps/mp/gametypes/_gamelogic.gsc +++ b/data/maps/mp/gametypes/_gamelogic.gsc @@ -1,5 +1,5 @@ // S1 GSC SOURCE -// Decompiled by https://github.com/xensik/gsc-tool +// Dumped by https://github.com/xensik/gsc-tool onforfeit( var_0 ) { @@ -445,7 +445,7 @@ waittillfinalkillcamdone() timelimitclock_intermission( var_0 ) { setgameendtime( gettime() + int( var_0 * 1000 ) ); - var_1 = spawn( "script_origin", ( 0.0, 0.0, 0.0 ) ); + var_1 = spawn( "script_origin", ( 0, 0, 0 ) ); var_1 hide(); if ( var_0 >= 10.0 ) @@ -527,7 +527,7 @@ graceperiod() if ( !isdefined( game["clientActive"] ) ) { - while ( getplaylistid() == 0 ) + while ( getactiveclientcount() == 0 ) wait 0.05; game["clientActive"] = 1; @@ -675,8 +675,8 @@ updatewinstats( var_0 ) var_0 maps\mp\gametypes\_missions::processchallenge( "ch_gun_crushing" ); break; - case "ctf": case "twar": + case "ctf": if ( game["shut_out"][var_0.team] ) var_0 maps\mp\gametypes\_missions::processchallenge( "ch_" + level.gametype + "_crushing" ); @@ -723,13 +723,13 @@ checkgameendchallenges() { case "_a": var_4 maps\mp\gametypes\_missions::processchallenge( "ch_dom_alphalock" ); - continue; + break; case "_b": var_4 maps\mp\gametypes\_missions::processchallenge( "ch_dom_bravolock" ); - continue; + break; case "_c": var_4 maps\mp\gametypes\_missions::processchallenge( "ch_dom_charlielock" ); - continue; + break; } } } @@ -897,7 +897,7 @@ updatematchbonusscores( var_0 ) } if ( var_1 != "tie" ) - clientannouncement( var_1 ); + setwinningteam( var_1 ); foreach ( var_4 in level.players ) { @@ -1024,7 +1024,7 @@ setxenonranks( var_0 ) if ( maps\mp\_utility::getminutespassed() ) var_4 = var_3.score / maps\mp\_utility::getminutespassed(); - _func_173( var_3, var_3.clientid, int( var_4 ) ); + setplayerteamrank( var_3, var_3.clientid, int( var_4 ) ); } } @@ -1059,7 +1059,7 @@ checktimelimit( var_0 ) return; if ( maps\mp\_utility::gettimepassedpercentage() > level.timepercentagecutoff ) - setnojipscore( 1 ); + setnojiptime( 1 ); var_1 = gettimeremaining(); @@ -1625,12 +1625,12 @@ callback_startgametype() game["strings"]["cowards_way"] = &"PLATFORM_COWARDS_WAY_OUT"; game["colors"]["blue"] = ( 0.25, 0.25, 0.75 ); game["colors"]["red"] = ( 0.75, 0.25, 0.25 ); - game["colors"]["white"] = ( 1.0, 1.0, 1.0 ); - game["colors"]["black"] = ( 0.0, 0.0, 0.0 ); + game["colors"]["white"] = ( 1, 1, 1 ); + game["colors"]["black"] = ( 0, 0, 0 ); game["colors"]["grey"] = ( 0.5, 0.5, 0.5 ); game["colors"]["green"] = ( 0.25, 0.75, 0.25 ); - game["colors"]["yellow"] = ( 0.65, 0.65, 0.0 ); - game["colors"]["orange"] = ( 1.0, 0.45, 0.0 ); + game["colors"]["yellow"] = ( 0.65, 0.65, 0 ); + game["colors"]["orange"] = ( 1, 0.45, 0 ); game["colors"]["cyan"] = ( 0.35, 0.7, 0.9 ); game["strings"]["allies_name"] = maps\mp\gametypes\_teams::getteamname( "allies" ); game["icons"]["allies"] = maps\mp\gametypes\_teams::getteamicon( "allies" ); @@ -1639,10 +1639,10 @@ callback_startgametype() game["icons"]["axis"] = maps\mp\gametypes\_teams::getteamicon( "axis" ); game["colors"]["axis"] = maps\mp\gametypes\_teams::getteamcolor( "axis" ); - if ( game["colors"]["allies"] == ( 0.0, 0.0, 0.0 ) ) + if ( game["colors"]["allies"] == ( 0, 0, 0 ) ) game["colors"]["allies"] = ( 0.5, 0.5, 0.5 ); - if ( game["colors"]["axis"] == ( 0.0, 0.0, 0.0 ) ) + if ( game["colors"]["axis"] == ( 0, 0, 0 ) ) game["colors"]["axis"] = ( 0.5, 0.5, 0.5 ); [[ level.onprecachegametype ]](); @@ -1652,7 +1652,7 @@ callback_startgametype() { if ( !level.splitscreen ) { - if ( _func_27A() ) + if ( isdedicatedserver() ) level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "graceperiod_ds" ); else level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "graceperiod" ); @@ -1662,7 +1662,7 @@ callback_startgametype() } else { - if ( _func_27A() ) + if ( isdedicatedserver() ) level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "playerwaittime_ds" ); else level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "playerwaittime" ); @@ -1910,7 +1910,7 @@ setattackingteam() callback_codeendgame() { - setplayerteamrank(); + endparty(); if ( !level.gameended ) level thread forceend(); @@ -1921,13 +1921,13 @@ verifydedicatedconfiguration() for (;;) { if ( level.rankedmatch ) - _func_16A( 0 ); + exitlevel( 0 ); if ( !getdvarint( "xblive_privatematch" ) ) - _func_16A( 0 ); + exitlevel( 0 ); if ( getdvar( "dedicated" ) != "dedicated LAN server" && getdvar( "dedicated" ) != "dedicated internet server" ) - _func_16A( 0 ); + exitlevel( 0 ); wait 5; } @@ -2018,7 +2018,7 @@ timelimitclock() { level endon( "game_ended" ); wait 0.05; - var_0 = spawn( "script_origin", ( 0.0, 0.0, 0.0 ) ); + var_0 = spawn( "script_origin", ( 0, 0, 0 ) ); var_0 hide(); while ( game["state"] == "playing" ) @@ -2133,7 +2133,7 @@ startgame() if ( var_0 || var_1 ) thread updategameduration(); - _func_240(); + lootserviceonstartgame(); } wavespawntimer() @@ -2438,7 +2438,7 @@ endgameovertime( var_0, var_1 ) level notify( "restarting" ); game["state"] = "playing"; setdvar( "ui_game_state", game["state"] ); - _func_169( 1 ); + map_restart( 1 ); } endgamehalftime( var_0 ) @@ -2519,7 +2519,7 @@ endgamehalftime( var_0 ) level notify( "restarting" ); game["state"] = "playing"; setdvar( "ui_game_state", game["state"] ); - _func_169( 1 ); + map_restart( 1 ); } updategameduration() @@ -2652,7 +2652,7 @@ endgame( var_0, var_1, var_2 ) level notify( "restarting" ); game["state"] = "playing"; setdvar( "ui_game_state", "playing" ); - _func_169( 1 ); + map_restart( 1 ); return; } @@ -2717,7 +2717,7 @@ endgame( var_0, var_1, var_2 ) setmatchdata( "alliesScore", game["teamScores"]["allies"] ); setmatchdata( "axisScore", game["teamScores"]["axis"] ); - _func_242( var_0 ); + tournamentreportwinningteam( var_0 ); } else setmatchdata( "victor", "none" ); @@ -2736,9 +2736,9 @@ endgame( var_0, var_1, var_2 ) if ( maps\mp\_utility::matchmakinggame() ) { - setmatchdata( "playlistVersion", isdedicatedserver() ); - setmatchdata( "playlistID", getplaylistversion() ); - setmatchdata( "isDedicated", _func_27A() ); + setmatchdata( "playlistVersion", getplaylistversion() ); + setmatchdata( "playlistID", getplaylistid() ); + setmatchdata( "isDedicated", isdedicatedserver() ); } setmatchdata( "levelMaxClients", level.maxclients ); @@ -2750,7 +2750,7 @@ endgame( var_0, var_1, var_2 ) var_5.pers["segments"] = var_5.segments; } - tournamentreportwinningteam(); + tournamentreportendofgame(); var_20 = 0; if ( maps\mp\_utility::practiceroundgame() ) @@ -2909,7 +2909,7 @@ endgame( var_0, var_1, var_2 ) } level notify( "exitLevel_called" ); - _func_16A( 0 ); + exitlevel( 0 ); } getgamewinner( var_0, var_1 ) @@ -2975,7 +2975,7 @@ getscoreperminute( var_0 ) if ( isplayer( self ) ) var_4 = self.score / var_3; else - var_4 = setclientnamemode( var_0 ) / var_3; + var_4 = getteamscore( var_0 ) / var_3; return var_4; } @@ -2987,7 +2987,7 @@ getscoreremaining( var_0 ) if ( isplayer( self ) ) var_2 = var_1 - self.score; else - var_2 = var_1 - setclientnamemode( var_0 ); + var_2 = var_1 - getteamscore( var_0 ); return var_2; } @@ -3039,7 +3039,7 @@ processlobbydata() maps\mp\_awards::assignawards(); maps\mp\_scoreboard::processlobbyscoreboards(); sendclientmatchdata(); - _func_23E(); + lootserviceonendgame(); } trackleaderboarddeathstats( var_0, var_1 ) diff --git a/data/maps/mp/gametypes/_playerlogic.gsc b/data/maps/mp/gametypes/_playerlogic.gsc index 7e7fba4..bf1c9e7 100644 --- a/data/maps/mp/gametypes/_playerlogic.gsc +++ b/data/maps/mp/gametypes/_playerlogic.gsc @@ -1,5 +1,5 @@ // S1 GSC SOURCE -// Decompiled by https://github.com/xensik/gsc-tool +// Dumped by https://github.com/xensik/gsc-tool timeuntilwavespawn( var_0 ) { @@ -419,7 +419,7 @@ showspawnnotifies() getspawnorigin( var_0 ) { - if ( !getstarttime( var_0.origin ) ) + if ( !positionwouldtelefrag( var_0.origin ) ) return var_0.origin; if ( !isdefined( var_0.alternates ) ) @@ -427,7 +427,7 @@ getspawnorigin( var_0 ) foreach ( var_2 in var_0.alternates ) { - if ( !getstarttime( var_2 ) ) + if ( !positionwouldtelefrag( var_2 ) ) return var_2; } @@ -619,7 +619,7 @@ spawnplayer( var_0, var_1 ) foreach ( var_11 in level.ugvs ) { if ( distancesquared( var_11.origin, var_2.playerspawnpos ) < 1024 ) - var_11 notify( "damage", 5000, var_11.owner, ( 0.0, 0.0, 0.0 ), ( 0.0, 0.0, 0.0 ), "MOD_EXPLOSIVE", "", "", "", undefined, "killstreak_emp_mp" ); + var_11 notify( "damage", 5000, var_11.owner, ( 0, 0, 0 ), ( 0, 0, 0 ), "MOD_EXPLOSIVE", "", "", "", undefined, "killstreak_emp_mp" ); } var_5 = self.setspawnpoint.playerspawnpos; @@ -825,7 +825,7 @@ spawnplayer( var_0, var_1 ) var_17 = self.pers["team"]; if ( maps\mp\_utility::inovertime() ) - thread maps\mp\gametypes\_hud_message::oldnotifymessage( game["strings"]["overtime"], game["strings"]["overtime_hint"], undefined, ( 1.0, 0.0, 0.0 ), "mp_last_stand" ); + thread maps\mp\gametypes\_hud_message::oldnotifymessage( game["strings"]["overtime"], game["strings"]["overtime_hint"], undefined, ( 1, 0, 0 ), "mp_last_stand" ); thread showspawnnotifies(); } @@ -1169,15 +1169,13 @@ callback_playerdisconnect( var_0 ) if ( maps\mp\_utility::getminutespassed() ) var_4 = self.score / maps\mp\_utility::getminutespassed(); - _func_173( self, self.clientid, int( var_4 ) ); + setplayerteamrank( self, self.clientid, int( var_4 ) ); } reconevent( "script_mp_playerquit: player_name %s, player %d, gameTime %d", self.name, self.clientid, gettime() ); var_5 = self getentitynumber(); var_6 = self.guid; - var_7 = "Q;" + var_6 + ";" + var_5 + ";" + self.name + "\n"; - - logprint( var_7 ); + logprint( "Q;" + var_6 + ";" + var_5 + ";" + self.name + "\n" ); thread maps\mp\_events::disconnected(); if ( level.gameended ) @@ -1283,7 +1281,7 @@ setupsavedactionslots() logplayerconsoleidandonwifiinmatchdata() { - var_0 = _func_2CE(); + var_0 = getcodanywherecurrentplatform(); var_1 = self getcommonplayerdata( "consoleIDChunkLow", var_0 ); var_2 = self getcommonplayerdata( "consoleIDChunkHigh", var_0 ); @@ -1426,7 +1424,7 @@ callback_playerconnect() setmatchdata( "players", self.clientid, "isBot", isai( self ) ); var_4 = self getentitynumber(); setmatchdata( "players", self.clientid, "codeClientNum", maps\mp\_utility::clamptobyte( var_4 ) ); - var_5 = _func_2CE(); + var_5 = getcodanywherecurrentplatform(); var_3 = self getcommonplayerdata( "connectionIDChunkLow", var_5 ); var_2 = self getcommonplayerdata( "connectionIDChunkHigh", var_5 ); setmatchdata( "players", self.clientid, "connectionIDChunkLow", var_3 ); diff --git a/data/maps/mp/gametypes/gun.gsc b/data/maps/mp/gametypes/gun.gsc index 0f18236..0c90a28 100644 --- a/data/maps/mp/gametypes/gun.gsc +++ b/data/maps/mp/gametypes/gun.gsc @@ -1,5 +1,5 @@ // S1 GSC SOURCE -// Decompiled by https://github.com/xensik/gsc-tool +// Dumped by https://github.com/xensik/gsc-tool main() { @@ -7,10 +7,8 @@ main() maps\mp\gametypes\_callbacksetup::setupcallbacks(); maps\mp\gametypes\_globallogic::setupcallbacks(); setguns(); - - maps\mp\_utility::registertimelimitdvar( level.gametype, 10 ); - setDvar( "scr_gun_scorelimit", level.gun_guns.size ); + setdvar( "scr_gun_scorelimit", level.gun_guns.size ); maps\mp\_utility::registerscorelimitdvar( level.gametype, level.gun_guns.size ); level thread reinitializescorelimitonmigration(); maps\mp\_utility::registerroundlimitdvar( level.gametype, 1 ); @@ -38,7 +36,7 @@ main() if ( level.matchrules_damagemultiplier ) level.modifyplayerdamage = maps\mp\gametypes\_damage::gamemodemodifyplayerdamage; - setteamscore( "ffa" ); + setteammode( "ffa" ); game["dialog"]["gametype"] = "gg_intro"; game["dialog"]["defense_obj"] = "gbl_start"; game["dialog"]["offense_obj"] = "gbl_start"; @@ -53,40 +51,38 @@ initializematchrules() { maps\mp\_utility::setcommonrulesfrommatchrulesdata( 1 ); level.matchrules_randomize = getmatchrulesdata( "gunData", "randomize" ); - setDvar( "scr_gun_scorelimit", level.gun_guns.size ); + setdvar( "scr_gun_scorelimit", level.gun_guns.size ); maps\mp\_utility::registerscorelimitdvar( level.gametype, level.gun_guns.size ); - setDvar( "scr_gun_winlimit", 1 ); + setdvar( "scr_gun_winlimit", 1 ); maps\mp\_utility::registerwinlimitdvar( "gun", 1 ); - setDvar( "scr_gun_roundlimit", 1 ); + setdvar( "scr_gun_roundlimit", 1 ); maps\mp\_utility::registerroundlimitdvar( "gun", 1 ); - setDvar( "scr_gun_halftime", 0 ); + setdvar( "scr_gun_halftime", 0 ); maps\mp\_utility::registerhalftimedvar( "gun", 0 ); - setDvar( "scr_gun_playerrespawndelay", 0 ); - setDvar( "scr_gun_waverespawndelay", 0 ); - setDvar( "scr_player_forcerespawn", 1 ); - setDvar( "scr_setback_levels", getmatchrulesdata( "gunData", "setbackLevels" ) ); + setdvar( "scr_gun_playerrespawndelay", 0 ); + setdvar( "scr_gun_waverespawndelay", 0 ); + setdvar( "scr_player_forcerespawn", 1 ); + setdvar( "scr_setback_levels", getmatchrulesdata( "gunData", "setbackLevels" ) ); } reinitializescorelimitonmigration() { - setDvar( "scr_gun_scorelimit", level.gun_guns.size ); + setdvar( "scr_gun_scorelimit", level.gun_guns.size ); maps\mp\_utility::registerscorelimitdvar( level.gametype, level.gun_guns.size ); } onstartgametype() { - getteamplayersalive( "auto_change" ); + setclientnamemode( "auto_change" ); maps\mp\_utility::setobjectivetext( "allies", &"OBJECTIVES_DM" ); maps\mp\_utility::setobjectivetext( "axis", &"OBJECTIVES_DM" ); - maps\mp\_utility::setobjectivescoretext( "allies", &"OBJECTIVES_DM_SCORE" ); maps\mp\_utility::setobjectivescoretext( "axis", &"OBJECTIVES_DM_SCORE" ); - maps\mp\_utility::setobjectivehinttext( "allies", &"OBJECTIVES_DM_HINT" ); maps\mp\_utility::setobjectivehinttext( "axis", &"OBJECTIVES_DM_HINT" ); initspawns(); - allowed = []; - maps\mp\gametypes\_gameobjects::main( allowed ); + var_0 = []; + maps\mp\gametypes\_gameobjects::main( var_0 ); level.quickmessagetoall = 1; level.blockweapondrops = 1; level thread onplayerconnect(); @@ -94,8 +90,8 @@ onstartgametype() initspawns() { - level.spawnmins = ( 0.0, 0.0, 0.0 ); - level.spawnmaxs = ( 0.0, 0.0, 0.0 ); + level.spawnmins = ( 0, 0, 0 ); + level.spawnmaxs = ( 0, 0, 0 ); level.spawn_name = "mp_dm_spawn"; maps\mp\gametypes\_spawnlogic::addspawnpoints( "allies", level.spawn_name ); maps\mp\gametypes\_spawnlogic::addspawnpoints( "axis", level.spawn_name ); @@ -199,17 +195,17 @@ onplayerscore( var_0, var_1, var_2 ) return 0; } -onplayerkilled( var_0, attacker, var_2, sMeansOfDeath, sWeapon, var_5, var_6, var_7, var_8, var_9 ) +onplayerkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) { - if ( !isdefined( attacker ) ) + if ( !isdefined( var_1 ) ) return; - if ( sMeansOfDeath == "MOD_TRIGGER_HURT" && !isplayer( attacker ) ) - attacker = self; + if ( var_3 == "MOD_TRIGGER_HURT" && !isplayer( var_1 ) ) + var_1 = self; - if ( sMeansOfDeath == "MOD_FALLING" || isplayer( attacker ) ) + if ( var_3 == "MOD_FALLING" || isplayer( var_1 ) ) { - if ( sMeansOfDeath == "MOD_FALLING" || attacker == self || maps\mp\_utility::ismeleemod( sMeansOfDeath ) && sWeapon != "riotshield_mp" || sWeapon == "boost_slam_mp" || sWeapon == "iw5_dlcgun12loot8_mp" ) + if ( var_3 == "MOD_FALLING" || var_1 == self || maps\mp\_utility::ismeleemod( var_3 ) && var_4 != "riotshield_mp" || var_4 == "boost_slam_mp" || var_4 == "iw5_dlcgun12loot8_mp" ) { self playlocalsound( "mp_war_objective_lost" ); self.gungameprevgunindex = self.gungamegunindex; @@ -222,53 +218,49 @@ onplayerkilled( var_0, attacker, var_2, sMeansOfDeath, sWeapon, var_5, var_6, va maps\mp\_utility::setextrascore1( self.mysetbacks ); self.showsetbacksplash = 1; - if ( maps\mp\_utility::ismeleemod( sMeansOfDeath ) || sWeapon == "boost_slam_mp" || sWeapon == "iw5_dlcgun12loot8_mp" ) + if ( maps\mp\_utility::ismeleemod( var_3 ) || var_4 == "boost_slam_mp" || var_4 == "iw5_dlcgun12loot8_mp" ) { - attacker.stabs++; - attacker.assists = attacker.stabs; - attacker thread maps\mp\_events::setbackenemygunlevelevent(); + var_1.stabs++; + var_1.assists = var_1.stabs; + var_1 thread maps\mp\_events::setbackenemygunlevelevent(); if ( self.gungameprevgunindex == level.gun_guns.size - 1 ) { - attacker thread maps\mp\_events::setbackfirstplayergunlevelevent(); - attacker maps\mp\_utility::leaderdialogonplayer( "humiliation", "status" ); + var_1 thread maps\mp\_events::setbackfirstplayergunlevelevent(); + var_1 maps\mp\_utility::leaderdialogonplayer( "humiliation", "status" ); } } } } - else if ( sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" || sMeansOfDeath == "MOD_HEAD_SHOT" || sMeansOfDeath == "MOD_PROJECTILE" || sMeansOfDeath == "MOD_PROJECTILE_SPLASH" || sMeansOfDeath == "MOD_EXPLOSIVE" || sMeansOfDeath == "MOD_IMPACT" || sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" || maps\mp\_utility::ismeleemod( sMeansOfDeath ) && sWeapon == "riotshield_mp" ) + else if ( var_3 == "MOD_PISTOL_BULLET" || var_3 == "MOD_RIFLE_BULLET" || var_3 == "MOD_HEAD_SHOT" || var_3 == "MOD_PROJECTILE" || var_3 == "MOD_PROJECTILE_SPLASH" || var_3 == "MOD_EXPLOSIVE" || var_3 == "MOD_IMPACT" || var_3 == "MOD_GRENADE" || var_3 == "MOD_GRENADE_SPLASH" || maps\mp\_utility::ismeleemod( var_3 ) && var_4 == "riotshield_mp" ) { - if ( isdefined( attacker.lastkillweapon ) && attacker.lastkillweapon == sWeapon ) - { + if ( isdefined( var_1.lastkillweapon ) && var_1.lastkillweapon == var_4 ) return; - } var_10 = level.gun_guns; if ( level.matchrules_randomize ) - var_10 = attacker.gunlist; + var_10 = var_1.gunlist; - var_11 = var_10[attacker.gungamegunindex]; + var_11 = var_10[var_1.gungamegunindex]; - if ( !issubstr( sWeapon, maps\mp\_utility::getbaseweaponname( var_11 ) ) ) - { + if ( !issubstr( var_4, maps\mp\_utility::getbaseweaponname( var_11 ) ) ) return; - } - attacker.lastkillweapon = sWeapon; + var_1.lastkillweapon = var_4; - if ( attacker.lastleveluptime + 3000 > gettime() ) - attacker thread maps\mp\_events::quickgunlevelevent(); + if ( var_1.lastleveluptime + 3000 > gettime() ) + var_1 thread maps\mp\_events::quickgunlevelevent(); - attacker.lastleveluptime = gettime(); - attacker.gungameprevgunindex = attacker.gungamegunindex; - attacker.gungamegunindex++; - attacker thread maps\mp\_events::increasegunlevelevent(); + var_1.lastleveluptime = gettime(); + var_1.gungameprevgunindex = var_1.gungamegunindex; + var_1.gungamegunindex++; + var_1 thread maps\mp\_events::increasegunlevelevent(); - if ( attacker.gungamegunindex == level.gun_guns.size - 1 ) + if ( var_1.gungamegunindex == level.gun_guns.size - 1 ) { maps\mp\_utility::playsoundonplayers( "mp_enemy_obj_captured" ); - level thread maps\mp\_utility::teamplayercardsplash( "callout_top_gun_rank", attacker ); + level thread maps\mp\_utility::teamplayercardsplash( "callout_top_gun_rank", var_1 ); var_12 = gettime(); if ( level.lastguntimevo + 4500 < var_12 ) @@ -278,8 +270,8 @@ onplayerkilled( var_0, attacker, var_2, sMeansOfDeath, sWeapon, var_5, var_6, va } } - if ( attacker.gungamegunindex < level.gun_guns.size ) - attacker givenextgun( 0, sWeapon ); + if ( var_1.gungamegunindex < level.gun_guns.size ) + var_1 givenextgun( 0, var_4 ); } } } @@ -292,9 +284,7 @@ givenextgun( var_0, var_1 ) var_2 = addattachments( var_2 ); while ( !self loadweapons( var_2 ) ) - { waitframe(); - } if ( isdefined( var_1 ) ) self takeweapon( var_1 ); @@ -319,13 +309,13 @@ getnextgun() { var_0 = level.gun_guns; var_1 = []; - newWeapon = undefined; + var_2 = undefined; if ( level.matchrules_randomize ) var_0 = self.gunlist; - newWeapon = var_0[self.gungamegunindex]; - var_1[var_1.size] = newWeapon; + var_2 = var_0[self.gungamegunindex]; + var_1[var_1.size] = var_2; if ( self.gungamegunindex + 1 < var_0.size ) var_1[var_1.size] = var_0[self.gungamegunindex + 1]; @@ -334,22 +324,22 @@ getnextgun() var_1[var_1.size] = var_0[self.gungamegunindex - 1]; self loadweapons( var_1 ); - return newWeapon; + return var_2; } -addattachments( weaponName ) +addattachments( var_0 ) { if ( getdvarint( "scr_gun_loot_variants", 0 ) == 1 ) { - var_1 = tablelookup( "mp/statstable.csv", 4, weaponName , 40 ); + var_1 = tablelookup( "mp/statstable.csv", 4, var_0, 40 ); if ( isdefined( var_1 ) && var_1 != "" ) - var_2 = maps\mp\gametypes\_class::buildweaponname( weaponName , var_1, "none", "none", 0, 0 ); + var_2 = maps\mp\gametypes\_class::buildweaponname( var_0, var_1, "none", "none", 0, 0 ); else - var_2 = maps\mp\gametypes\_class::buildweaponname( weaponName , "none", "none", "none", 0, 0 ); + var_2 = maps\mp\gametypes\_class::buildweaponname( var_0, "none", "none", "none", 0, 0 ); } else - var_2 = maps\mp\gametypes\_class::buildweaponname( weaponName , "none", "none", "none", 0, 0 ); + var_2 = maps\mp\gametypes\_class::buildweaponname( var_0, "none", "none", "none", 0, 0 ); return var_2; } @@ -357,14 +347,14 @@ addattachments( weaponName ) ontimelimit() { level.finalkillcam_winner = "none"; - winners = gethighestprogressedplayers(); + var_0 = gethighestprogressedplayers(); - if ( !isdefined( winners ) || !winners.size ) + if ( !isdefined( var_0 ) || !var_0.size ) thread maps\mp\gametypes\_gamelogic::endgame( "tie", game["end_reason"]["time_limit_reached"] ); - else if ( winners.size == 1 ) - thread maps\mp\gametypes\_gamelogic::endgame( winners[0], game["end_reason"]["time_limit_reached"] ); - else if ( winners[winners.size - 1].gungamegunindex > winners[winners.size - 2].gungamegunindex ) - thread maps\mp\gametypes\_gamelogic::endgame( winners[winners.size - 1], game["end_reason"]["time_limit_reached"] ); + else if ( var_0.size == 1 ) + thread maps\mp\gametypes\_gamelogic::endgame( var_0[0], game["end_reason"]["time_limit_reached"] ); + else if ( var_0[var_0.size - 1].gungamegunindex > var_0[var_0.size - 2].gungamegunindex ) + thread maps\mp\gametypes\_gamelogic::endgame( var_0[var_0.size - 1], game["end_reason"]["time_limit_reached"] ); else thread maps\mp\gametypes\_gamelogic::endgame( "tie", game["end_reason"]["time_limit_reached"] ); } diff --git a/deps/extra/gsc-tool/gsc_interface.cpp b/deps/extra/gsc-tool/gsc_interface.cpp new file mode 100644 index 0000000..b4579fe --- /dev/null +++ b/deps/extra/gsc-tool/gsc_interface.cpp @@ -0,0 +1,6 @@ +#include "gsc_interface.hpp" + +namespace gsc +{ + std::unique_ptr cxt; +} diff --git a/deps/extra/gsc-tool/gsc_interface.hpp b/deps/extra/gsc-tool/gsc_interface.hpp new file mode 100644 index 0000000..9723f04 --- /dev/null +++ b/deps/extra/gsc-tool/gsc_interface.hpp @@ -0,0 +1,15 @@ +#pragma once +#undef ERROR +#undef IN +#undef TRUE +#undef FALSE + +#undef far + +#include +#include + +namespace gsc +{ + extern std::unique_ptr cxt; +} diff --git a/deps/extra/gsc-tool/interface.cpp b/deps/extra/gsc-tool/interface.cpp deleted file mode 100644 index 4e224a6..0000000 --- a/deps/extra/gsc-tool/interface.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include "interface.hpp" - -namespace gsc -{ - std::unique_ptr compiler() - { - auto compiler = std::make_unique(); - compiler->mode(xsk::gsc::build::prod); - return compiler; - } - - std::unique_ptr decompiler() - { - return std::make_unique(); - } - - std::unique_ptr assembler() - { - return std::make_unique(); - } - - std::unique_ptr disassembler() - { - return std::make_unique(); - } -} diff --git a/deps/extra/gsc-tool/interface.hpp b/deps/extra/gsc-tool/interface.hpp deleted file mode 100644 index 133e6ae..0000000 --- a/deps/extra/gsc-tool/interface.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace gsc -{ - std::unique_ptr compiler(); - std::unique_ptr decompiler(); - std::unique_ptr assembler(); - std::unique_ptr disassembler(); -} diff --git a/deps/fmt b/deps/fmt new file mode 160000 index 0000000..05e3a92 --- /dev/null +++ b/deps/fmt @@ -0,0 +1 @@ +Subproject commit 05e3a9233ac1dd0c2d9643e046dbb5f788c39f61 diff --git a/deps/gsc-tool b/deps/gsc-tool index 7d37402..b3ac7d2 160000 --- a/deps/gsc-tool +++ b/deps/gsc-tool @@ -1 +1 @@ -Subproject commit 7d374025b7675bada64c247ebe9378dd335a33da +Subproject commit b3ac7d2562e41a0cf821e39baa96b80c02b6ba9c diff --git a/deps/premake/fmt.lua b/deps/premake/fmt.lua new file mode 100644 index 0000000..905bbf7 --- /dev/null +++ b/deps/premake/fmt.lua @@ -0,0 +1,34 @@ +fmt = { + source = path.join(dependencies.basePath, "fmt"), +} + +function fmt.import() + links { "fmt" } + + fmt.includes() +end + +function fmt.includes() + includedirs { + path.join(fmt.source, "include"), + } +end + +function fmt.project() + project "fmt" + kind "StaticLib" + language "C++" + + fmt.includes() + + files { + path.join(fmt.source, "include/fmt/*.h"), + path.join(fmt.source, "src/*.cc") + } + + removefiles { + path.join(fmt.source, "src/fmt.cc") + } +end + +table.insert(dependencies, fmt) diff --git a/deps/premake/gsc-tool.lua b/deps/premake/gsc-tool.lua index 325a64d..50530e2 100644 --- a/deps/premake/gsc-tool.lua +++ b/deps/premake/gsc-tool.lua @@ -11,6 +11,9 @@ function gsc_tool.includes() includedirs { path.join(gsc_tool.source, "s1"), path.join(gsc_tool.source, "utils"), + path.join(gsc_tool.source, "gsc"), + gsc_tool.source, + path.join(dependencies.basePath, "extra/gsc-tool"), } end @@ -20,9 +23,6 @@ function gsc_tool.project() kind "StaticLib" language "C++" - pchheader "stdafx.hpp" - pchsource (path.join(gsc_tool.source, "utils/stdafx.cpp")) - files { path.join(gsc_tool.source, "utils/**.hpp"), path.join(gsc_tool.source, "utils/**.cpp"), @@ -34,23 +34,30 @@ function gsc_tool.project() } zlib.includes() + fmt.includes() project "xsk-gsc-s1" kind "StaticLib" language "C++" filter "action:vs*" - buildoptions "/bigobj" buildoptions "/Zc:__cplusplus" filter {} - pchheader "stdafx.hpp" - pchsource (path.join(gsc_tool.source, "s1/stdafx.cpp")) - files { - path.join(gsc_tool.source, "s1/**.hpp"), - path.join(gsc_tool.source, "s1/**.cpp"), - path.join(dependencies.basePath, "extra/gsc-tool/interface.cpp"), + path.join(gsc_tool.source, "s1/s1_pc.hpp"), + path.join(gsc_tool.source, "s1/s1_pc.cpp"), + path.join(gsc_tool.source, "s1/s1_pc_code.cpp"), + path.join(gsc_tool.source, "s1/s1_pc_func.cpp"), + path.join(gsc_tool.source, "s1/s1_pc_meth.cpp"), + path.join(gsc_tool.source, "s1/s1_pc_token.cpp"), + + path.join(gsc_tool.source, "gsc/misc/*.hpp"), + path.join(gsc_tool.source, "gsc/misc/*.cpp"), + path.join(gsc_tool.source, "gsc/*.hpp"), + path.join(gsc_tool.source, "gsc/*.cpp"), + + path.join(dependencies.basePath, "extra/gsc-tool/gsc_interface.cpp"), } includedirs { @@ -58,6 +65,8 @@ function gsc_tool.project() gsc_tool.source, path.join(dependencies.basePath, "extra/gsc-tool"), } + + fmt.includes() end table.insert(dependencies, gsc_tool) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index ced3be3..f1dfaf0 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -3,12 +3,12 @@ #include "game/game.hpp" #include "console.hpp" -#include "command.hpp" #include "network.hpp" #include "party.hpp" #include "scheduler.hpp" #include +#include #include @@ -18,6 +18,19 @@ namespace discord { DiscordRichPresence discord_presence; + void join_game(const char* join_secret) + { + game::Cbuf_AddText(0, utils::string::va("connect %s\n", join_secret)); + } + + void join_request(const DiscordUser* request) + { +#ifdef _DEBUG + console::info("Discord: Join request from %s (%s)\n", request->username, request->userId); +#endif + Discord_Respond(request->userId, DISCORD_REPLY_IGNORE); + } + void update_discord() { Discord_RunCallbacks(); @@ -70,6 +83,13 @@ namespace discord { discord_presence.state = host_name; discord_presence.partyMax = party::server_client_count(); + + std::hash hash_fn; + static const auto nonce = utils::cryptography::random::get_integer(); + + const auto& address = party::get_target(); + discord_presence.partyId = utils::string::va("%zu", hash_fn(address) ^ nonce); + discord_presence.joinSecret = network::net_adr_to_string(address); } if (!discord_presence.startTimestamp) @@ -101,13 +121,13 @@ namespace discord handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = nullptr; + handlers.joinGame = join_game; handlers.spectateGame = nullptr; - handlers.joinRequest = nullptr; + handlers.joinRequest = join_request; Discord_Initialize("823223724013912124", &handlers, 1, nullptr); - scheduler::once([]() + scheduler::once([] { scheduler::once(update_discord, scheduler::pipeline::async); scheduler::loop(update_discord, scheduler::pipeline::async, 15s); @@ -118,7 +138,7 @@ namespace discord void pre_destroy() override { - if (!initialized_ || game::environment::is_dedi()) + if (!initialized_) { return; } diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index 2a7cd53..7eeebf3 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -38,9 +38,9 @@ namespace fastfiles std::string buffer; buffer.append(header.scriptfile->name, std::strlen(header.scriptfile->name) + 1); - buffer.append(reinterpret_cast(&header.scriptfile->compressedLen), 4); - buffer.append(reinterpret_cast(&header.scriptfile->len), 4); - buffer.append(reinterpret_cast(&header.scriptfile->bytecodeLen), 4); + buffer.append(reinterpret_cast(&header.scriptfile->compressedLen), sizeof(int)); + buffer.append(reinterpret_cast(&header.scriptfile->len), sizeof(int)); + buffer.append(reinterpret_cast(&header.scriptfile->bytecodeLen), sizeof(int)); buffer.append(header.scriptfile->buffer, header.scriptfile->compressedLen); buffer.append(reinterpret_cast(header.scriptfile->bytecode), header.scriptfile->bytecodeLen); diff --git a/src/client/component/game_log.cpp b/src/client/component/game_log.cpp index 69810a3..b205183 100644 --- a/src/client/component/game_log.cpp +++ b/src/client/component/game_log.cpp @@ -70,7 +70,7 @@ namespace game_log class component final : public component_interface { public: - void post_load() override + void post_unpack() override { if (game::environment::is_sp()) { diff --git a/src/client/component/gsc/script_extension.cpp b/src/client/component/gsc/script_extension.cpp index 0a85134..0ddcbd2 100644 --- a/src/client/component/gsc/script_extension.cpp +++ b/src/client/component/gsc/script_extension.cpp @@ -13,8 +13,7 @@ #include -#include -#include +#include namespace gsc { @@ -96,11 +95,11 @@ namespace gsc if (function_id > 0x1000) { - console::warn("in call to builtin method \"%s\"%s", xsk::gsc::s1::resolver::method_name(function_id).data(), error.data()); + console::warn("in call to builtin method \"%s\"%s", gsc::cxt->meth_name(function_id).data(), error.data()); } else { - console::warn("in call to builtin function \"%s\"%s", xsk::gsc::s1::resolver::function_name(function_id).data(), error.data()); + console::warn("in call to builtin function \"%s\"%s", gsc::cxt->func_name(function_id).data(), error.data()); } } @@ -108,7 +107,8 @@ namespace gsc { try { - return {xsk::gsc::s1::resolver::opcode_name(opcode)}; + auto index = gsc::cxt->opcode_enum(opcode); + return {xsk::gsc::opcode_name(index)}; } catch (...) { @@ -232,7 +232,7 @@ namespace gsc void override_function(const std::string& name, game::BuiltinFunction func) { - const auto id = xsk::gsc::s1::resolver::function_id(name); + const auto id = gsc::cxt->func_id(name); builtin_funcs_overrides.emplace(id, func); } @@ -240,7 +240,7 @@ namespace gsc { ++function_id_start; functions[function_id_start] = function; - xsk::gsc::s1::resolver::add_function(name, function_id_start); + gsc::cxt->func_add(name, function_id_start); } class extension final : public component_interface diff --git a/src/client/component/gsc/script_loading.cpp b/src/client/component/gsc/script_loading.cpp index 1b958f1..a18f1a7 100644 --- a/src/client/component/gsc/script_loading.cpp +++ b/src/client/component/gsc/script_loading.cpp @@ -2,8 +2,10 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" -#include +#include #include +#include +#include #include "component/filesystem.hpp" #include "component/console.hpp" @@ -12,37 +14,31 @@ #include "script_loading.hpp" -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace gsc { namespace { - auto compiler = ::gsc::compiler(); - auto decompiler = ::gsc::decompiler(); - auto assembler = ::gsc::assembler(); - auto disassembler = ::gsc::disassembler(); - std::unordered_map main_handles; std::unordered_map init_handles; std::unordered_map loaded_scripts; + std::unordered_map included_scripts; + utils::memory::allocator script_allocator; + + const game::dvar_t* developer_script; void clear() { main_handles.clear(); init_handles.clear(); loaded_scripts.clear(); + included_scripts.clear(); + script_allocator.clear(); } - bool read_script_file(const std::string& name, std::string* data) + bool read_raw_script_file(const std::string& name, std::string* data) { if (filesystem::read_file(name, data)) { @@ -86,18 +82,44 @@ namespace gsc return itr->second; } - std::string source_buffer{}; - if (!read_script_file(real_name + ".gsc", &source_buffer)) - { - return nullptr; - } - - std::vector data; - data.assign(source_buffer.begin(), source_buffer.end()); - try { - compiler->compile(real_name, data); + auto& compiler = gsc::cxt->compiler(); + auto& assembler = gsc::cxt->assembler(); + + std::string source_buffer{}; + if (!read_raw_script_file(real_name + ".gsc", &source_buffer)) + { + return nullptr; + } + + std::vector data; + data.assign(source_buffer.begin(), source_buffer.end()); + + const auto assembly_ptr = compiler.compile(real_name, data); + // Pair of two buffers. First is the byte code and second is the stack + const auto output_script = assembler.assemble(*assembly_ptr); + + const auto script_file_ptr = static_cast(script_allocator.allocate(sizeof(game::ScriptFile))); + script_file_ptr->name = file_name; + + script_file_ptr->len = static_cast(output_script.second.size); + script_file_ptr->bytecodeLen = static_cast(output_script.first.size); + + const auto stack_size = static_cast(output_script.second.size + 1); + const auto byte_code_size = static_cast(output_script.first.size + 1); + + script_file_ptr->buffer = static_cast(script_allocator.allocate(stack_size)); + std::memcpy(const_cast(script_file_ptr->buffer), output_script.second.data, output_script.second.size); + + script_file_ptr->bytecode = static_cast(game::PMem_AllocFromSource_NoDebug(byte_code_size, 4, 1, 5)); + std::memcpy(script_file_ptr->bytecode, output_script.first.data, output_script.first.size); + + script_file_ptr->compressedLen = 0; + + loaded_scripts[real_name] = script_file_ptr; + + return script_file_ptr; } catch (const std::exception& ex) { @@ -106,49 +128,11 @@ namespace gsc console::error("**********************************************\n"); return nullptr; } - - auto assembly = compiler->output(); - - try - { - assembler->assemble(real_name, assembly); - } - catch (const std::exception& ex) - { - console::error("*********** script compile error *************\n"); - console::error("failed to assemble '%s':\n%s", real_name.data(), ex.what()); - console::error("**********************************************\n"); - return nullptr; - } - - const auto script_file_ptr = static_cast(game::Hunk_AllocateTempMemoryHighInternal(sizeof(game::ScriptFile))); - script_file_ptr->name = file_name; - - const auto stack = assembler->output_stack(); - script_file_ptr->len = static_cast(stack.size()); - - const auto script = assembler->output_script(); - script_file_ptr->bytecodeLen = static_cast(script.size()); - - const auto stack_size = static_cast(stack.size() + 1); - const auto byte_code_size = static_cast(script.size() + 1); - - script_file_ptr->buffer = static_cast(game::Hunk_AllocateTempMemoryHighInternal(stack_size)); - std::memcpy(const_cast(script_file_ptr->buffer), stack.data(), stack.size()); - - script_file_ptr->bytecode = static_cast(game::PMem_AllocFromSource_NoDebug(byte_code_size, 4, 1, 5)); - std::memcpy(script_file_ptr->bytecode, script.data(), script.size()); - - script_file_ptr->compressedLen = 0; - - loaded_scripts[real_name] = script_file_ptr; - - return script_file_ptr; } std::string get_script_file_name(const std::string& name) { - const auto id = xsk::gsc::s1::resolver::token_id(name); + const auto id = gsc::cxt->token_id(name); if (!id) { return name; @@ -157,7 +141,7 @@ namespace gsc return std::to_string(id); } - std::vector decompile_script_file(const std::string& name, const std::string& real_name) + std::pair read_compiled_script_file(const std::string& name, const std::string& real_name) { const auto* script_file = game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, name.data(), false).scriptfile; if (!script_file) @@ -167,17 +151,18 @@ namespace gsc console::info("Decompiling scriptfile '%s'\n", real_name.data()); - std::vector stack{script_file->buffer, script_file->buffer + script_file->len}; - std::vector bytecode{script_file->bytecode, script_file->bytecode + script_file->bytecodeLen}; + if (const auto itr = included_scripts.find(name); itr != included_scripts.end()) + { + return {{script_file->bytecode, static_cast(script_file->bytecodeLen)}, {reinterpret_cast(itr->second.data()), itr->second.size()}}; + } - auto decompressed_stack = xsk::utils::zlib::decompress(stack, static_cast(stack.size())); + const std::string stack{script_file->buffer, static_cast(script_file->len)}; - disassembler->disassemble(name, bytecode, decompressed_stack); - auto output = disassembler->output(); + const auto decompressed_stack = utils::compression::zlib::decompress(stack); + const auto result = included_scripts.emplace(std::make_pair(name, decompressed_stack)); + const auto& itr = result.first; - decompiler->decompile(name, output); - - return decompiler->output(); + return {{script_file->bytecode, static_cast(script_file->bytecodeLen)}, {reinterpret_cast(itr->second.data()), itr->second.size()}}; } void load_script(const std::string& name) @@ -187,8 +172,8 @@ namespace gsc return; } - const auto main_handle = game::Scr_GetFunctionHandle(name.data(), xsk::gsc::s1::resolver::token_id("main")); - const auto init_handle = game::Scr_GetFunctionHandle(name.data(), xsk::gsc::s1::resolver::token_id("init")); + const auto main_handle = game::Scr_GetFunctionHandle(name.data(), gsc::cxt->token_id("main")); + const auto init_handle = game::Scr_GetFunctionHandle(name.data(), gsc::cxt->token_id("init")); if (main_handle) { @@ -285,7 +270,7 @@ namespace gsc for (auto& function_handle : main_handles) { console::info("Executing '%s::main'\n", function_handle.first.data()); - const auto thread = game::Scr_ExecThread(function_handle.second, 0); + const auto thread = game::Scr_ExecThread(static_cast(function_handle.second), 0); game::RemoveRefToObject(thread); } } @@ -305,19 +290,55 @@ namespace gsc for (auto& function_handle : init_handles) { console::info("Executing '%s::init'\n", function_handle.first.data()); - const auto thread = game::Scr_ExecThread(function_handle.second, 0); + const auto thread = game::Scr_ExecThread(static_cast(function_handle.second), 0); game::RemoveRefToObject(thread); } } + + void scr_begin_load_scripts_stub() + { + const auto comp_mode = developer_script->current.enabled ? + xsk::gsc::build::dev : + xsk::gsc::build::prod; + + gsc::cxt->init(comp_mode, [](const std::string& include_name) -> std::pair + { + const auto real_name = include_name + ".gsc"; + + std::string file_buffer; + if (!read_raw_script_file(real_name, &file_buffer) || file_buffer.empty()) + { + const auto name = get_script_file_name(include_name); + if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, name.data())) + { + return read_compiled_script_file(name, real_name); + } + + throw std::runtime_error(std::format("Could not load gsc file '{}'", real_name)); + } + + return {xsk::gsc::buffer(reinterpret_cast(file_buffer.data()), file_buffer.size()), {}}; + }); + + utils::hook::invoke(SELECT_VALUE(0x1403118E0, 0x1403EDE60)); + } + + void scr_end_load_scripts_stub() + { + // Cleanup the compiler + gsc::cxt->cleanup(); + + utils::hook::invoke(SELECT_VALUE(0x140243780, 0x1403EDF90)); + } } game::ScriptFile* find_script(game::XAssetType type, const char* name, int allow_create_default) { std::string real_name = name; - const auto id = static_cast(std::atoi(name)); + const auto id = static_cast(std::strtol(name, nullptr, 10)); if (id) { - real_name = xsk::gsc::s1::resolver::token_name(id); + real_name = gsc::cxt->token_name(id); } auto* script = load_custom_script(name, real_name); @@ -332,39 +353,26 @@ namespace gsc class loading final : public component_interface { public: + void post_load() override + { + gsc::cxt = std::make_unique(); + } + void post_unpack() override { // Load our scripts with an uncompressed stack utils::hook::call(SELECT_VALUE(0x14031ABB0, 0x1403F7380), db_get_raw_buffer_stub); + utils::hook::call(SELECT_VALUE(0x1403309E9, 0x1403309E9), scr_begin_load_scripts_stub); // GScr_LoadScripts + utils::hook::call(SELECT_VALUE(0x14023DA84, 0x140330B9C), scr_end_load_scripts_stub); // GScr_LoadScripts + + developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments"); + if (game::environment::is_sp()) { return; } - // Allow custom scripts to include other custom scripts - xsk::gsc::s1::resolver::init([](const auto& include_name) -> std::vector - { - const auto real_name = include_name + ".gsc"; - - std::string file_buffer; - if (!read_script_file(real_name, &file_buffer) || file_buffer.empty()) - { - const auto name = get_script_file_name(include_name); - if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, name.data())) - { - return decompile_script_file(name, real_name); - } - - throw std::runtime_error(std::format("Could not load gsc file '{}'", real_name)); - } - - std::vector result; - result.assign(file_buffer.begin(), file_buffer.end()); - - return result; - }); - // ProcessScript utils::hook::call(0x1403F7317, find_script); utils::hook::call(0x1403F7327, db_is_x_asset_default); @@ -380,7 +388,6 @@ namespace gsc { if (free_scripts) { - xsk::gsc::s1::resolver::cleanup(); clear(); } }); diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 8b65119..5e06767 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -204,6 +204,11 @@ namespace party return count; } + game::netadr_s& get_target() + { + return connect_state.host; + } + void connect(const game::netadr_s& target) { if (game::environment::is_sp()) diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index 50e9a48..4c45014 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -10,8 +10,10 @@ namespace party void clear_sv_motd(); int server_client_count(); - int get_client_num_by_name(const std::string& name); + [[nodiscard]] int get_client_num_by_name(const std::string& name); - int get_client_count(); - int get_bot_count(); + [[nodiscard]] int get_client_count(); + [[nodiscard]] int get_bot_count(); + + [[nodiscard]] game::netadr_s& get_target(); } diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp index d7e8965..1dd958f 100644 --- a/src/client/game/scripting/functions.cpp +++ b/src/client/game/scripting/functions.cpp @@ -5,33 +5,26 @@ #include "component/gsc/script_extension.hpp" -#include -#include +#include namespace scripting { namespace { - int find_function_index(const std::string& name, const bool prefer_global) + int find_function_index(const std::string& name, [[maybe_unused]] const bool prefer_global) { const auto target = utils::string::to_lower(name); - auto first = xsk::gsc::s1::resolver::function_id; - auto second = xsk::gsc::s1::resolver::method_id; - if (!prefer_global) + auto const& first = gsc::cxt->func_map(); + auto const& second = gsc::cxt->meth_map(); + + if (const auto itr = first.find(name); itr != first.end()) { - std::swap(first, second); + return static_cast(itr->second); } - const auto first_res = first(target); - if (first_res) + if (const auto itr = second.find(name); itr != second.end()) { - return first_res; - } - - const auto second_res = second(target); - if (second_res) - { - return second_res; + return static_cast(itr->second); } return -1; @@ -50,17 +43,17 @@ namespace scripting std::string find_token(std::uint32_t id) { - return xsk::gsc::s1::resolver::token_name(static_cast(id)); + return gsc::cxt->token_name(id); } std::string find_token_single(std::uint32_t id) { - return xsk::gsc::s1::resolver::token_name(static_cast(id)); + return gsc::cxt->token_name(id); } unsigned int find_token_id(const std::string& name) { - const auto id = xsk::gsc::s1::resolver::token_id(name); + const auto id = gsc::cxt->token_id(name); if (id) { return id; diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index 5c0ef0f..e1135e6 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -11,8 +11,7 @@ #include -#include -#include +#include namespace scripting::lua { @@ -246,7 +245,7 @@ namespace scripting::lua auto entity_type = state.new_usertype("entity"); - for (const auto& func : xsk::gsc::s1::resolver::get_methods()) + for (auto const& func : gsc::cxt->meth_map()) { const auto name = std::string(func.first); entity_type[name] = [name](const entity& entity, const sol::this_state s, sol::variadic_args va) @@ -378,7 +377,7 @@ namespace scripting::lua auto game_type = state.new_usertype("game_"); state["game"] = game(); - for (const auto& func : xsk::gsc::s1::resolver::get_functions()) + for (auto const& func : gsc::cxt->func_map()) { const auto name = std::string(func.first); game_type[name] = [name](const game&, const sol::this_state s, sol::variadic_args va) diff --git a/src/common/utils/memory.cpp b/src/common/utils/memory.cpp index 51e76e1..405ed0f 100644 --- a/src/common/utils/memory.cpp +++ b/src/common/utils/memory.cpp @@ -57,7 +57,7 @@ namespace utils { std::lock_guard _(this->mutex_); - const auto data = memory::duplicate_string(string); + auto* data = memory::duplicate_string(string); this->pool_.push_back(data); return data; }