Jump to content

[HOWTO / RELEASE] Keep your plot pole after you die!!!


Recommended Posts

I created a MySQL trigger that will update a characters plot pole with their new CharacterID once they die.

 

  1. In MySQL Workbench CE connect to your mysql server.
  2. open the dayz_epoch db
  3. right click on character_data and select 'Alter Table'
  4. click on the Triggers tab at the bottom.
  5. Select After Insert from the list and click Add Trigger
  6. Replace the generated code with the below and select Apply
DELIMITER $$
DROP TRIGGER IF EXISTS dayz_epoch.`character_data_AINS_plot`;
CREATE TRIGGER `dayz_epoch.character_data_AINS_plot` AFTER INSERT ON dayz_epoch.character_data FOR EACH ROW
-- Edit trigger body code below this line. Do not edit lines above this one
BEGIN
	DECLARE oldCharacterID INT;
	SELECT 
		CharacterID INTO oldCharacterID
	FROM 
		dayz_epoch.character_data 
	WHERE
		PlayerUID = new.PlayerUID
			AND
		Alive = '0'
	ORDER BY CharacterID Desc
	LIMIT 1;

	IF (oldCharacterID IS NOT NULL) THEN
		UPDATE
			dayz_epoch.object_data
		SET
			CharacterID = new.CharacterID
		WHERE
			Classname = 'Plastic_Pole_EP1_DZ'
				AND
			CharacterID = oldCharacterID;
	END IF;
END

My next attempt will be to have the characters buildables follow them as well so that they can remove their walls and what not.

 

What this does sets the players previous plot pole from their old characterID to their new characterID when they rejoin and select a new character.

 

UPDATE:

 

In addition to the above I have written scripts so that you do NOT have to restart the server... I have tested these and have worked for me.

 

Unpack your dayz_server.pbo file and open compile/server_playerLogin.sqf. find 

dayzPlayerLogin = [_charID,_inventory,_backpack,_survival,_isNew,dayz_versionNo,_model,_isHiveOk,_newPlayer,_isInfected];

at the bottom and just before this line add

if (_isNew) then {
	diag_log format["Player %1 Character %2 is NEW", _playerID, _charID];
	[_charID, _playerID, _playerObj] call server_changePlotsOwner;
};

open server_functions.sqf and add 

DeadPlayerPlotObjects = [];

just above

BIS_Effects_Burn =				{};

now find

server_maintainArea = 			compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_maintainArea.sqf";

and add this code just below it

server_changePlotsOwner =		compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_changePlotsOwner.sqf"; 

open server_playerDied.sqf

find:

_newObject setVariable["processedDeath",diag_tickTime];

if (typeName _minutes == "STRING") then 
{
	_minutes = parseNumber _minutes;
};

diag_log ("PDEATH: Player Died " + _playerID);

and add the below code just above it

_allPoleObjs = allMissionObjects "Plastic_Pole_EP1_DZ";
_playerOwnedPlots = [];
diag_log format["Running pole stuff for char %1", _characterID];
diag_log format["All Poles: %1", _allPoleObjs];
	{
            diag_log format["Pole: %1",_x];
            _ownerID = _x getVariable["CharacterID","0"];
            diag_log format["Owner of pole: %1", _ownerID];
            if (_ownerID == _characterID) then {
                diag_log format["Owner: %1 == Char: %2", _ownerID, _characterID];
                _playerOwnedPlots set [(count _playerOwnedPlots), _x];
            };
	} forEach (_allPoleObjs);
        diag_log format["Player owned plots: %1", _playerOwnedPlots];
	_player_death_object_record = [
		_characterID,
		_playerID,
        _playerOwnedPlots
	];
        diag_log format["Player death records: %1", _player_death_object_record];

	DeadPlayerPlotObjects set [(count DeadPlayerPlotObjects), _player_death_object_record];
	diag_log format["DeadPlayerObjects: %1", DeadPlayerPlotObjects];

now create a new file in the /compile folder called server_changePlotsOwner.sqf and add

private ["_charID", "_playerID", "_playerObj", "_oldCharID", "_playaID", "_plots", "_removePlayerObjects", "_loc", "_dir", "_objCharID", "_classname", "_obj"];

_charID = _this select 0;
_playerID = _this select 1;
_playerObj = _this select 2;

//Check if player had any plots
diag_log ("Hello New player");
diag_log format["Your ID: %1 - %2 - %3", _playerID, _playerObj, _charID];
diag_log DeadPlayerPlotObjects;
diag_log format["Dead players count: %1", (count DeadPlayerPlotObjects)];
{
	diag_log format["player object found: %1",_x];
	_oldCharID = _x select 0;
	_playaID = _x select 1;
	_plots = _x select 2;
            diag_log format["Old Character: %1 PlayerID: %2 Plots: %3", _oldCharID, _playaID, _plots];
        if (count _plots > 0) then {
            if (_playaID == _playerID) then {
                    // User was found
                    {
                            // assign plots to new character
                            diag_log format["Type: %1", typeOf _x];
                            _x setVariable ["CharacterID", _charID, true];
                            diag_log format["Plot %1 is now owned by %2", _x, _x getVariable ["CharacterID","0"]];
                            
                    } forEach (_plots);
                    _removePlayerObjects set [count _removePlayerObjects, _x];
            };
        };
} forEach (DeadPlayerPlotObjects);
  
DeadPlayerPlotObjects = DeadPlayerPlotObjects - _removePlayerObjects;

Thats it... feel free to remove the diag_log lines if you want. Now save all the files and repack your dayz_server.pbo file.

 

I'm trying to get object swapping to work so that there is no need for the database triggers but having issues with that part. For now the above works fine

Link to comment
Share on other sites

hey spectral i've been waiting for this for ages and was so exited to see someone worked it out , BUT ive followed your instructions and i fully understand how to install this but for some reason its not working for me ? does the database need restarting ? I will try that when my servers restart . 

Link to comment
Share on other sites

hey spectral i've been waiting for this for ages and was so exited to see someone worked it out , BUT ive followed your instructions and i fully understand how to install this but for some reason its not working for me ? does the database need restarting ? I will try that when my servers restart . 

 

You shouldn't have to restart the server. Atleast I didn't. What did you try? For me, I used my existing character that had a plot pole planted. I then killed myself after creating the trigger and respawned. I then alt + tabbed out of the game and checked the DB and my plot pole was then assigned to my new CharacterID.

Link to comment
Share on other sites

First refer to this to set up a "vehicle_test" table in your database

 

and then use this trigger

DELIMITER ;
DROP TRIGGER IF EXISTS EPOCH_TABLE_NAME.`update_owner`;
DELIMITER //
CREATE TRIGGER EPOCH_TABLE_NAME.`update_owner`
AFTER INSERT ON EPOCH_TABLE_NAME.character_data
FOR EACH ROW
BEGIN
    UPDATE EPOCH_TABLE_NAME.object_data SET CharacterID = NEW.CharacterID WHERE CharacterID IN (SELECT CharacterID FROM character_data WHERE PlayerUID = NEW.PlayerUID) and classname NOT IN (select * from vehicle_test) AND NOT (Classname LIKE '%door%' OR Classname LIKE '%vault%' OR Classname LIKE '%box%');
END//
DELIMITER ;

Remember to change the "EPOCH_TABLE_NAME" to your table name!

 

This is not my original code i found it on here and expanded it a bit

Link to comment
Share on other sites

Spectral, thanks for this. If this works, it would be great. I installed it like your way, but after i died, i can`t respawn. Requesting Authentication and then Retrying Authentication is shown in 80 seconds on Loadingscreen. What`s the problem? You have a solution ?

 

Solution :-) : Object Table etc wrong lettersize. But it doesn`t work like it should. I can login, but can`t build on my "old" plotpole with respawncharakter.

Have to wait for restart?

Link to comment
Share on other sites

Spectral, thanks for this. If this works, it would be great. I installed it like your way, but after i died, i can`t respawn. Requesting Authentication and then Retrying Authentication is shown in 80 seconds on Loadingscreen. What`s the problem? You have a solution ?

 

Solution :-) : Object Table etc wrong lettersize. But it doesn`t work like it should. I can login, but can`t build on my "old" plotpole with respawncharakter.

Have to wait for restart?

 

Does the plot pole in the object_data table show the new character ID?

Link to comment
Share on other sites

for that to work you would have to read the new ID from the hive, write it to the correct plot pole and then publish it to the clients. That's why i'm working on the fix posted in my last comment, to lower the network traffic, it might be a bit of work for the server admins to implement but in the long run you will get better performance

Link to comment
Share on other sites

Error earlier
 

ERROR 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-xxxxxx.character_data_AINS' at line 1
SQL Statement:
DROP TRIGGER IF EXISTS user-xxxxxx.character_data_AINS

ERROR: Error when running failback script. Details follow.

ERROR 1050: Table 'character_data' already exists
SQL Statement:
CREATE TABLE `character_data` (
  `CharacterID` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `PlayerUID` varchar(20) NOT NULL DEFAULT '0',
  `Slot` tinyint(3) unsigned NOT NULL DEFAULT '1',
  `InstanceID` int(11) NOT NULL DEFAULT '0',
  `Datestamp` datetime DEFAULT NULL,
  `LastLogin` datetime NOT NULL,
  `Inventory` longtext,
  `Backpack` longtext,
  `Worldspace` varchar(128) NOT NULL DEFAULT '[]',
  `Medical` varchar(300) NOT NULL DEFAULT '[]',
  `Alive` tinyint(3) unsigned NOT NULL DEFAULT '1',
  `Generation` int(11) unsigned NOT NULL DEFAULT '1',
  `LastAte` datetime NOT NULL,
  `LastDrank` datetime NOT NULL,
  `KillsZ` int(11) unsigned NOT NULL DEFAULT '0',
  `HeadshotsZ` int(11) unsigned NOT NULL DEFAULT '0',
  `DistanceFoot` int(11) NOT NULL DEFAULT '0',
  `Duration` int(11) NOT NULL DEFAULT '0',
  `CurrentState` varchar(200) NOT NULL DEFAULT '[]',
  `KillsH` int(11) unsigned NOT NULL DEFAULT '0',
  `Model` varchar(50) NOT NULL DEFAULT '"Survivor2_DZ"',
  `KillsB` int(11) unsigned NOT NULL DEFAULT '0',
  `Humanity` int(11) NOT NULL DEFAULT '2500',
  `Infected` tinyint(3) DEFAULT '0',
  PRIMARY KEY (`CharacterID`),
  KEY `PlayerUID` (`PlayerUID`) USING BTREE,
  KEY `Alive` (`Alive`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1860 DEFAULT CHARSET=latin1

Link to comment
Share on other sites

Asien kid, since you have issues regarding your SQL use this

Also this Will give better performance in the long run as you dont have at rigger running on the SQL server every time some one dies and you dont have A script to update characterIDs, even tho spectrals solution is good, switching to PlayerUID will be better for performance

Link to comment
Share on other sites

Going to try this later!

 

Will be very interested to see if you get the buildings working too!
 

Wouldn't it be possible to do it another way though? Like...

 

set new charid to oldcharid? That way all buildables and poles more to be theirs. Or is this not possible? (probably not or I guess you'd have done it!). Be cool if it did work tho, especially without reboots!

 

 

I created a MySQL trigger that will update a characters plot pole with their new CharacterID once they die.

 

  1. In MySQL Workbench CE connect to your mysql server.
  2. open the dayz_epoch db
  3. right click on character_data and select 'Alter Table'
  4. click on the Triggers tab at the bottom.
  5. Select After Insert from the list and click Add Trigger
  6. Replace the generated code with the below and select Apply
DELIMITER $$
DROP TRIGGER IF EXISTS dayz_epoch.`character_data_AINS_plot`;
CREATE TRIGGER `character_data_AINS_plot` AFTER INSERT ON dayz_epoch.character_data FOR EACH ROW
-- Edit trigger body code below this line. Do not edit lines above this one
BEGIN
	DECLARE oldCharacterID INT;
	SELECT 
		CharacterID INTO oldCharacterID
	FROM 
		dayz_epoch.character_data 
	WHERE
		PlayerUID = new.PlayerUID
			AND
		Alive = '0'
	ORDER BY CharacterID Desc
	LIMIT 1;

	IF (oldCharacterID IS NOT NULL) THEN
		UPDATE
			dayz_epoch.object_data
		SET
			CharacterID = new.CharacterID
		WHERE
			Classname = 'Plastic_Pole_EP1_DZ'
				AND
			CharacterID = oldCharacterID;
	END IF;
END

My next attempt will be to have the characters buildables follow them as well so that they can remove their walls and what not.

 

What this does sets the players previous plot pole from their old characterID to their new characterID when they rejoin and select a new character.

 

UPDATE:

 

In addition to the above I have written scripts so that you do NOT have to restart the server... I have tested these and have worked for me.

 

Unpack your dayz_server.pbo file and open compile/server_playerLogin.sqf. find 

dayzPlayerLogin = [_charID,_inventory,_backpack,_survival,_isNew,dayz_versionNo,_model,_isHiveOk,_newPlayer,_isInfected];

at the bottom and just before this line add

if (_isNew) then {
	diag_log format["Player %1 Character %2 is NEW", _playerID, _charID];
	[_charID, _playerID, _playerObj] call server_changePlotsOwner;
};

open server_functions.sqf and add 

DeadPlayerPlotObjects = [];

just above

BIS_Effects_Burn =				{};

now find

server_maintainArea = 			compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_maintainArea.sqf";

and add this code just below it

server_changePlotsOwner =		compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_changePlotsOwner.sqf"; 

open server_playerDied.sqf

find:

_newObject setVariable["processedDeath",diag_tickTime];

if (typeName _minutes == "STRING") then 
{
	_minutes = parseNumber _minutes;
};

diag_log ("PDEATH: Player Died " + _playerID);

and add the below code just above it

_allPoleObjs = allMissionObjects "Plastic_Pole_EP1_DZ";
_playerOwnedPlots = [];
diag_log format["Running pole stuff for char %1", _characterID];
diag_log format["All Poles: %1", _allPoleObjs];
	{
            diag_log format["Pole: %1",_x];
            _ownerID = _x getVariable["CharacterID","0"];
            diag_log format["Owner of pole: %1", _ownerID];
            if (_ownerID == _characterID) then {
                diag_log format["Owner: %1 == Char: %2", _ownerID, _characterID];
                _playerOwnedPlots set [(count _playerOwnedPlots), _x];
            };
	} forEach (_allPoleObjs);
        diag_log format["Player owned plots: %1", _playerOwnedPlots];
	_player_death_object_record = [
		_characterID,
		_playerID,
        _playerOwnedPlots
	];
        diag_log format["Player death records: %1", _player_death_object_record];

	DeadPlayerPlotObjects set [(count DeadPlayerPlotObjects), _player_death_object_record];
	diag_log format["DeadPlayerObjects: %1", DeadPlayerPlotObjects];

now create a new file in the /compile folder called server_changePlotsOwner.sqf and add

private ["_charID", "_playerID", "_playerObj", "_oldCharID", "_playaID", "_plots", "_removePlayerObjects", "_loc", "_dir", "_objCharID", "_classname", "_obj"];

_charID = _this select 0;
_playerID = _this select 1;
_playerObj = _this select 2;

//Check if player had any plots
diag_log ("Hello New player");
diag_log format["Your ID: %1 - %2 - %3", _playerID, _playerObj, _charID];
diag_log DeadPlayerPlotObjects;
diag_log format["Dead players count: %1", (count DeadPlayerPlotObjects)];
{
	diag_log format["player object found: %1",_x];
	_oldCharID = _x select 0;
	_playaID = _x select 1;
	_plots = _x select 2;
            diag_log format["Old Character: %1 PlayerID: %2 Plots: %3", _oldCharID, _playaID, _plots];
        if (count _plots > 0) then {
            if (_playaID == _playerID) then {
                    // User was found
                    {
                            // assign plots to new character
                            diag_log format["Type: %1", typeOf _x];
                            _x setVariable ["CharacterID", _charID, true];
                            diag_log format["Plot %1 is now owned by %2", _x, _x getVariable ["CharacterID","0"]];
                            
                    } forEach (_plots);
                    _removePlayerObjects set [count _removePlayerObjects, _x];
            };
        };
} forEach (DeadPlayerPlotObjects);
  
DeadPlayerPlotObjects = DeadPlayerPlotObjects - _removePlayerObjects;

Thats it... feel free to remove the diag_log lines if you want. Now save all the files and repack your dayz_server.pbo file.

 

I'm trying to get object swapping to work so that there is no need for the database triggers but having issues with that part. For now the above works fine

Link to comment
Share on other sites

  • 2 weeks later...

It seems to have issues with multiple deaths in a row.  ( Ex: Like when someone suicide chains to get a better spawn )  at least on our server.  Also we've not been able to determine if spawning in on a parachute and splatting has been effecting it or not so we did tests after landing the parachute and dying multiple times in a row and the same effect.  If you are curious as to which mods we might be using you are welcome to take a look at our server link in my signature.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Discord

×
×
  • Create New...