diff --git a/Sources/epoch_code/System/player_login.fsm b/Sources/epoch_code/System/player_login.fsm index 07515bae..70973387 100644 --- a/Sources/epoch_code/System/player_login.fsm +++ b/Sources/epoch_code/System/player_login.fsm @@ -1,4 +1,4 @@ -/*%FSM*/ +/*%FSM*/ /*%FSM*/ /* item0[] = {"INIT",0,250,-25.000000,-375.000000,75.000000,-325.000000,0.000000,"INIT"}; @@ -18,7 +18,7 @@ item13[] = {"ERROR_PlayerUID",2,250,275.000000,125.000000,375.000000,175.000000, item14[] = {"",7,210,471.000061,145.999908,478.999939,154.000092,0.000000,""}; item15[] = {"Timeout_No_Respo",4,218,125.000000,875.000000,225.000000,925.000000,0.000000,"Timeout" \n "No Response"}; item16[] = {"Response",4,218,-150.000000,825.000000,-50.000000,875.000000,0.000000,"Response"}; -item17[] = {"Setup_Player_Var",2,250,-25.000000,1075.000000,75.000000,1125.000000,0.000000,"Setup Player" \n "Variables"}; +item17[] = {"Setup_Player_Var",2,4346,-25.000000,1075.000000,75.000000,1125.000000,0.000000,"Setup Player" \n "Variables"}; item18[] = {"Request_Hive",2,250,-25.000000,575.000000,75.000000,625.000000,0.000000,"Request Hive"}; item19[] = {"Timeout_No_Respo",4,218,125.000000,575.000000,225.000000,625.000000,0.000000,"Timeout" \n "No Response"}; item20[] = {"ERROR_Server_not",2,250,275.000000,875.000000,375.000000,925.000000,0.000000,"ERROR" \n "Server not" \n "Response"}; @@ -62,7 +62,7 @@ item57[] = {"Select_Weapon",2,250,150.000000,1300.000000,250.000000,1350.000000, item58[] = {"true",8,218,225.000000,1375.000000,325.000000,1425.000000,0.000000,"true"}; item59[] = {"Do_nothing",2,250,300.000000,1300.000000,400.000000,1350.000000,0.000000,"Do nothing"}; item60[] = {"Check_New_Player",2,250,-25.000000,875.000000,75.000000,925.000000,0.000000,"Check" \n "New Player" \n "Setup"}; -item61[] = {"check_new__player",4,4314,-150.000000,925.000000,-50.000000,975.000000,0.000000,"check new " \n "player not null"}; +item61[] = {"check_new__player",4,218,-150.000000,925.000000,-50.000000,975.000000,0.000000,"check new " \n "player not null"}; item62[] = {"true",4,218,-150.000000,-325.000000,-60.000000,-275.000000,0.000000,"true"}; item63[] = {"Process_1",2,250,-25.000000,-275.000000,75.000000,-225.000000,0.000000,"Process"}; item64[] = {"Wait_ArmA_Loading",4,218,-150.000000,-225.000000,-50.000000,-175.000000,0.000000,"Wait ArmA" \n "Loading Screen" \n "Done"}; @@ -183,8 +183,8 @@ link93[] = {82,76}; link94[] = {83,16}; link95[] = {83,22}; link96[] = {84,31}; -globals[] = {0.000000,0,0,0,0,640,480,1,247,6316128,1,-423.640717,1096.514160,1778.978027,253.646729,577,604,1}; -window[] = {2,-1,-1,-1,-1,767,105,1089,0,3,595}; +globals[] = {0.000000,0,0,0,0,640,480,1,247,6316128,1,-374.618774,303.072205,1651.411377,653.207275,573,844,1}; +window[] = {2,-1,-1,-1,-1,863,96,1080,96,3,595}; *//*%FSM*/ class FSM { @@ -462,10 +462,13 @@ class FSM "{" \n " missionNamespace setVariable[(format[""EPOCH_player%1"", EPOCH_customVars select _forEachIndex]), _x];" \n "} forEach _playerVariables;" \n - """Loading Player Variables... Please wait!"" call Epoch_updateLoadingScreen;" \n + "{" \n + " missionNamespace setVariable[(format[""EPOCH_total%1"", EPOCH_communityStats select _forEachIndex]), _x];" \n + "} forEach _communityStats;" \n + """Loading Player Variables and Community Stats... Please wait!"" call Epoch_updateLoadingScreen;" \n "progressLoadingScreen 0.7;" \n "if (_debug) then {" \n - " diag_log ""EPOCH-LOGIN: Setup Player Variables"";" \n + " diag_log ""EPOCH-LOGIN: Setup Player Variables and Community Stats"";" \n "};"/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links @@ -1396,6 +1399,7 @@ class FSM "Epoch_canBeRevived = _C_SET deleteAt 0;" \n "Epoch_personalToken = _C_SET deleteAt 0;" \n "Epoch_my_Group = _C_SET deleteAt 0;" \n + "_communityStats = _C_SET deleteAt 0;" \n "" \n "_extraPayload = _C_SET deleteAt 0;" \n "" \n diff --git a/Sources/epoch_code/compile/EPOCH_unitSpawn.sqf b/Sources/epoch_code/compile/EPOCH_unitSpawn.sqf index 65880930..20b8fe52 100644 --- a/Sources/epoch_code/compile/EPOCH_unitSpawn.sqf +++ b/Sources/epoch_code/compile/EPOCH_unitSpawn.sqf @@ -57,6 +57,9 @@ switch _unitClass do { _units pushBack _unit; _unit call _disableAI; [_unit,_trgt] execFSM "\x\addons\a3_epoch_code\System\cloak.fsm"; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AntagonistKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; }; }; case "GreatWhite_F": { @@ -67,6 +70,9 @@ switch _unitClass do { _units pushBack _unit; _unit call _disableAI; [_unit] execFSM "\x\addons\a3_epoch_code\System\Shark_Brain.fsm"; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AntagonistKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; }; }; }; @@ -90,6 +96,9 @@ switch _unitClass do { _unit setVariable ["sapperHndl",_sapperHndl]; _unit addEventHandler ["FiredNear", format ["%1 setFSMVariable [""_sFiredNear"",[_this select 1, _this select 2]];",_sapperHndl]]; _unit addEventHandler ["Hit", format ["%1 setFSMVariable [""_sHit"",[_this select 1, _this select 2]];",_sapperHndl]]; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AntagonistKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; }; }; }; @@ -104,6 +113,9 @@ switch _unitClass do { _unit setVariable ["sapperHndl",_sapperHndl]; _unit addEventHandler ["FiredNear", format ["%1 setFSMVariable [""_sFiredNear"",[_this select 1, _this select 2]];",_sapperHndl]]; _unit addEventHandler ["Hit", format ["%1 setFSMVariable [""_sHit"",[_this select 1, _this select 2]];",_sapperHndl]]; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AntagonistKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; }; }; case "Epoch_SapperB_F": { @@ -117,6 +129,9 @@ switch _unitClass do { _unit setVariable ["sapperHndl",_sapperHndl]; _unit addEventHandler ["FiredNear", format ["%1 setFSMVariable [""_sFiredNear"",[_this select 1, _this select 2]];",_sapperHndl]]; _unit addEventHandler ["Hit", format ["%1 setFSMVariable [""_sHit"",[_this select 1, _this select 2]];",_sapperHndl]]; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AntagonistKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; }; }; case "I_UAV_01_F": { @@ -132,6 +147,9 @@ switch _unitClass do { _driver = _grp createUnit["I_UAV_AI", position _unit, [], 0, "CAN_COLLIDE"]; _driver moveInAny _unit; [_unit, _trgt] execFSM "\x\addons\a3_epoch_code\System\Copter_brain.fsm"; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AIKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; }; }; case "PHANTOM": { @@ -180,6 +198,9 @@ switch _unitClass do { _unit enableAI "MOVE"; _unit enableAI "ANIM"; _unit disableAI "FSM"; + _unit addEventHandler ["Killed", { + [player, _this select 1, "AIKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; + }]; // randomize skill for "_i" from 0 to ((count _arrSkills)-1) do { _aiskill = floor random (_arrVals select _i); diff --git a/Sources/epoch_code/compile/EPOCH_zombieSpawn.sqf b/Sources/epoch_code/compile/EPOCH_zombieSpawn.sqf index 39321280..2dbac50d 100644 --- a/Sources/epoch_code/compile/EPOCH_zombieSpawn.sqf +++ b/Sources/epoch_code/compile/EPOCH_zombieSpawn.sqf @@ -47,5 +47,8 @@ removegoggles _unit; _zedHandle = [_unit,true] execFSM "epoch_code\system\EPOCH_zombie_brain.fsm"; _unit addEventHandler ["FiredNear", "(_this select 0) setVariable [""zFiredNear"",[_this select 1, _this select 2]];"]; _unit addEventHandler ["Hit", "(_this select 0) setVariable [""zHit"",[_this select 1, _this select 2]];"]; +_unit addEventHandler ["Killed", { + [player, _this select 1, "ZombieKills", 1, true, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; +}]; _unit diff --git a/Sources/epoch_code/compile/functions/EPOCH_client_updatePlayerStat.sqf b/Sources/epoch_code/compile/functions/EPOCH_client_updatePlayerStat.sqf new file mode 100644 index 00000000..2c96b4a4 --- /dev/null +++ b/Sources/epoch_code/compile/functions/EPOCH_client_updatePlayerStat.sqf @@ -0,0 +1,45 @@ +/* + + Author: DirtySanchez - EpochMod.com + + Contributors: + + Description: + Update player community stat + Can function as inbound stat adjustment from server side change + Can also function as client side adjustment and send to server for saving + + Licence: + Arma Public License Share Alike (APL-SA) - https://www.bistudio.com/community/licenses/arma-public-license-share-alike + + Github: + https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_code/compile/functions/EPOCH_client_updatePlayerStat.sqf + + usage: + // This will add +15 to the "ZedKills" index and will also update the server variable + ["ZedKills",15,true] call EPOCH_client_updatePlayerStat; + + _statType - STRING: the name of the variable as set in the EpochClientConfig defineCommunityStats[] = {}; + + _adjust - NUMBER: set the positive or negative adjustment, a value of 0 will exit the script + + _toServer - BOOLEAN: (OPTIONAL): false by default + +*/ +params [ ["_statType",""], ["_adjust",0], ["_toServer",false] ]; + +if(_statType isEqualTo "")exitWith{ + diag_log "EPOCHDebug: updatePlayerStats -2- stat type not defined"; +}; +if(_adjust isEqualTo 0)exitWith{ + diag_log "EPOCHDebug: updatePlayerStats -3- stat adjustment is 0"; +}; + +private _statVarName = format["EPOCH_total%1",_statType]; +private _currentStat = missionNameSpace getVariable[_statVarName,0]; +private _newStat = _currentStat + _adjust; +missionNameSpace setVariable[_statVarName,_newStat]; + +if(_toServer)then{ + [player, _statType, _adjust, false, Epoch_personalToken] remoteExec ["EPOCH_fnc_updatePlayerStats",2]; +}; \ No newline at end of file diff --git a/Sources/epoch_code/compile/missions/EPOCH_mission_accept.sqf b/Sources/epoch_code/compile/missions/EPOCH_mission_accept.sqf index 4a8d5892..e2183830 100644 --- a/Sources/epoch_code/compile/missions/EPOCH_mission_accept.sqf +++ b/Sources/epoch_code/compile/missions/EPOCH_mission_accept.sqf @@ -72,6 +72,7 @@ if !(isNull _trader) then { EPOCH_mission_startTime = diag_ticktime; EPOCH_ActiveTraderMission = [_inGameTasksconfig,_taskname,_missionname]; }; + ["TraderMissions",1,true] call EPOCH_client_updatePlayerStat; } else { [format["Mission Not Allowed !",_menuCondition], 5] call Epoch_message; //Not formatting, is this intended? diff --git a/Sources/epoch_code/init/both_init.sqf b/Sources/epoch_code/init/both_init.sqf index 16bc56c8..602a5164 100644 --- a/Sources/epoch_code/init/both_init.sqf +++ b/Sources/epoch_code/init/both_init.sqf @@ -13,7 +13,7 @@ https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_code/init/both_init.sqf */ //[[[cog import generate_private_arrays ]]] -private ["_antagonistSpawnDefaults","_customVarsInit","_say3dsounds","_say3dsoundsConfig","_spawnLimits"]; +private ["_antagonistSpawnDefaults","_customVarsInit","_say3dsounds","_say3dsoundsConfig","_spawnLimits","_communityStatsInit"]; //[[[end]]] // detect if Ryan's Zombies and Deamons mod is present @@ -77,6 +77,18 @@ _customVarsInit = ["CfgEpochClient", "customVarsDefaults", EPOCH_customVarsDefau } forEach _customVarsInit; EPOCH_customVarCount = count EPOCH_customVars; +// Init Community Stats +EPOCH_communityStats = []; +EPOCH_defaultStatVars = []; +_communityStatsInit = ["CfgEpochClient", "defineCommunityStats", []] call EPOCH_fnc_returnConfigEntryV2; +EPOCH_communityStatsDefaults = _communityStatsInit; +{ + EPOCH_communityStats pushBack (_x select 0); + EPOCH_defaultStatVars pushBack (_x select 1); +} forEach _communityStatsInit; +EPOCH_communityStatsCount = count EPOCH_communityStats; + + // Init antagonist spawn limits EPOCH_spawnIndex = []; EPOCH_spawnLimits = []; diff --git a/Sources/epoch_config/Configs/CfgClientFunctions.hpp b/Sources/epoch_config/Configs/CfgClientFunctions.hpp index 803cd98e..d6429996 100644 --- a/Sources/epoch_config/Configs/CfgClientFunctions.hpp +++ b/Sources/epoch_config/Configs/CfgClientFunctions.hpp @@ -137,7 +137,8 @@ class CfgClientFunctions class giveAttributes {}; class fnc_spawnEffects {}; class fnc_arrayStringToBool {}; - class fnc_getHitPointsDamageAverage {}; + class client_updatePlayerStat {}; + class fnc_getHitPointsDamageAverage {}; }; class environment { diff --git a/Sources/epoch_config/Configs/CfgEpochClient.hpp b/Sources/epoch_config/Configs/CfgEpochClient.hpp index a95c57dd..08847686 100644 --- a/Sources/epoch_config/Configs/CfgEpochClient.hpp +++ b/Sources/epoch_config/Configs/CfgEpochClient.hpp @@ -57,6 +57,8 @@ class CfgEpochClient ryanZombiesEnabled = "true"; antagonistSpawnIndex[] = {{"Epoch_Cloak_F",1},{"GreatWhite_F",2},{"Epoch_Sapper_F",2},{"Epoch_SapperG_F",1},{"Epoch_SapperB_F",1},{"I_UAV_01_F",2},{"PHANTOM",1},{"B_Heli_Transport_01_F",1},{"EPOCH_RyanZombie_1",12},{"I_Soldier_EPOCH",1}}; // {"type", limit} customVarsDefaults[] = {{"Temp",98.6,{106.7,95,102,105,96,95}},{"Hunger",1500,{5000,0,5001,5001,1250,0}},{"Thirst",750,{2500,0,2501,2501,625,0}},{"AliveTime",0,{-2,0}},{"Energy",0,{2500,0}},{"Wet",0,{100,0,35,55,-1,-1}},{"Soiled",0,{100,0,35,55,-1,-1}},{"Immunity",0,{100,0}},{"Toxicity",0,{100,0,35,55,-1,-1}},{"Stamina",100,{"EPOCH_playerStaminaMax",0}},{"Crypto",0,{250000,0}},{"HitPoints",{0,0,0,0},{1,0,0.5,1,-1,-1}},{"BloodP",100,{190,0,120,140,70,50}},{"SpawnArray",{},{}},{"Karma",0,{50000,-50000}},{"Alcohol",0,{100,0,35,55,-1,-1}},{"Radiation",0,{100,0,35,55,-1,-1}},{"Nuisance",0,{100,0}},{"MissionArray",{},{}}}; // EPOCH_player + varName, default value, {max,min,high-warn,high-critical,low-warn,low-critical} + // add any stats and their starting number here for better community integration and neat stats tracking too! + defineCommunityStats[] = {{"Murders",0},{"Deaths",0},{"Suicides",0},{"Revives",0},{"TraderMissions",0},{"AIKills",0},{"AntagonistKills",0},{"ZombieKills",0}}; hudConfigs[] = {{{"BloodP","","",{"getPlayerDamage",">=",0.7}},"topRight","x\addons\a3_epoch_code\Data\UI\bleeding_ca.paa",{"forceUpdate"}},{{"Oxygen","getPlayerOxygenRemaining","",{},{1,0,2,2,1,0.55}},"topRight","x\addons\a3_epoch_code\Data\UI\oxygen_ca.paa"},{"Hunger","topRight","x\addons\a3_epoch_code\Data\UI\hunger_ca.paa",{"forceBloodRise"}},{"Thirst","topRight","x\addons\a3_epoch_code\Data\UI\thirst_ca.paa",{"forceBloodRise"}},{"Temp","topRight",{"x\addons\a3_epoch_code\Data\UI\hot_ca.paa","x\addons\a3_epoch_code\Data\UI\cold_ca.paa"},{"forceFatigue"}},{"Toxicity","topRight","x\addons\a3_epoch_code\Data\UI\hazzard_ca.paa"},{"Alcohol","topRight","x\addons\a3_epoch_code\Data\UI\drunk_ca.paa"},{"Soiled","topRight","x\addons\a3_epoch_code\Data\UI\soiled_ca.paa"},{"Radiation","topRight","x\addons\a3_epoch_code\Data\UI\rads_ca.paa"},{{"HitPoints","getPlayerHitPointDamage","HitLegs"},"topRight","x\addons\a3_epoch_code\Data\UI\broken_ca.paa"}}; group_upgrade_lvl[] = {4,"1000",6,"1500",8,"2000",10,"2500",12,"3000",14,"3500",16,"4000",32,"8000",64,"16000"}; // controls max group limit and cost // Event handler code diff --git a/Sources/epoch_config/Configs/CfgRemoteExec.hpp b/Sources/epoch_config/Configs/CfgRemoteExec.hpp index e4301d29..8a5c5dec 100644 --- a/Sources/epoch_config/Configs/CfgRemoteExec.hpp +++ b/Sources/epoch_config/Configs/CfgRemoteExec.hpp @@ -305,6 +305,16 @@ class CfgRemoteExec { allowedTargets = 2; jip = 0; + }; + class EPOCH_fnc_updatePlayerStats + { + allowedTargets = 2; + jip = 0; + }; + class EPOCH_client_updatePlayerStat + { + allowedTargets = 1; + jip = 0; }; }; class Commands diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_savePlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_savePlayer.sqf index 4c092ee4..18ff043e 100644 --- a/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_savePlayer.sqf +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_savePlayer.sqf @@ -14,5 +14,5 @@ */ params ["_player","",["_token","",[""]]]; if([_player,_token] call EPOCH_server_getPToken)then{ - _this call EPOCH_server_savePlayer -} + _this call EPOCH_server_savePlayer; +}; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_updatePlayerStats.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_updatePlayerStats.sqf new file mode 100644 index 00000000..44e56b92 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_updatePlayerStats.sqf @@ -0,0 +1,26 @@ +/* + Author: DirtySanchez - EpochMod.com + + Contributors: + + Description: + Save player with token check for use with RemoteExec + + Licence: + Arma Public License Share Alike (APL-SA) - https://www.bistudio.com/community/licenses/arma-public-license-share-alike + + Github: + https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_player/EPOCH_fnc_updatePlayerStats.sqf +*/ +params ["_player","_killer","_statType","_adjust","_toClient",["_token","",[""]]]; + +if(isNull _player)exitWith{ + diag_log "EPOCHDebug: fnc_updatePlayerStats -1a- player is Null"; +}; +if(isNull _killer)exitWith{ + diag_log "EPOCHDebug: fnc_updatePlayerStats -1b- non local killer is Null"; +}; + +if([_player,_token] call EPOCH_server_getPToken)then{ + [_killer, _statType, _adjust, _toClient] call EPOCH_server_updatePlayerStats; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf index 83d2bf36..391b31b1 100644 --- a/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf @@ -13,7 +13,7 @@ https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf */ //[[[cog import generate_private_arrays ]]] -private ["_apperance","_arr","_class","_dead","_deadPlayer","_hitpoints","_isMale","_medical","_playerUID","_response","_vars"]; +private ["_apperance","_arr","_class","_dead","_deadPlayer","_hitpoints","_isMale","_medical","_playerUID","_response","_vars","_communityStatsArray"]; //[[[end]]] params [["_playerObj",objNull]]; if (_playerObj isEqualType objNull) then { @@ -50,6 +50,13 @@ if (_playerObj isEqualType objNull) then { _dead = true; }; }; + + // check status of community stats to prevent load / save issues + _communityStatsArray = ["CommunityStats", _playerUID] call EPOCH_fnc_server_hiveGETRANGE; + if((_communityStatsArray select 1) isEqualTo []) then{ + _return = ["CommunityStats", _playerUID, EPOCH_expiresCommunityStats, [EPOCH_defaultStatVars]] call EPOCH_fnc_server_hiveSETEX; + }; + /* true => New Char false => load old Char */ ['_checkPlayer_PVC', _dead] remoteExec ['EPOCH_playerLoginInit',_playerObj]; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf index 83015509..de60e70b 100644 --- a/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf @@ -13,7 +13,7 @@ https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf */ //[[[cog import generate_private_arrays ]]] -private ["_bankBalance","_bankData","_cIndex","_current_crypto","_defaultVars","_playerName","_playerUID","_pos","_response","_triggerType","_vars"]; +private ["_bankBalance","_bankData","_cIndex","_current_crypto","_defaultVars","_playerName","_playerUID","_pos","_response","_triggerType","_vars","_killerUID","_deathType","_killerCommunityStats","_mIndex","_current_murders","_communityStats","_sIndex","_current_suicides","_dIndex","_current_deaths"]; //[[[end]]] params ["_playerObj","_killer","_playerName",["_token","",[""]] ]; @@ -21,7 +21,9 @@ params ["_playerObj","_killer","_playerName",["_token","",[""]] ]; if !([_playerObj, _token] call EPOCH_server_getPToken) exitWith{}; _playerUID = getPlayerUID _playerObj; +_killerUID = getPlayerUID _killer; _pos = getposATL _playerObj; +_deathType = 666; if (_playerObj != _killer) then { if (random 1 <= EPOCH_antagonistChancePDeath) then { @@ -37,9 +39,22 @@ if (_playerObj != _killer) then { _playerName = toString (_playerName); }; - ['deathlog', format['%1 (%2) Killed By %3 (%4) with weapon %5 from %6m at %7', _playerName, _playerUID, name _killer, getPlayerUID _killer, currentWeapon _killer, _playerObj distance _killer, _pos]] call EPOCH_fnc_server_hiveLog; + ['deathlog', format['%1 (%2) Killed By %3 (%4) with weapon %5 from %6m at %7', _playerName, _playerUID, name _killer, _killerUID, currentWeapon _killer, _playerObj distance _killer, _pos]] call EPOCH_fnc_server_hiveLog; + + if!(_killerUID isEqualTo "")then{ + [_killer, "Murders", 1, true] call EPOCH_server_updatePlayerStats; + }; + _deathType = 1; }; +switch(_deathType)do{ + case 666: { + [_playerObj, "Suicides", 1] call EPOCH_server_updatePlayerStats; + }; + case 1: { + [_playerObj, "Deaths", 1] call EPOCH_server_updatePlayerStats; + }; +}; _defaultVars = call EPOCH_defaultVars_SEPXVar; // get vars array and current Crypto value _cIndex = EPOCH_customVars find "Crypto"; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf index 89d0e77f..65d59eeb 100644 --- a/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf @@ -13,7 +13,7 @@ https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf */ //[[[cog import generate_private_arrays ]]] -private ["_CheckLocation","_allGroupMembers","_alreadyDead","_attachments","_backpack","_canBeRevived","_class","_currWeap","_deadPlayer","_defaultData","_dir","_equipped","_found","_goggles","_group","_headgear","_hitpoints","_instanceID","_itemsInContainers","_jammer","_jammers","_linkedItems","_location","_newLocation","_newPlyr","_normalMagazines","_playerData","_playerGroup","_playerGroupArray","_playerNetID","_playerUID","_reject","_serverSettingsConfig","_type","_uniform","_vars","_vest","_wMags","_wMagsArray","_weapon","_weaponsAndItems","_weaponsInContainers"]; +private ["_CheckLocation","_allGroupMembers","_alreadyDead","_attachments","_backpack","_canBeRevived","_class","_currWeap","_deadPlayer","_defaultData","_dir","_equipped","_found","_goggles","_group","_headgear","_hitpoints","_instanceID","_itemsInContainers","_jammer","_jammers","_linkedItems","_location","_newLocation","_newPlyr","_normalMagazines","_playerData","_playerGroup","_playerGroupArray","_playerNetID","_playerUID","_reject","_serverSettingsConfig","_type","_uniform","_vars","_vest","_wMags","_wMagsArray","_weapon","_weaponsAndItems","_weaponsInContainers","_communityStatsArray","_communityStats"]; //[[[end]]] _reject = true; @@ -306,7 +306,12 @@ if (!isNull _player) then { _newPlyr setVariable["REVIVE", _canBeRevived]; }; - [_playerNetID, _playerUID, [_newPlyr, _vars, _currWeap, loadAbs _newPlyr, _playerGroup, _canBeRevived, _newPlyr call EPOCH_server_setPToken,_playerGroupArray]] call EPOCH_server_pushPlayer; + // load community stats + _communityStatsArray = ["CommunityStats", _playerUID] call EPOCH_fnc_server_hiveGETRANGE; + _communityStats = ((_communityStatsArray select 1) select 0); + _newPlyr setVariable["COMMUNITY_STATS", _communityStats]; + + [_playerNetID, _playerUID, [_newPlyr, _vars, _currWeap, loadAbs _newPlyr, _playerGroup, _canBeRevived, _newPlyr call EPOCH_server_setPToken,_playerGroupArray, _communityStats]] call EPOCH_server_pushPlayer; //diag_log format["DEBUG (Load Player) Sent Group: %1 %2", _playerGroup, _playerGroupArray]; _newPlyr setVariable["SETUP", true, true]; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf index 7793456a..e2ad7feb 100644 --- a/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf @@ -247,6 +247,9 @@ if (!local _player) then { // send to player [_newPlyr, _token, loadAbs _newPlyr] remoteExec ['EPOCH_clientRevive',_player]; + + // send stat to reviver + [_reviver, "Revives", 1, true] call EPOCH_server_updatePlayerStats; }; }; }; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf index 33623bd3..61842bc1 100644 --- a/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf @@ -12,7 +12,7 @@ Github: https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf */ -private["_return", "_pos", "_medical", "_playerUID", "_weapons", "_itemsplayer", "_weaponsplayer", "_appearance", "_dmg", "_allowSave", "_cIndex", "_Svars", "_current_crypto", "_group", "_revive", "_vehiclePlyr","_server_vars"]; +private["_return", "_return2", "_pos", "_medical", "_playerUID", "_weapons", "_itemsplayer", "_weaponsplayer", "_appearance", "_dmg", "_allowSave", "_cIndex", "_Svars", "_current_crypto", "_group", "_revive", "_vehiclePlyr","_server_vars","_stats"]; params [["_player",objNull], ["_vars",[]]]; if (isNull _player) exitWith { @@ -88,6 +88,10 @@ if (_allowSave) then{ // save player _return = ["Player", _playerUID, EPOCH_expiresPlayer, [[getDir _player, _pos, (call EPOCH_fn_InstanceID)], _medical, _appearance, _server_vars, _vars, _weapons, assignedItems _player, magazinesAmmo _player, _itemsplayer, _weaponsplayer, _group, _revive]] call EPOCH_fnc_server_hiveSETEX; + // save community stats + _stats = _player getVariable["COMMUNITY_STATS", EPOCH_defaultStatVars]; + _return2 = ["CommunityStats", _playerUID, EPOCH_expiresCommunityStats, [_stats]] call EPOCH_fnc_server_hiveSETEX; + // kill player if blood pressure >= 180 if (_vars select 12 >= 180) then { _player setDamage 1; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_updatePlayerStats.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_updatePlayerStats.sqf new file mode 100644 index 00000000..000211ca --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_updatePlayerStats.sqf @@ -0,0 +1,67 @@ +/* + + Author: DirtySanchez - EpochMod.com + + Contributors: + + Description: + Save player community stats - default server only update, _this select 3 = true will send stat update to client + + Licence: + Arma Public License Share Alike (APL-SA) - https://www.bistudio.com/community/licenses/arma-public-license-share-alike + + Github: + https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_player/EPOCH_server_updatePlayerStats.sqf + + usage: + + example 1: + [_playerObj, "AIKills", 1] call Epoch_server_updatePlayerStats; + + usage example + [_playerObj, _statType, _adjust, true] call Epoch_server_updatePlayerStats; + + _playerObj - OBJECT: the player object to receive the stat adjust and send to database/player + + _statType - STRING: the name of the variable as set in the EpochClientConfig defineCommunityStats[] = {}; + + _adjust - NUMBER: set the positive or negative adjustment, a value of 0 will exit the script + + _toClient - BOOLEAN: (OPTIONAL) by default this script is server side variables/hive changes only. + by setting this true the client will receive the stat update. + Use true when the stat change originates from the server and not the client. +*/ +params [ ["_playerObj",objNull], ["_statType",""], ["_adjust",0], ["_toClient",false] ]; + +if(isNull _playerObj)exitWith{ + diag_log "EPOCHDebug: playerUpdateStats -1- player is null object"; +}; +if(_statType isEqualTo "")exitWith{ + diag_log "EPOCHDebug: playerUpdateStats -2- stat type not defined"; +}; +if(_adjust isEqualTo 0)exitWith{ + diag_log "EPOCHDebug: playerUpdateStats -3- stat adjustment is 0"; +}; +_playerUID = getplayerUID _playerObj; +if(_playerUID isEqualTo "")exitWith{ + diag_log "EPOCHDebug: playerUpdateStats -4- player UID is empty"; +}; + +//get this playerObj stats +_playerStats = _playerObj getVariable["COMMUNITY_STATS", EPOCH_defaultStatVars]; +//get this stats index # +_sIndex = EPOCH_communityStats find _statType; +//get this stat value +_currentStat = _playerStats select _sIndex; +//set the new stat value +_playerStats set[_sIndex, _currentStat + _adjust]; +//set the new stats array back onto this playerObj +_playerObj setVariable["COMMUNITY_STATS", _playerStats]; + +//send to hive +["CommunityStats", _playerUID, EPOCH_expiresCommunityStats, [_playerStats]] call EPOCH_fnc_server_hiveSETEX; + +//send to player +if(_toClient)then{ + [_statType,_adjust] remoteExecCall ["EPOCH_client_updatePlayerStat",(owner _playerObj)]; +}; \ No newline at end of file diff --git a/Sources/epoch_server/config.cpp b/Sources/epoch_server/config.cpp index 86dbe556..872391ba 100644 --- a/Sources/epoch_server/config.cpp +++ b/Sources/epoch_server/config.cpp @@ -64,6 +64,8 @@ class CfgServerFunctions class server_deadPlayerDetonate{}; class server_playerSetVariable{}; class server_PayCrypto{}; + class fnc_updatePlayerStats{}; + class server_updatePlayerStats{}; }; class epoch_traders { class server_loadTraders {}; diff --git a/Sources/epoch_server/init/server_variables.sqf b/Sources/epoch_server/init/server_variables.sqf index 8ee3e104..71518800 100644 --- a/Sources/epoch_server/init/server_variables.sqf +++ b/Sources/epoch_server/init/server_variables.sqf @@ -54,6 +54,7 @@ private _configArray = [ ["expiresBank", "7776000"], ["expiresVehicle", "604800"], ["expiresAIdata", "604800"], + ["expiresCommunityStats", "7776000"], ["hiveAdminCmdExec", false], ["hiveAdminSavePlayerList", true], ["hiveAdminCmdTime", 5],