/////////////////////////////////////////////////////////////////////////////// // // SoScore v0.9, last modified 2008/12/25 // by Forlix // http://forlix.org/ // mail: df@forlix.org // // VERSION HISTORY: // // v0.9, 2008/12/25 // - Beta testing // // DESCRIPTION: // // For soccer maps. Registers the individual player that shot the goal and // credits him with a centermessage, message in the chat area, and a score point. // If there was a passer, he will also be mentioned in the chat area message, // but not given any points. // The script balances the scores of players on death as well, so no one looses // any points when dying, and the player score count on the scoreboard clearly // displays how many goals the individual player has scored. // The scoreboard will no longer be filled with negative scores, but show // zeros instead for someone who has not scored a goal at all. // // The script sets up the maps entity network in such a way that it does most of // the work of tracking the players at the ball, and there will only be a single // call back to the script when a goal has been scored, where the shooters userid, // and the team number whose goal has been shot is handed over. If there was a // passer (the shooter only knifed the ball once before it entered the goal), // he will be reported in a seperate call. // The script also provides logging capability, logging goals, own goals, // and passers if existing. // // Keep in mind, the "shooter" is always considered to be the one who last // knifed the ball. Pushing the ball into the goal may give erroneous results. // Analogous, the passer is always the next to last to knife the ball. // // The passer is only reported if he's on the same team as the shooter, and // the goal was NOT an own goal. // // AUTOEXEC.CFG: (add the following without // at the beginning of the line) // // es_load soscore // // COMMANDS: // // None. // The script automatically enables only on maps listed in the config section. // It has to be loaded by autoexec on map start, it should not be loaded in the // middle of a map (in that case, the goal score display would only work for // players who joined the server after the script was enabled) // // CONFIGURATION: block config { // Maps and their entity setups, where soscore will be active // // Syntax to add new maps: // replace and as described below // // es_xkeycreate sc_maps "" // es_xkeysetvalue sc_maps "" "ballent" "" // es_xkeysetvalue sc_maps "" "dmgio" "" // es_xkeysetvalue sc_maps "" "gtrig_t" "" // es_xkeysetvalue sc_maps "" "gtrig_ct" "" // es_xkeysetvalue sc_maps "" "pservcmd" "" // // map_name: Name of the map to be added // ballent: Targetname of the ball entity // dmgio: Name of the ball's entity output that triggers when the ball is knifed // gtrig_t: Targetname of the TERRORIST goal trigger entity // gtrig_ct: Targetname of the CT goal trigger entity // pservcmd: Targetname of the point_servercommand entity es_xkeycreate sc_maps "ka_soccer_2006_v2" es_xkeysetvalue sc_maps "ka_soccer_2006_v2" "ballent" "ballon" es_xkeysetvalue sc_maps "ka_soccer_2006_v2" "dmgio" "OnDamaged" es_xkeysetvalue sc_maps "ka_soccer_2006_v2" "gtrig_t" "terro_But" es_xkeysetvalue sc_maps "ka_soccer_2006_v2" "gtrig_ct" "ct_But" es_xkeysetvalue sc_maps "ka_soccer_2006_v2" "pservcmd" "pushscale" es_xkeycreate sc_maps "ka_soccer_2006_v3fix" es_xkeysetvalue sc_maps "ka_soccer_2006_v3fix" "ballent" "ballon" es_xkeysetvalue sc_maps "ka_soccer_2006_v3fix" "dmgio" "OnDamaged" es_xkeysetvalue sc_maps "ka_soccer_2006_v3fix" "gtrig_t" "terro_But" es_xkeysetvalue sc_maps "ka_soccer_2006_v3fix" "gtrig_ct" "ct_But" es_xkeysetvalue sc_maps "ka_soccer_2006_v3fix" "pservcmd" "pushscale" es_xkeycreate sc_maps "ka_soccer_snow_v3" es_xkeysetvalue sc_maps "ka_soccer_snow_v3" "ballent" "ballon" es_xkeysetvalue sc_maps "ka_soccer_snow_v3" "dmgio" "OnDamaged" es_xkeysetvalue sc_maps "ka_soccer_snow_v3" "gtrig_t" "terro_But" es_xkeysetvalue sc_maps "ka_soccer_snow_v3" "gtrig_ct" "ct_But" es_xkeysetvalue sc_maps "ka_soccer_snow_v3" "pservcmd" "pushscale" es_xkeycreate sc_maps "ka_soccer_badweather" es_xkeysetvalue sc_maps "ka_soccer_badweather" "ballent" "ball" es_xkeysetvalue sc_maps "ka_soccer_badweather" "dmgio" "OnHealthChanged" es_xkeysetvalue sc_maps "ka_soccer_badweather" "gtrig_t" "terro_but" es_xkeysetvalue sc_maps "ka_soccer_badweather" "gtrig_ct" "ct_but" es_xkeysetvalue sc_maps "ka_soccer_badweather" "pservcmd" "pushscale" // Turn logging on or off: // When 1, logs every goal scored to the server log in standard format. // The three log lines that may occur are as follows: // // L MM/DD/YYYY - HH:MM:SS: "PLAYER" passed // L MM/DD/YYYY - HH:MM:SS: "PLAYER" scored a goal // L MM/DD/YYYY - HH:MM:SS: "PLAYER" scored own goal sc_log 1 } /////////////////////////////////////////////////////////////////////////////// block load { es_xset sc_enable 0 es_xset sc_ballent 0 es_xset sc_dmgio 0 es_xset sc_gtrig_t 0 es_xset sc_gtrig_ct 0 es_xset sc_pservcmd 0 es_xset sc_gsuserid 0 es_xset sc_gsname 0 es_xset sc_gsteam 0 es_xset sc_gssteamid 0 es_xset sc_psuserid 0 es_xset sc_psname 0 es_xset sc_psteam 0 es_xset sc_pssteamid 0 es_xset sc_ioplayer 0 es_xset sc_rereason 0 es_xset sc_log 0 es_xset sc_tmp 0 es_xset soscore_ver 0.9 es_xmakepublic soscore_ver es_xset sc_regcmd 0 es_xexists sc_regcmd command sc_handle ifx false(sc_regcmd) { es_xregcmd sc_handle soscore/handle "Internal command to register goal scores" } es_xkeygroupcreate sc_maps es_xkeygroupcreate sc_kills es_xdoblock soscore/config es_xdoblock soscore/mapgetentsetup } /////////////////////////////////////////////////////////////////////////////// block unload { sc_tmp 0 es_xexists sc_tmp keygroup sc_maps ifx true(sc_tmp) do { es_xkeygroupdelete sc_maps } sc_tmp 0 es_xexists sc_tmp keygroup sc_kills ifx true(sc_tmp) do { es_xkeygroupdelete sc_kills } } /////////////////////////////////////////////////////////////////////////////// event es_map_start { sc_enable 0 es_xdoblock soscore/mapgetentsetup } /////////////////////////////////////////////////////////////////////////////// event round_start { ifx true(sc_enable) do { es_xset sc_rstmp 0 es_xgetplayercount sc_rstmp ifx true(sc_rstmp) // dont even think about setting up entities when server is empty! { getrandplayer sc_ioplayer #all es_xdoblock soscore/mapiosetup } ifx parse("sc_rereason == 16") do // reset kills if previous round end was game commencing { foreach player sc_rstmp #all "es_keysetvalue sc_kills server_var(sc_rstmp) kills 0" sc_rereason 0 } // es_xmsg #multi #greenSoscore#lightgreen by Forlix - Players get points for scoring goals! } } /////////////////////////////////////////////////////////////////////////////// event round_end { ifx true(sc_enable) do { es_set sc_rereason event_var(reason) } } /////////////////////////////////////////////////////////////////////////////// event player_activate { ifx true(sc_enable) do { es_xset sc_patmp 0 es_format sc_patmp "OnUser1 %1,command,sc_handle %2 2,0,-1" server_var(sc_pservcmd) event_var(userid) es_fire event_var(userid) !self AddOutput server_var(sc_patmp) es_format sc_patmp "OnUser2 %1,command,sc_handle %2 3,0,-1" server_var(sc_pservcmd) event_var(userid) es_fire event_var(userid) !self AddOutput server_var(sc_patmp) es_format sc_patmp "OnUser4 %1,command,sc_handle %2 0,0,-1" server_var(sc_pservcmd) event_var(userid) es_fire event_var(userid) !self AddOutput server_var(sc_patmp) es_fire event_var(userid) !self AddOutput "OnUser1 !self,AddOutput,targetname player,0,-1" es_fire event_var(userid) !self AddOutput "OnUser2 !self,AddOutput,targetname player,0,-1" es_fire event_var(userid) !self AddOutput "OnUser4 !self,AddOutput,targetname player,0,-1" es_keycreate sc_kills event_var(userid) es_keysetvalue sc_kills event_var(userid) kills 0 sc_patmp 0 es_xgetplayercount sc_patmp ifx parse("sc_patmp == 1") do // player entered empty server and map entities are not set up - do it quick! { es_set sc_ioplayer event_var(userid) es_xdoblock soscore/mapiosetup } } } /////////////////////////////////////////////////////////////////////////////// event player_disconnect { es_xset sc_dctmp 0 es_exists sc_dctmp key sc_kills event_var(userid) ifx true(sc_dctmp) do { es_keydelete sc_kills event_var(userid) } } /////////////////////////////////////////////////////////////////////////////// event player_death { ifx true(sc_enable) do { es_xset sc_dhtmp 0 es_exists sc_dhtmp keyvalue sc_kills event_var(userid) kills es_xset sc_postkills 0 es getplayerinfo sc_postkills event_var(userid) kills ifx true(sc_dhtmp) do { es_xset sc_prekills 0 es_keygetvalue sc_prekills sc_kills event_var(userid) kills ifx parse("sc_postkills < sc_prekills") do // if the player lost a point on death, give it back! // why the check? for example ma_slay adds one too, so in total they // would get +1 kills for being slayed - not that great right? { es_xmath sc_postkills + 1 es_soon es_xfire event_var(userid) game_score ApplyScore } } es_xelse do { es_keycreate sc_kills event_var(userid) } es_keysetvalue sc_kills event_var(userid) kills server_var(sc_postkills) } } /////////////////////////////////////////////////////////////////////////////// block mapiosetup { // we dont need to set any delays here, the outputs are always executed in the // reversed order they were added (lets hope it stays that way - delays are not optimal here) es_xformatv sc_tmp "%1 !activator,AddOutput,targetname _shot,0,-1" sc_dmgio es_fire server_var(sc_ioplayer) server_var(sc_ballent) AddOutput server_var(sc_tmp) es_xformatv sc_tmp "%1 _shot,AddOutput,targetname _pass,0,-1" sc_dmgio es_fire server_var(sc_ioplayer) server_var(sc_ballent) AddOutput server_var(sc_tmp) es_xformatv sc_tmp "%1 _pass,AddOutput,targetname player,0,-1" sc_dmgio es_fire server_var(sc_ioplayer) server_var(sc_ballent) AddOutput server_var(sc_tmp) // the goals will trigger the passers and shooters outputs which in turn execute the handle block. // the passer has to report in first in order to be registered. delays are also required for the later // displayed centermsg, so that it will hopefully override the "Terrorists Win!" message... es_fire server_var(sc_ioplayer) server_var(sc_gtrig_t) AddOutput "OnTrigger _pass,FireUser4,,0.02,-1" es_fire server_var(sc_ioplayer) server_var(sc_gtrig_t) AddOutput "OnTrigger _shot,FireUser1,,0.05,-1" es_fire server_var(sc_ioplayer) server_var(sc_gtrig_ct) AddOutput "OnTrigger _pass,FireUser4,,0.02,-1" es_fire server_var(sc_ioplayer) server_var(sc_gtrig_ct) AddOutput "OnTrigger _shot,FireUser2,,0.05,-1" es_entcreate server_var(sc_ioplayer) game_score es_fire server_var(sc_ioplayer) game_score AddOutput "points 1" } /////////////////////////////////////////////////////////////////////////////// block mapgetentsetup { sc_tmp 0 es_xexists sc_tmp keygroup sc_kills ifx true(sc_tmp) do { es_xkeygroupdelete sc_kills } sc_tmp 0 es_exists sc_tmp key sc_maps server_var(eventscripts_currentmap) ifx true(sc_tmp) do { es_keygetvalue sc_ballent sc_maps server_var(eventscripts_currentmap) ballent es_keygetvalue sc_dmgio sc_maps server_var(eventscripts_currentmap) dmgio es_keygetvalue sc_gtrig_t sc_maps server_var(eventscripts_currentmap) gtrig_t es_keygetvalue sc_gtrig_ct sc_maps server_var(eventscripts_currentmap) gtrig_ct es_keygetvalue sc_pservcmd sc_maps server_var(eventscripts_currentmap) pservcmd es_xkeygroupcreate sc_kills sc_enable 1 } } /////////////////////////////////////////////////////////////////////////////// block handle { es_xset sc_userid 0 es_xset sc_typeid 0 sc_tmp 0 es_xgetargv sc_userid 1 es_xgetargv sc_typeid 2 ifx false(sc_typeid) do // the passer reports in { es_set sc_psuserid server_var(sc_userid) sc_psname 0 sc_psteam 0 sc_pssteamid 0 es_getplayername sc_psname server_var(sc_psuserid) es_getplayerteam sc_psteam server_var(sc_psuserid) es_getplayersteamid sc_pssteamid server_var(sc_psuserid) } es_xelse do // the goal scorer reports in { es_set sc_gsuserid server_var(sc_userid) sc_gsname 0 sc_gsteam 0 sc_gssteamid 0 es_getplayername sc_gsname server_var(sc_gsuserid) es_getplayerteam sc_gsteam server_var(sc_gsuserid) es_getplayersteamid sc_gssteamid server_var(sc_gsuserid) es_xset sc_gslogmsg 0 es_xset sc_pslogmsg 0 es_xset sc_goaltype 0 ifx parse("sc_typeid == 2") do { ifx parse("sc_gsteam == 2") do { // TERRORIST own goal sc_goaltype 1 } ifx parse("sc_gsteam == 3") do { // CT scored sc_goaltype 3 } } ifx parse("sc_typeid == 3") do { ifx parse("sc_gsteam == 3") do { // CT own goal sc_goaltype 1 } ifx parse("sc_gsteam == 2") do { // TERRORIST scored sc_goaltype 2 } } ifx parse("sc_goaltype > 0") do { ifx parse("sc_goaltype == 1") do { es_xformatv sc_tmp "#green%1#lightgreen scored an own goal..." sc_gsname es_msg #multi server_var(sc_tmp) esnq es_xcentermsg server_var(sc_gsname) scored an own goal... es_delayed 1.5 es_xnq es_xcentermsg server_var(sc_gsname) scored an own goal... sc_gslogmsg "scored own goal" } ifx parse("sc_goaltype >= 2") do { ifx parse("sc_psuserid > 0 and sc_psteam == sc_gsteam") do // credit the passer only if he exists and is on the same team as the shooter { es_xformatv sc_tmp "#green%1#lightgreen scored a goal, pass by #green%2#lightgreen!" sc_gsname sc_psname sc_pslogmsg 1 } es_xelse do { es_xformatv sc_tmp "#green%1#lightgreen scored a goal!" sc_gsname } es_msg #multi server_var(sc_tmp) esnq es_xcentermsg server_var(sc_gsname) scored a goal! es_delayed 1.5 es_xnq es_xcentermsg server_var(sc_gsname) scored a goal! sc_gslogmsg "scored a goal" es_xset sc_tmpkills 0 es getplayerinfo sc_tmpkills server_var(sc_gsuserid) kills es_xmath sc_tmpkills + 1 es_fire server_var(sc_gsuserid) game_score ApplyScore sc_tmp 0 es_exists sc_tmp keyvalue sc_kills server_var(sc_gsuserid) kills ifx false(sc_tmp) do { es_keycreate sc_kills server_var(sc_gsuserid) } es_keysetvalue sc_kills server_var(sc_gsuserid) kills server_var(sc_tmpkills) } ifx true(sc_log) do { ifx parse("sc_gsteam == 2") do { sc_gsteam "TERRORIST" } es_xelse do { sc_gsteam "CT" } ifx true(sc_pslogmsg) do { es_set sc_psteam server_var(sc_gsteam) es_xformatv sc_logentry "%1%2<%3><%4><%5>%1 passed" eventscripts_quote sc_psname sc_psuserid sc_pssteamid sc_psteam es_xlogv sc_logentry } es_xformatv sc_logentry "%1%2<%3><%4><%5>%1 %6" eventscripts_quote sc_gsname sc_gsuserid sc_gssteamid sc_gsteam sc_gslogmsg es_xlogv sc_logentry } } // else // goal shooter must have quickly changed team to SPECTATOR after shooting, // so we cant say if it was an own goal or not -> we rather shut up sc_gsuserid 0 sc_psuserid 0 } } ///////////////////////////////////////////////////////////////////////////////