[FilterScript] Dynamic Map System
#3

I haven't looked at the source code, but by the looks of it, it would be nice to have something like this for an event system. Also, I created a map voting/management system a while back, mind including it here or something? It would make this somehow more complex and it might turn out to be good for events and such.

pawn Код:
// [ DEVELOPMENT GAMEMODE ]

// INCLUDES:

#include <a_samp>
#include <sscanf2>
#include <foreach>
#include <zcmd>

// DEFINES:

// GENERAL:

#define MAX_MAPS 100
#define MAX_MAP_INFO 2
#define MAX_PAGE_RESULTS 20
#define VOTE_INTERVAL 30
#define INTERVAL_TIME 180000

// FUNCTIONS:

#define function%0(%1) forward%0(%1); public%0(%1)
#define isnull(%1) ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))
#define strcpy(%0,%1,%2) strcat((%0[0] = '\0', %0), %1, %2)
#define GetPageCount(%0,%1) floatround((%1 - 1) / %0, floatround_floor) + 1
#define plural_singular(%0,%1,%2) ((%0) == 1)?((#%1)):((#%2))

// DIALOGS:

#define DIALOG_OK 0
#define DIALOG_MAP_NAME 1
#define DIALOG_MAP_POSITION 2
#define DIALOG_MAP_CONFIRMATION 3
#define DIALOG_MAP_LIST 4
#define DIALOG_MAP_VOTE 5
#define DIALOG_MAP_VOTE_OPTIONS 6

// DATABASE:

#define DATABASE_PATH "maps.db"
#define TABLE_MAPS "Maps"

#define MAP_NAME "name"
#define MAP_POSITION "position"

// MAP INFO:

#define MAP_INFO_NAME 0
#define MAP_INFO_POSITION 1

// ARRAYS AND ENUMERATORS:

enum eMapInfo
{
    map_name[128],
    Float:map_x,
    Float:map_y,
    Float:map_z,
    Float:map_angle,
    map_votes
};

new aMapInfo[MAX_MAPS][eMapInfo];

// VARIABLES:

// GENERAL:

new gMapCount,
gVoteCountDown,
gTopVotes,
gLeadingMap;

// DATABASE:

new DB:database;

// TIMERS:

new gtmMapVoting,
gtmLoadMap,
gtmChangeMap;

// TEXTDRAWS:

new Text:tCountDown;

// PER-PLAYER VARIABLES:

// GENERAL:

new pNewMapString[MAX_PLAYERS][MAX_MAP_INFO][128],
pLastPage[MAX_PLAYERS],
pMap[MAX_PLAYERS];

// STATES:

new bool:sVoting[MAX_PLAYERS] = false;

// MAIN:

main()
{
    print("Development Mode: map_voting.amx");
}

// CALLBACKS:

public OnGameModeInit()
{
    LoadDatabase();
    LoadTextdraws();

    new query[144], DBResult:result, results, position[128], count;
    format(query, sizeof(query), "SELECT `%s`, `%s` FROM `%s`",
    MAP_NAME,
    MAP_POSITION,
    TABLE_MAPS);
    result = db_query(database, query);

    results = db_num_rows(result);
    gMapCount = results;

    if(results != 0)
    {
        if(count <= MAX_MAPS)
        {
            db_get_field_assoc(result, MAP_NAME, aMapInfo[count][map_name], 128);
            db_get_field_assoc(result, MAP_POSITION, position, sizeof(position));
            format(position, sizeof(position), "%s", ReplaceString(",", " ", position));
            sscanf(position, "ffff", aMapInfo[count][map_x], aMapInfo[count][map_y], aMapInfo[count][map_z], aMapInfo[count][map_angle]);

            count ++;

            while(db_next_row(result))
            {
                if(count > MAX_MAPS) break;

                db_get_field_assoc(result, MAP_NAME, aMapInfo[count][map_name], 128);
                db_get_field_assoc(result, MAP_POSITION, position, sizeof(position));
                format(position, sizeof(position), "%s", ReplaceString(",", " ", position));
                sscanf(position, "ffff", aMapInfo[count][map_x], aMapInfo[count][map_y], aMapInfo[count][map_z], aMapInfo[count][map_angle]);

                count ++;
            }
        }
    }

    db_free_result(result);

    gtmChangeMap = SetTimer("ChangeMap", INTERVAL_TIME, true);
    return 1;
}

public OnGameModeExit()
{
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
    {
        case DIALOG_OK: return 1;
        case DIALOG_MAP_NAME:
        {
            if(!response) return 1;
            else if(response)
            {
                if(isnull(inputtext)) return ShowEnterMapName(playerid);

                strcpy(pNewMapString[playerid][MAP_INFO_NAME], inputtext, 128);
                return ShowEnterMapPosition(playerid);
            }
        }
        case DIALOG_MAP_POSITION:
        {
            if(!response) return ShowEnterMapName(playerid);
            else if(response)
            {
                if(isnull(inputtext)) return ShowEnterMapPosition(playerid);

                strcpy(pNewMapString[playerid][MAP_INFO_POSITION], inputtext, 128);
                return ShowAddMapConfirmation(playerid);
            }
        }
        case DIALOG_MAP_CONFIRMATION:
        {
            if(!response) return ShowEnterMapPosition(playerid);
            else if(response)
            {
                new query[256];
                format(query, sizeof(query), "INSERT INTO `%s` ", TABLE_MAPS);
                format(query, sizeof(query), "%s(`%s`,", query, MAP_NAME);
                format(query, sizeof(query), "%s`%s`) ", query, MAP_POSITION);

                format(query, sizeof(query), "%sVALUES('%s',", query, pNewMapString[playerid][MAP_INFO_NAME]); // MAP_NAME
                format(query, sizeof(query), "%s'%s')", query, pNewMapString[playerid][MAP_INFO_POSITION]); // MAP_POSITION
                db_query(database, query);

                gMapCount ++;
                strcpy(aMapInfo[gMapCount][map_name], pNewMapString[playerid][MAP_INFO_NAME], 128);
                sscanf(pNewMapString[playerid][MAP_INFO_POSITION], "ffff", aMapInfo[gMapCount][map_x], aMapInfo[gMapCount][map_y], aMapInfo[gMapCount][map_z], aMapInfo[gMapCount][map_angle]);
            }
        }
        case DIALOG_MAP_LIST:
        {
            if(!response) return 1;
            else if(response)
            {
                pLastPage[playerid] ++;
                return ShowMaps(playerid);
            }
        }
        case DIALOG_MAP_VOTE:
        {
            if(!response)
            {
                new pages = GetPageCount(MAX_PAGE_RESULTS, gMapCount);
                if(pLastPage[playerid] < pages) pLastPage[playerid] ++;
                return ShowMaps(playerid);
            }
            else if(response)
            {
                new mapid = (((MAX_PAGE_RESULTS * pLastPage[playerid]) - MAX_PAGE_RESULTS) + listitem);
                pMap[playerid] = mapid;
                return ShowMapVoteOptions(playerid);
            }
        }
        case DIALOG_MAP_VOTE_OPTIONS:
        {
            if(!response) return ShowMaps(playerid);
            else if(response)
            {
                switch(listitem)
                {
                    case 0: // Vote for map
                    {
                        new string[144], mapid = pMap[playerid];
                        aMapInfo[mapid][map_votes] ++;

                        if(aMapInfo[mapid][map_votes] > gTopVotes)
                        {
                            gTopVotes = aMapInfo[mapid][map_votes];
                            gLeadingMap = mapid;
                        }

                        format(string, sizeof(string), "You have voted for the map: %s.", aMapInfo[mapid][map_name]);
                        SendClientMessage(playerid, -1, string);

                        sVoting[playerid] = false;
                    }
                    case 1: // Previous page
                    {
                        if(pLastPage[playerid] > 1) pLastPage[playerid] --;
                        return ShowMaps(playerid);
                    }
                    case 2: // Next page
                    {
                        new pages = GetPageCount(MAX_PAGE_RESULTS, gMapCount);
                        if(pLastPage[playerid] < pages) pLastPage[playerid] ++;
                        return ShowMaps(playerid);
                    }
                }
            }
        }
    }
    return 1;
}

// COMMANDS:

CMD:voteoff(playerid, cmd[], cmdtext[])
{
    KillTimer(gtmChangeMap);
    return 1;
}

CMD:voteon(playerid, cmd[], cmdtext[])
{
    KillTimer(gtmChangeMap);
    gtmChangeMap = SetTimer("ChangeMap", INTERVAL_TIME, true);
    return 1;
}

CMD:addmap(playerid, cmd[], cmdtext[])
{
    if(IsPlayerVoting(playerid)) return SendClientMessage(playerid, -1, "You cannot use this command while voting for a map.");
    if(gMapCount >= MAX_MAPS) return SendClientMessage(playerid, -1, "The max amount of maps has been reached, you cannot create another one.");

    ShowEnterMapName(playerid);
    return 1;
}

CMD:maps(playerid, cmd[], cmdtext[])
{
    if(IsPlayerVoting(playerid)) return SendClientMessage(playerid, -1, "You cannot use this command while voting for a map.");

    pLastPage[playerid] = 1;
    ShowMaps(playerid);
    return 1;
}

CMD:forcevote(playerid, params[])
{
    if(IsPlayerVoting(playerid)) return SendClientMessage(playerid, -1, "You cannot use this command while voting for a map.");
    if(gMapCount <= 0) return SendClientMessage(playerid, -1, "There are no maps for players to vote for.");

    gTopVotes = 0;
    gLeadingMap = 0;

    for(new i = 0; i < gMapCount; i ++)
    {
        aMapInfo[i][map_votes] = 0;
    }

    foreach(new i: Player)
    {
        sVoting[i] = true;
        pLastPage[i] = 1;
        ShowMaps(i);
    }

    gVoteCountDown = VOTE_INTERVAL;

    KillTimer(gtmMapVoting);
    gtmMapVoting = SetTimer("MapVoting", 1000, true);
    return 1;
}

// FUNCTIONS:

stock LoadDatabase()
{
    new query[128];
    database = db_open(DATABASE_PATH);

    format(query, sizeof(query), "CREATE TABLE IF NOT EXISTS `%s` ", TABLE_MAPS);
    format(query, sizeof(query), "%s(`%s`,", query, MAP_NAME);
    format(query, sizeof(query), "%s`%s`)", query, MAP_POSITION);
    db_query(database, query);
}

stock LoadTextdraws()
{
    tCountDown = TextDrawCreate(321.000000, 411.000000, "");
    TextDrawAlignment(tCountDown, 2);
    TextDrawBackgroundColor(tCountDown, 255);
    TextDrawFont(tCountDown, 2);
    TextDrawLetterSize(tCountDown, 0.319999, 1.400000);
    TextDrawColor(tCountDown, -1);
    TextDrawSetOutline(tCountDown, 0);
    TextDrawSetProportional(tCountDown, 1);
    TextDrawSetShadow(tCountDown, 1);
    TextDrawSetSelectable(tCountDown, 0);
    return 1;
}

stock ShowEnterMapName(playerid)
{
    new string[144];
    strcat(string, "{FFFFFF}Please enter the name of the map below.");
    return ShowPlayerDialog(playerid, DIALOG_MAP_NAME, DIALOG_STYLE_INPUT, "{FFFF00}Add Map: Map Name", string, "Submit", "Close");
}

stock ShowEnterMapPosition(playerid)
{
    new string[256];
    strcat(string, "{FFFFFF}Please enter the position of the map's spawn below.\n");
    strcat(string, "Example: {9C00FF}0.0 0.0 0.0 0.0, 0.0, 0.0, 0.0, 0.0\n");
    strcat(string, "or 0.0,0.0,0.0,0.0 (x, y, z, angle).\n\n");
    strcat(string, "{FF0000}Using the wrong syntax might cause issues.");
    return ShowPlayerDialog(playerid, DIALOG_MAP_POSITION, DIALOG_STYLE_INPUT, "{FFFF00}Add Map: Map Position", string, "Submit", "Back");
}

stock ShowAddMapConfirmation(playerid)
{
    new string[256], temp[128];
    strcat(string, "{FFFFFF}You are about to add a new map.\n");
    format(temp, sizeof(temp), "- Name: %s\n", pNewMapString[playerid][MAP_INFO_NAME]);
    strcat(string, temp);
    format(temp, sizeof(temp), "- Position: %s\n\n", pNewMapString[playerid][MAP_INFO_POSITION]);
    strcat(string, temp);
    strcat(string, "Are these fields correct?");
    return ShowPlayerDialog(playerid, DIALOG_MAP_CONFIRMATION, DIALOG_STYLE_MSGBOX, "{FFFF00}Add Map: Confirmation", string, "Yes", "No");
}

stock ShowMaps(playerid)
{
    new title[128], string[300], pages = GetPageCount(MAX_PAGE_RESULTS, gMapCount), resultcount = ((MAX_PAGE_RESULTS * pLastPage[playerid]) - MAX_PAGE_RESULTS), bool:nextpage = false;
    strcat(string, "ID\tName\tVotes");

    for(new i = resultcount; i < gMapCount; i ++)
    {
        resultcount ++;
        if(resultcount <= MAX_PAGE_RESULTS * pLastPage[playerid])
        {
            format(string, sizeof(string), "%s\n%d\t%s\t%s", string, resultcount, aMapInfo[i][map_name], ConvertToAmount(aMapInfo[i][map_votes]));
        }
        else if(resultcount > MAX_PAGE_RESULTS * pLastPage[playerid])
        {
            nextpage = true;
            break;
        }
    }

    if(IsPlayerVoting(playerid))
    {
        format(title, sizeof(title), "{414DE9}Maps - Page %s of %s", ConvertToAmount(pLastPage[playerid]), ConvertToAmount(pages));

        if(nextpage) return ShowPlayerDialog(playerid, DIALOG_MAP_VOTE, DIALOG_STYLE_TABLIST_HEADERS, title, string, "Options", "Next");
        ShowPlayerDialog(playerid, DIALOG_MAP_VOTE, DIALOG_STYLE_TABLIST_HEADERS, title, string, "Options", "");
    }
    else
    {
        format(title, sizeof(title), "{414DE9}Maps - Page %s of %s", ConvertToAmount(pLastPage[playerid]), ConvertToAmount(pages));

        if(nextpage ) return ShowPlayerDialog(playerid, DIALOG_MAP_LIST, DIALOG_STYLE_TABLIST_HEADERS, title, string, "Next", "Close");
        ShowPlayerDialog(playerid, DIALOG_OK, DIALOG_STYLE_TABLIST_HEADERS, title, string, "Close", "");
    }
    return 1;
}

stock ShowMapVoteOptions(playerid)
{
    new title[128], string[256];
    format(string, sizeof(string), "{FFFFFF}Vote for map\n");
    format(string, sizeof(string), "%sPrevious page\n", string);
    format(string, sizeof(string), "%sNext page", string);

    format(title, sizeof(title), "{414DE9}Map: %s", aMapInfo[pMap[playerid]][map_name]);
    return ShowPlayerDialog(playerid, DIALOG_MAP_VOTE_OPTIONS, DIALOG_STYLE_LIST, title, string, "Select", "Back");
}

stock ConvertToAmount(value)
{
    new string[128], count = -1;
    valstr(string, value);

    for(new i = strlen(string); i > 0; i --)
    {
        count++;
        if(count == 3)
        {
            strins(string, ",", i);
            count = 0;
        }
    }
    return string;
}

stock ReplaceString(search[], replace[], source[])
{
    new string[256], length;
    for(new i = 0; i < strlen(source); i ++)
    {
        if(strlen(search) > 1 && i != (strlen(source) - 1))
        {
            new bool:match = false, start = i;
            for(new j = 0; j < strlen(search) && !match; j ++)
            {
                if(source[i] != search[j] && j == 0)
                {
                    string[length] = source[i];
                    match = true;
                }
                else
                {
                    if(source[i] == search[j]) i ++;
                    else match = true;
                }
            }

            if(match == true)
            {
                while(start <= i)
                {
                    string[length] = source[start];
                    length ++;
                    start ++;
                }
            }
            else
            {
                for(new j; j < strlen(replace); j ++)
                {
                    string[length] = replace[j];
                    length ++;
                }

                i = (start + (strlen(search) - 1));
            }
        }
        else
        {
            if(strlen(search) == 1 && source[i] == search[0])
            {
                for(new j; j < strlen(replace); j ++)
                {
                    string[length] = replace[j];
                    length ++;
                }
            }
            else
            {
                string[length] = source[i];
                length ++;
            }
        }
    }

    string[length] = EOS;
    return string;
}

function bool:IsPlayerVoting(playerid) return sVoting[playerid];

function MapVoting()
{
    new string[144];
    if(gVoteCountDown > 0)
    {
        if(gLeadingMap == 0 && gTopVotes == 0)
        {
            format(string, sizeof(string), "~r~MAP VOTING: ~y~%s~n~~p~~h~N/A (N/A votes)", ConvertToAmount(gVoteCountDown));
        }
        else
        {
            format(string, sizeof(string), "~r~MAP VOTING: ~y~%s~n~~p~~h~%s (%s %s)", ConvertToAmount(gVoteCountDown), aMapInfo[gLeadingMap][map_name], \
            ConvertToAmount(aMapInfo[gLeadingMap][map_votes]), plural_singular(aMapInfo[gLeadingMap][map_votes], "vote", "votes"));
        }

        TextDrawSetString(tCountDown, string);
        TextDrawShowForAll(tCountDown);
    }
    else if(gVoteCountDown == 0)
    {
        foreach(new i: Player)
        {
            ShowPlayerDialog(i, -1, DIALOG_STYLE_MSGBOX, " ", " ", " ", " ");
        }

        if(gLeadingMap == 0 && gTopVotes == 0)
        {
            format(string, sizeof(string), "~r~NEXT MAP:~n~~p~~h~Random (0 votes)");
        }
        else
        {
            format(string, sizeof(string), "~r~NEXT MAP:~n~~p~~h~%s (%s %s)", aMapInfo[gLeadingMap][map_name], ConvertToAmount(aMapInfo[gLeadingMap][map_votes]), \
            plural_singular(aMapInfo[gLeadingMap][map_votes], "vote", "votes"));
        }

        TextDrawSetString(tCountDown, string);
        TextDrawShowForAll(tCountDown);
    }
    else if(gVoteCountDown <= -3)
    {
        TextDrawHideForAll(tCountDown);
        KillTimer(gtmMapVoting);

        new selected;
        if(gLeadingMap == 0 && gTopVotes == 0) selected = random(gMapCount);
        else selected = gLeadingMap;

        GameTextForAll("Loading Map...", 5000, 5);

        foreach(new i: Player)
        {
            TogglePlayerControllable(i, false);
            SetPlayerPos(i, aMapInfo[selected][map_x], aMapInfo[selected][map_y], aMapInfo[selected][map_z]);
            SetPlayerFacingAngle(i, aMapInfo[selected][map_angle]);
            SetCameraBehindPlayer(i);

            KillTimer(gtmLoadMap);
            gtmLoadMap = SetTimer("LoadMap", 5000, false);
        }
    }

    gVoteCountDown --;
    return 1;
}

function LoadMap()
{
    GameTextForAll("Map Loaded!", 3000, 5);

    foreach(new i: Player)
    {
        TogglePlayerControllable(i, true);
    }
    return 1;
}

function ChangeMap()
{
    if(gMapCount > 0)
    {
        gTopVotes = 0;
        gLeadingMap = 0;

        for(new i = 0; i < gMapCount; i ++)
        {
            aMapInfo[i][map_votes] = 0;
        }

        foreach(new i: Player)
        {
            sVoting[i] = true;
            pLastPage[i] = 1;
            ShowMaps(i);
        }

        gVoteCountDown = VOTE_INTERVAL;

        KillTimer(gtmMapVoting);
        gtmMapVoting = SetTimer("MapVoting", 1000, true);
    }
    return 1;
}
So, basically you can add server-called maps (name and position), let people vote and then bring them there after an interval has surpassed itself. You can also force them to vote for a map. Example: "DM event coming up: Vote for a map!" and then they have to vote; otherwise, other actions will be taken once the interval is over, depending whether they voted or not.

So what you do is create a group of objects with the dynamic map system and as an add-on with the map voting system you can make it so it loads that group of objects which composes a server map and let the system do the rest.

If you do not want to, then it's all good. It would a great addition, though.
Reply


Messages In This Thread
Dynamic Map System - by Abagail - 26.07.2015, 16:08
Re: Dynamic Map System - by TwinkiDaBoss - 26.07.2015, 19:42
Re: Dynamic Map System - by SickAttack - 26.07.2015, 19:59
Re: Dynamic Map System - by Abagail - 26.07.2015, 21:01
Re: Dynamic Map System - by ognyanov - 26.07.2015, 21:46
Re: Dynamic Map System - by Abagail - 26.07.2015, 22:57
Re: Dynamic Map System - by RedLabel - 30.07.2015, 12:26
Re: Dynamic Map System - by dominik523 - 30.07.2015, 17:35
Re: Dynamic Map System - by Abagail - 30.07.2015, 23:19
Re: Dynamic Map System - by Chaprnks - 12.04.2017, 00:08
Re: Dynamic Map System - by Inceptio - 14.04.2017, 17:43

Forum Jump:


Users browsing this thread: 6 Guest(s)