[FilterScript] Alcor's event system!
#1

Introduction

This is just a simple event system, ideal for RPG servers as it doesn't have teleportation commands or whatnot. That's about if for the introduction, see the video for more information on how it works and how to use it in the game. You don't need to put any credits for me, it took me 10 minutes to do as a quick addition to my own server. I have used sscanf2 and ZCMD for this, but you can optimize it for your own needs.


Commands available

/event - View the information of an existing event, anyone can use this command.
/e - Speak on the event organizer's chat, you can only use this if you're the organizer of the event, only the event organizer can use this command.
/cancelrequest - Cancel an outstanding event request you have, anyone who has requested an event can use this command.
/stopevent - Stop an event that you're hosting, only the event organizer and RCON admins can use this command.
/requestevent - Request to host an event, must be approved by admins before it being published, anyone can use this command.
/acceptevent - Accept an incoming event request, only admins can use this command.
** NEW ** /rejectevent - Reject an event that was submitted, with a given reason, only RCON admins can use this command.
** NEW ** /pendingevents - Shows a dialog of a list style where you can see the outstanding events that have been requested, this includes the player, the player's ID and the requested event's title, only RCON admins can use this command.
** NEW ** /checkevent - A bit like the command /event, but with this command you can check the details of the event before it being accepted. Only RCON admins can use this command too.


Installation of the script


First thing you want to do is to add the global variables, so put the following at the top of your script:

Code:
new eventorganizer[MAX_PLAYERS];
new requestingevent[MAX_PLAYERS];
new requestingtitle[MAX_PLAYERS][50];
new requestinglocation[MAX_PLAYERS][50];
new requestingdescription[MAX_PLAYERS][100];
new requestingprize[MAX_PLAYERS];
new requestingtime[MAX_PLAYERS][50];

new activeevent;
new eventtitle[50];
new eventlocation[50];
new eventdescription[100];
new eventprize;
new eventtime[50];
Second thing, under OnPlayerDisconnect add the following code:

Code:
requestingevent[playerid] = 0;
eventorganizer[playerid] = 0;
For our third step, we'll be adding the commands

Code:
CMD:event(playerid, params[])
{
	if(activeevent == 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}There is currently no active event running.");
	new string[300], name[MAX_PLAYER_NAME];
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(eventorganizer[i] == 1)
	    {
	        GetPlayerName(i, name, sizeof(name));
		}
	}
	SendClientMessage(playerid, 0xFFFFFFFF, "-------------------------------------------");
	format(string, sizeof(string), "{FFFF00}Title: %s Location: %s Time: %s", eventtile, eventlocation, eventtime);
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Organizer: %s Prize: $%s", third, Comma(eventprize));
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Description: %s", eventdescription);
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	SendClientMessage(playerid, 0xFFFFFFFF, "-------------------------------------------");
	return 1;
}

CMD:e(playerid, params[])
{
	if(eventorganizer[playerid] == 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}You're not the organizer of the event.");
	new text[250];
	if(sscanf(params, "s[250]", text)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Syntax: /e [text]");
    new string[300], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    format(string, sizeof(string), "{7094DB}Event Organizer %s: %s", name, text);
    SendClientMessageToAll(0xFFFFFFFF, string);
    return 1;
}

CMD:cancelrequest(playerid, params[])
{
	if(requestingevent[playerid] == 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}You're not requesting an event.");
	requestingevent[playerid] = 0;
	SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Your event request has been cancelled.");
	return 1;
}

CMD:stopevent(playerid, params[])
{
	if(activeevent == 0 && IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}There isn't any events to stop.");
	if(eventorganizer[playerid] == 0 && !IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}You're not the organizer of the event.");
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    eventorganizer[i] = 0;
	}
	SendClientMessageToAll(0xFFFFFFFF, "-------------------------------------------");
	SendClientMessageToAll(0xFFFFFFFF, "{FFFF00}Event over.");
	SendClientMessageToAll(0xFFFFFFFF, "-------------------------------------------");
	activeevent = 0;
	return 1;
}

CMD:acceptevent(playerid, params[])
{
	if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}You're not an admin.");
	if(activeevent == 1) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}There's already an active event.");
	new evetnid;
	if(sscanf(params, "d", eventid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Syntax: /acceptevent [eventid]");
	if(requestingevent[eventid] == 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid event ID.");
	strmid(eventtitle, requestingtitle[eventid], 0, strlen(requestingtitle[eventid]));
	strmid(eventlocation, requestinglocation[eventid], 0, strlen(requestinglocation[eventid]));
	strmid(eventdescription, requestingdescription[eventid], 0, strlen(requestingdescription[eventid]));
	eventprize = requestingprize[eventid];
	strmid(eventtime, requestingtime[eventid], 0, strlen(requestingtime[eventid]));
	new string[300], name[MAX_PLAYER_NAME];
	GetPlayerName(eventid, name, sizeof(name));
	SendClientMessageToAll(0xFFFFFFFF, "-------------------------------------------");
	format(string, sizeof(string), "{FFFF00}Event: %d Title: %s Location: %s Time: %s", eventid, eventtitle, eventlocation, eventtime);
	SendClientMessageToAll(0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Organizer: %s Prize: $%s", name, Comma(eventprize));
	SendClientMessageToAll(0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Description: %s", eventdescription);
	SendClientMessageToAll(0xFFFFFFFF, string);
	SendClientMessageToAll(0xFFFFFFFF, "-------------------------------------------");
	eventorganizer[eventid] = 1;
	requestingevent[eventid] = 0;
	activeevent = 1;
	return 1;
}

CMD:requestevent(playerid, params[])
{
	if(activeevent == 1) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}There's already an active event.");
	if(requestingevent[playerid] == 1) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}You're already requesting an event, cancel it first.");
    new title[50], location[50], description[100], prize, time[50];
    if(sscanf(params, "p<|>s[50]s[50]s[50]s[100]d", title, location, time, description, prize)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Syntax: /requestevent [Title|Location|Time|Description|Prize]");
	if(strlen(title) < 1 || strlen(title) > 50) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid amount of characters in title.");
	if(strlen(location) < 1 || strlen(location) > 50) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid amount of characters in location.");
	if(strlen(time) < 1 || strlen(time) > 50) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid amount of characters in time.");
	if(strlen(description) < 1 || strlen(description) > 100) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid amount of characters in description.");
	if(prize < 1 || prize > 5000000) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid prize amount.");
	new string[300], name[MAX_PLAYER_NAME];
	GetPlayerName(playerid, name, sizeof(name));
	requestingevent[playerid] = 1;
	strmid(requestingtitle[playerid], title, 0, strlen(title));
	strmid(requestinglocation[playerid], location, 0, strlen(location));
	strmid(requestingdescription[playerid], description, 0, strlen(description));
	requestingprize[playerid] = prize;
	strmid(requestingtime[playerid], time, 0, strlen(time));
	if(!IsPlayerAdmin(playerid)) SendClientMessage(playerid, 0xFFFFFFFF, "-------------------------------------------");
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, "-------------------------------------------");
		}
	}
	format(string, sizeof(string), "{FFFF00}Event %d has been requested, details are below.", playerid);
	if(!IsPlayerAdmin(playerid)) SendClientMessage(playerid, 0xFFFFFFFF, string);
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, string);
		}
	}
	format(string, sizeof(string), "{FFFF00}Event: %d Title: %s Location: %s Time: %s", playerid, title, location, time);
	if(!IsPlayerAdmin(playerid)) SendClientMessage(playerid, 0xFFFFFFFF, string);
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, string);
		}
	}
	format(string, sizeof(string), "{FFFF00}Organizer: %s Prize: $%s", name, Comma(prize));
	if(!IsPlayerAdmin(playerid)) SendClientMessage(playerid, 0xFFFFFFFF, string);
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, string);
		}
	}
	format(string, sizeof(string), "{FFFF00}Description: %s", description);
	if(PlayerData[playerid][pAdmin] < 1) SendClientMessage(playerid, 0xFFFFFFFF, string);
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, string);
		}
	}
	format(string, sizeof(string), "{FFFF00}Use [/acceptevent %d] to accept this event.", playerid);
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, string);
		}
	}
	SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Your event is pending approval from an admin, please wait.");
	if(!IsPlayerAdmin(playerid)) SendClientMessage(playerid, 0xFFFFFFFF, "-------------------------------------------");
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        SendClientMessage(i, 0xFFFFFFFF, string);
		}
	}
	return 1;
}

CMD:rejectevent(playerid, params[])
{
	if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Only admins can use this command.");
	new id, reason[100];
	if(sscanf(params, "us[100]", id, reason)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Syntax: /rejectevent [eventid] [reason]");
	if(requestingevent[id] == 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid event ID.");
	new string[300], sendername[MAX_PLAYER_NAME], receivername[MAX_PLAYER_NAME];
	requestingevent[id] = 0;
	GetPlayerName(playerid, sendername, sizeof(sendername));
	GetPlayerName(id, receivername, sizeof(receivername));
	format(string, sizeof(string), "{FFFF00}Admin %s has rejected your event, reason: %s", sendername, reason);
	SendClientMessage(id, 0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}You rejected %s's event, reason: %s", receivername, reason);
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	return 1;
}

CMD:pendingevents(playerid, params[])
{
	if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Only admins can use this command.");
	new string[1000], tmpstring[100], titlestring[100], count = 0, name[MAX_PLAYER_NAME;
	for(new i = 0; i < MAX_PLAYERS; i ++)
	{
	    if(IsPlayerConnected(i))
	    {
	        if(requestingevent[i] == 1)
	        {
	            GetPlayerName(i, name, sizeof(name));
	            format(tmpstring, sizeof(tmpstring), "Name: %s | ID: %d | Title: %s", name, i, requestingtitle[i]);
				strcat(string, tmpstring);
				count ++;
			}
		}
	}
	if(count == 0) return ShowPlayerDialog(playerid, 5345, DIALOG_STYLE_MSGBOX, "Pending Requests: 0", "There are no pending requests.", "Done", "");
	format(titlestring, sizeof(titlestring), "Pending Requests: %d", count);
	ShowPlayerDialog(playerid, 5345, DIALOG_STYLE_LIST, titlestring, string, "Done", "");
	SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Use the command /checkevent to check the pending event information.");
	return 1;
}

CMD:checkevent(playerid, params[])
{
	if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Only admins can use this command.");
	new eventid;
	if(sscanf(params, "u", eventid)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Syntax: /checkevent [eventid]");
	if(requestingevent[eventid] == 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FFFF00}Invalid event ID.");
	new string[300], name[MAX_PLAYER_NAME];
	GetPlayerName(eventid, name, sizeof(name));
	SendClientMessage(playerid, 0xFFFFFFFF, "-------------------------------------------");
	format(string, sizeof(string), "{FFFF00}Title: %s Location: %s Time: %s", requestingtitle[eventid], requestinglocation[eventid], requestingtime[eventid]);
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Organizer: %s Prize: $%s", name, Comma(requestingprize[eventid]));
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Description: %s", requestingdescription[eventid]);
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	format(string, sizeof(string), "{FFFF00}Use [/acceptevent %d] to accept this event.", eventid);
	SendClientMessage(playerid, 0xFFFFFFFF, string);
	SendClientMessage(playerid, 0xFFFFFFFF, "-------------------------------------------");
	return 1;
}
Fourthly, just add the stocks that I've used here, i.e. the Comma stock. Credits to whomever made it, I forgot...

Code:
stock Comma(numbers)
{
    new temp[100], counter = -1;
    valstr(temp, numbers);
    for(new i = strlen(temp);i > 0; i--)
    {
        counter++;
        if(counter == 3)
        {
            strins(temp, ",", i);
            counter = 0;
        }
    }
    return temp;
}
Now, that'll be done. Just go into the game and test it out. I know some of the code is pretty bad for a good scripter, but I did do it in 10 minutes and now I need to go out.
Reply
#2

Wow thanks, it really worked!
Reply
#3

Good but is not this a tutorial?
Reply
#4

Quote:
Originally Posted by SonnyGamer
View Post
Good but is not this a tutorial?
No it isn't...
Reply
#5

I didnt test it yet, but good work.
Reply
#6

It's 2017 still MAX_PLAYERS loop? Use foreach instead.
Reply
#7

Add 'k' to the name it will be "Kalcor's event system" :0
Reply
#8

Quote:
Originally Posted by Logic_
View Post
It's 2017 still MAX_PLAYERS loop? Use foreach instead.
MAX_PLAYERS is just a macro definition of an int..

Foreach is the definition of a macro defined for() loop (I guess, never looked into its source)

It's the same thing, for() while() etc etc, it's still PAWN, it's still a loop.




No matter what people use, it's the same thing over and over, but how you use it is what's important.
https://sampwiki.blast.hk/wiki/Control_Structures#Loops
Reply
#9

Quote:
Originally Posted by Meller
View Post
MAX_PLAYERS is just a macro definition of an int..

Foreach is the definition of a macro defined for() loop (I guess, never looked into its source)

It's the same thing, for() while() etc etc, it's still PAWN, it's still a loop.




No matter what people use, it's the same thing over and over, but how you use it is what's important.
https://sampwiki.blast.hk/wiki/Control_Structures#Loops
Code that is using foreach = Optimized, Code that is using for(new i; i < MAX_PLAYERS; i++) is unoptimized
Reply
#10

Quote:
Originally Posted by adri[4]Life
View Post
Code that is using foreach = Optimized, Code that is using for(new i; i < MAX_PLAYERS; i++) is unoptimized
AHAHHAHAHAHAHAHHAHAHAHAHHAHA-.. *fake laugh begins*

Mhm, let's eh..
look at the facts you've got:

Quote:
Originally Posted by adri[4]Life
View Post
Code that is using foreach = Optimized
Proof; Eh?

Quote:
Originally Posted by adri[4]Life
View Post
Code that is using foreach = Optimized, Code that is using for(new i; i < MAX_PLAYERS; i++) is unoptimized
Proof; None?

Explanation; None.






Real facts;

for( ; ; )
Quote:

A "for" loop is essentially a compressed "while" loop. A "for" statement has three sections; initialization, condition and finalization.

Source
Expl: for( ; ; ) simply works like while(), it runs down untill the second parameter is accurate, example;
for(new x; x != 100; x++)
Run this code with the variable x untill it reaches 100.

foreach()
Quote:

Foreach loop. Infinite loop. Control flow. For each (or foreach) is a control flow statement for traversing items in a collection. Foreach is usually used in place of a standard for statement.

Source

https://en.wikipedia.org/wiki/Foreach_loop#C.23
Quote:

they essentially say "do this to everything in this set", rather than "do this x times".




Do you understand what foreach is now? And what for() is in the embedded scripting language pawn?
Reply
#11

Quote:
Originally Posted by adri[4]Life
View Post
Code that is using foreach = Optimized, Code that is using for(new i; i < MAX_PLAYERS; i++) is unoptimized
The second part is not always true, sometimes you want to reset an array which is MAX_PLAYERS long.

Quote:
Originally Posted by Meller
View Post
MAX_PLAYERS is just a macro definition of an int..

Foreach is the definition of a macro defined for() loop (I guess, never looked into its source)

It's the same thing, for() while() etc etc, it's still PAWN, it's still a loop.




No matter what people use, it's the same thing over and over, but how you use it is what's important.
https://sampwiki.blast.hk/wiki/Control_Structures#Loops
Its technically not a "still the same loop".

It uses a loop, yes, but a dynamic loop, saving you processing time.
When you use frequently a certain loop, like in a timer with an interval of 1000 milliseconds, you'd want it to be as fast as possible, foreach will sure ensure it.

foreach uses the y_iterate approach, which is also a child library of YSI.

Loops are useful, but they're better when they're short.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)