Dynamic job script - actors and saving?
#1

Heyhey.

I'm making a dynamic job system right now, but I am stuck because I managed to confuse myself - therefore I need some help and hints to get out of it and sort it out. Also need some tips regarding actors, but will get back to that later.

Here's my current "script", just includes two commands pretty much: http://pastebin.com/v950waAL

My MySQL database has an own table for jobs. Right now it has a jobid (primary key, auto increment), jobtype (int), jobname (varchar, 24), jobposx-z(float) and jobworld. Including jobworld incase I'll add a job inside an interior. When I make a job in-game the 3d text is being created, however whenever I try to update it - it adds a new 3dxtext label. I haven't made any load function yet, will try to do that soon.

All the code releated to dynamic text labels gets a tag mismatch warning (even the destroy, so 3 warnings)

Since the jobid is auto increment and primary key, I'm wondering how the heck I am supposed to do this correctly. Example my enums, when I use them on /createjob - I wrote createjobtype, but that is clearly wrong as it is supposed to be the jobid I guess? But that's being auto generated, so will I have to retrieve/find that from the database first? I'm confusing myself.

About actors:
How does that work? Like if I'd like to replace the dynamic 3d text labels with actors instead, how'd that work out? Like in the same table as jobs. Whenever I /createjob - an actor spawns, and tells the person that is closeby to type /takejob to join the job for instance. Or does it require a own table as it needs an unique ID? Anyone got a good idea here?

And if there's anything that could be done another way, please tell me about it. Trying to learn.
Reply
#2

Anyone?
Reply
#3

Instead of destroying and recreating the label, you can use Update3DTextLabelText: https://sampwiki.blast.hk/wiki/Update3DTextLabelText
As for your error, you are forgetting the 'Text3D:' tag.

Actors are static NPCs, they can't move but can execute animations. The good thing about actors is that they don't use player slots unlike NPCs.
_Emmet's extended actor functionality: https://sampforum.blast.hk/showthread.php?tid=573504

And: https://sampwiki.blast.hk/wiki/CreateActor , make sure to check the 'related functions' at the bottom of the page.

You can make a message pop-up when a player gets close to a given actor, and mimic is if it were the actor saying it.
Reply
#4

Alright, any clue how I am supposed to deal with the job ids?
Quote:

Since the jobid is auto increment and primary key, I'm wondering how the heck I am supposed to do this correctly. Example my enums, when I use them on /createjob - I wrote createjobtype, but that is clearly wrong as it is supposed to be the jobid I guess? But that's being auto generated, so will I have to retrieve/find that from the database first? I'm confusing myself.

Reply
#5

Quote:
Originally Posted by TheBigFive
Посмотреть сообщение
Alright, any clue how I am supposed to deal with the job ids?
Not sure why you would use MAX_PLAYER_NAME as your size. It doesn't quite tell you what it is. You should define MAX_JOBS or something along those lines instead.

As for your question, the database ID is only used in queries. Session ID and Database ID is something to be kept apart because of the fact that you use an array to access the enum and arrays start counting at 0, unlike your A_I field. I personally prefer keeping the 0-start instead of adding 1 to every index.

To achieve that, I keep an extra boolean enumerator usually called 'bool: xxExists'. Fill in the 'xx' yourself or remove it. This variable is not saved.

Loading:
PHP код:
for(new 0cache_get_row_count(); MAX_JOBS && ji++) {
    
jobData[i][Exists] = true;
    
// Load other data

Filling in the gaps when creating a new job:
PHP код:
for(new i  0MAX_JOBSi++) if(!jobData[i][Exists]) {
    
jobData[i][Exists] = true;
    
// Save other data

The loop will loop through all indexes of jobData and check which ID is not created yet. It will then create the new job using that ID. All you have to do to remove a job is set 'Exists' to false and of course remove the row from the database.

There are countless ways of achieving the same thing, but I do it like this. I'm open to hear from others on how to do it differently.
Reply
#6

Ah god. This is a mess, don't really understand this loop thing, nor how to load things properly.
Also uploaded the code to pastebin so it's easier to read: http://pastebin.com/YJth3Heh
Код:
#define MAX_JOBS 1
enum JobData
{
	jobid,
	jobtype,
	jobname[MAX_PLAYER_NAME],
	Float:jobposx,
	Float:jobposy,
	Float:jobposz,
	Float:jobposr,
	jobworld,
	actorskin

};
new jobData[MAX_JOBS][JobData];

CMD:createjob(playerid, params[])
{
	if(charData[playerid][characteradmin] > 1) return ErrorMSG(playerid, "You are not authorized to use this command");
	new createjobtype, createjobname[24], createactorskin;
	if(sscanf(params, "is[24]", createjobtype, createjobname, createactorskin)) return UsageMSG(playerid, "/createjob [jobtype] [jobname] [actorskin]");
	if(createjobtype > 6 || createjobtype == 0) return ErrorMSG(playerid, "The job type has to be between 1 and 6");
	new Float:x, Float:y, Float:z, Float:r, createjobworld;
	GetPlayerPos(playerid, x, y, z);
	GetPlayerFacingAngle(playerid, r);
	createjobworld = GetPlayerVirtualWorld(playerid);

	format(jobData[createjobtype][jobname], 24, "%s", createjobname);
	jobData[createjobtype][jobposx] = x;
	jobData[createjobtype][jobposy] = y;
	jobData[createjobtype][jobposz] = z;
	jobData[createjobtype][jobworld] = createjobworld;
	CreateActor(createactorskin, x, y, z, r);

	mysql_format(connection, query, sizeof(query), "INSERT INTO `jobs` (jobtype, jobname, jobposx, jobposy, jobposz, actorskin) VALUES(%d, '%s', %f, %f, %f, %d)", createjobtype, createjobname, x, y, z, createactorskin);
	mysql_tquery(connection, query, "", "");
	return CMD_SUCCESS;
}

CMD:editjob(playerid, params[])
{
	new editjobid, editoption, editjobtext[24];
	if(charData[playerid][characteradmin] > 1) return ErrorMSG(playerid, "You are not authorized to use this command");
	if(sscanf(params, "is[24]", editjobid, editoption, editjobtext)) return UsageMSG(playerid, "/editjob [option(1-name, 2-pos)] [text]");
	if(editoption == 1)
	{
		for(new i = 0, j = cache_get_row_count(); i < MAX_JOBS && i < j; i++) 
		{ 
			if(IsPlayerInRangeOfPoint(playerid, 3, jobData[i][jobposx], jobData[i][jobposy], jobData[i][jobposz]))	
			{	
				new Float:x, Float:y, Float:z;
				GetPlayerPos(playerid, x, y, z);
				mysql_format(connection, query, sizeof(query), "UPDATE `jobs` SET `jobname` = '%s' WHERE `jobid` = %d", editjobtext, i);
				mysql_tquery(connection, query, "", "");
			}
		}
	}
	return CMD_SUCCESS;
}

forward OnLoadJobs();
public OnLoadJobs()
{
	new rows, fields;
	cache_get_data(rows, fields, connection);
	if(rows)
	{
		jobid = cache_get_row_int(rows, 0, connection);
		jobData[jobid][jobtype] = cache_get_field_content_int(1, "jobtype");
		cache_get_row(rows, 2, jobData[jobid][jobname], connection, 24);
		jobData[jobid][jobname] = cache_get_field_content_int(3, "jobname");
		jobData[jobid][jobposx] = cache_get_field_content_float(4, "jobposx");
		jobData[jobid][jobposy] = cache_get_field_content_float(5, "jobposy");
		jobData[jobid][jobposz] = cache_get_field_content_float(6, "jobposz");
		jobData[jobid][jobposr] = cache_get_field_content_float(7, "jobposr");
		jobData[jobid][jobworld] = cache_get_field_content_int(8, "jobworld");
		jobData[jobid][actorskin] = cache_get_field_content_float(6, "actorskin");
		format(msg, sizeof(msg), "%s\n/takejob", jobData[jobid][jobname]);
		CreateActor(jobData[jobid][actorskin], jobData[jobid][jobposx], jobData[jobid][jobposy], jobData[jobid][jobposz], jobData[jobid][jobposr]);
	}
	return true;	
}
Reply
#7

bump
Reply
#8

Still got some issues here.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)