Long time no post.
Well for my quest system I needed some sort of alternative for clientr. variables so I developed this System I call Scratch. Feel free to give it your own name if you decide to implement it on your server.
Basicly think of it as a Scratchpad for your variables, it keeps them in memory and allows you to manipulate them and when your player logs out the variables are stored back in their respective variable files and ready to be reloaded on login.
I'm sure many have a system similiar to this in their own scripts that allow variables to be saved to files but here's how I decided to do mine
Feel free to modify, and implement into your own servers/scripts. I haven't really tested it that in depth but it should meet a majority of your alternative clientr. needs.
Giving credit to me in the script is appreciated but not required, hope someone can find use for this
Possible Implementations:
- MUDLib, see example.
- Quest System
MUDLib Theory Example:
PHP Code:
function onActionPlayerOnline() {
// Load Scratch Data
Scratch.onLoadScratch("levels/mudlib/players/fowlplay4.txt", "playerstats", true);
// Set Player Health to 10
Scratch.onSetScratch("playerstats", "health", 10);
}
function onPlayerLogout(acc) {
// Remove from Memory and Save
Scratch.onUnloadScratch(acc);
}
//#CLIENTSIDE
function onCreated() {
// As long as the variables were in sync before this ran
// 10 would echo in your F2 Log
echo(Scratch.onGetScratch("playerstats", "health"));
}
The Database NPC
PHP Code:
/*
Main Idea: Alternative to clientr. values
- Loads a Variable File into Memory
- Allows Option to Sync Data with Client
- Unloads and Saves on PlayerLogout
*/
function onCreated() {
// For Calling Scratch instead of using findnpc()
const Scratch = this;
// The Clientside Weapon used with Scratch
this.db = "+Scratch";
}
/*
Loads Scratch Data into Database
@param file Absolute Path to File
@param identity The ID you're going to give your file
@param clientsync Sync Data with Client? True or False
*/
public function onLoadScratch(file, identity, clientsync) {
// Add Files to Memory
this.identifiers.(@player.account).add(identity);
this.files.(@player.account).add(file);
// Load Scratch Memory
this.scratch.(@player.account).(@extractfilebase(file)).loadvars(file);
// Sync with Client?
if (clientsync) {
temp.lines.loadlines(file);
player.triggerclient(this.db, "load", identity, temp.lines);
this.clientsync.(@player.account).add(identity);
}
}
/*
Unloads Scratch data associated with account
@param acc Player's Account Name
@param identity Optional Param: Use if you only want to unload one specific Scratch
*/
public function onUnloadScratch(acc, identity) {
// Remove Specific Scratch
if (identity) {
// Determine File
temp.file = onGetFile(identity);
// Save File
this.scratch.(@acc).(@extractfilebase(file)).savevars(file, 0);
// Remove from Memory
this.scratch.(@acc).(@extractfilebase(file)).clearvars();
// Remove from Player Variables
this.identifiers.(@acc).remove(identity);
this.files.(@acc).remove(file);
if (identity in this.clientsync.(@acc))
this.clientsync.(@acc).remove(identity);
return;
}
// Save Files and Remove from Memory
for (temp.file: this.files.(@acc)) {
this.scratch.(@acc).(@extractfilebase(file)).savevars(file, 0);
this.scratch.(@acc).(@extractfilebase(file)).clearvars();
}
// Remove Player Variables from Memory
this.identifiers.(@acc) = "";
this.files.(@acc) = "";
this.clientsync.(@acc) = "";
}
/*
Sets variable to value in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's New Value
*/
public function onSetScratch(identity, variable, value) {
// Locate File
temp.file = onGetFile(identity);
// Adjust Scratch
this.scratch.(@player.account).(@extractfilebase(file)).(@variable) = value;
// Sync with Client?
if (identity in this.clientsync.(@player.account)) {
player.triggerclient(this.db, "sync", identity, variable, value);
}
}
/*
Adds value to variable's array in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's Value to Add
*/
public function onAddScratch(identity, variable, value) {
// Locate File
temp.file = onGetFile(identity);
// Adjust Scratch
this.scratch.(@player.account).(@extractfilebase(file)).(@variable).add(value);
// Sync with Client?
if (identity in this.clientsync.(@player.account)) {
player.triggerclient(this.db, "sync", identity, variable, onGetScratch(identity, variable));
}
}
/*
Removes value from variable's array in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's Value to Add
*/
public function onRemScratch(identity, variable, value) {
// Locate File
temp.file = onGetFile(identity);
// Adjust Scratch
this.scratch.(@player.account).(@extractfilebase(file)).(@variable).remove(value);
// Sync with Client?
if (identity in this.clientsync.(@player.account)) {
player.triggerclient(this.db, "sync", identity, variable, onGetScratch(identity, variable));
}
}
/*
Accesses identity's Scratch and returns Variable's Value
@param identity Scratch's Identity Value
@param variable Variable Name
@return Value of Variable
*/
public function onGetScratch(identity, variable) {
// Locate File
temp.file = onGetFile(identity);
// Return Variable
return this.scratch.(@player.account).(@extractfilebase(file)).(@variable);
}
/*
Gets the Scratch's associated file
@param identity Scratch's Identity Value
@return Files Absolute Location
*/
public function onGetFile(identity) {
return this.files.(@player.account)[this.identifiers.(@player.account).index(identity)];
}
The Weapon NPC
PHP Code:
function onActionServerside() {
if (params[0] != "scratch") return;
switch (params[1]) {
case "set":
Scratch.onSetScratch(params[2], params[3], params[4]);
break;
case "add":
Scratch.onAddScratch(params[2], params[3], params[4]);
break;
case "rem":
Scratch.onRemScratch(params[2], params[3], params[4]);
break;
}
}
//#CLIENTSIDE
function onCreated() {
// Allows other Scripts to access it as Scratch
// instead of using findweapon()
const Scratch = this;
}
function onActionClientside(cmd) {
temp.identity = params[1];
switch (cmd) {
case "load":
// Clear Sync'd Vars if they Exist
if (identity in this.synced)
this.scratch.(@identity).clearvars();
else
this.synced.add(identity);
// Load Variables
this.scratch.(@identity).loadvarsfromarray(params[2]);
break;
case "sync":
// Sync Variable
if (identity in this.synced)
this.scratch.(@identity).(@params[2]) = params[3];
break;
}
}
/*
Accesses identity's Scratch and returns Variable's Value
@param identity Scratch's Identity Value
@param variable Variable Name
@return Value of Variable
*/
public function onGetScratch(identity, variable) {
// Return Variable
return this.scratch.(@identity).(@variable);
}
/*
Tells server to set variable to value in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's New Value
*/
public function onSetScratch(identity, variable, value) {
if (!(identity in this.synced)) return;
triggerserver("gui", name, "scratch", "set", identity, variable, value);
}
/*
Tells server to add value to variable's array in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's Value to Add
*/
public function onAddScratch(identity, variable, value) {
if (!(identity in this.synced)) return;
triggerserver("gui", name, "scratch", "add", identity, variable, value);
}
/*
Tells server to remove value from variable's array in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's Value to Add
*/
public function onRemScratch(identity, variable, value) {
if (!(identity in this.synced)) return;
triggerserver("gui", name, "scratch", "rem", identity, variable, value);
}