Активный
- Тема Автор
- #1
Руководство по созданию системы банд с территориями, войнами и иерархией участников.
Структура данных банды
Создание банды
Вступление в банду
Выход из банды
Система территорий
Захват территории
Ганг-чат
Команды управления бандой
Обновление территорий
Сохранение данных банды
Система банд добавляет глубину игровому процессу с территориальными войнами и командной игрой.
Структура данных банды
Код:
enum GangInfo
{
gName[32],
gTag[8],
gColor,
gLeader[MAX_PLAYER_NAME],
gMembers,
gTerritories,
gWins,
gLosses,
Float:gSpawnX,
Float:gSpawnY,
Float:gSpawnZ,
gInterior
}
new GangData[20][GangInfo];
new TotalGangs = 0;
new PlayerGang[MAX_PLAYERS] = {-1, ...};
new PlayerGangRank[MAX_PLAYERS];
Создание банды
Код:
CreateGang(name[], tag[], color, Float:x, Float:y, Float:z, interior)
{
if(TotalGangs >= sizeof(GangData))
{
return -1;
}
strcpy(GangData[TotalGangs][gName], name, 32);
strcpy(GangData[TotalGangs][gTag], tag, 8);
GangData[TotalGangs][gColor] = color;
GangData[TotalGangs][gSpawnX] = x;
GangData[TotalGangs][gSpawnY] = y;
GangData[TotalGangs][gSpawnZ] = z;
GangData[TotalGangs][gInterior] = interior;
GangData[TotalGangs][gMembers] = 0;
GangData[TotalGangs][gTerritories] = 0;
GangData[TotalGangs][gWins] = 0;
GangData[TotalGangs][gLosses] = 0;
TotalGangs++;
return TotalGangs - 1;
}
Вступление в банду
Код:
JoinGang(playerid, gangid)
{
if(gangid < 0 || gangid >= TotalGangs)
{
return 0;
}
if(PlayerGang[playerid] != -1)
{
SendClientMessage(playerid, -1, "Вы уже состоите в банде");
return 0;
}
PlayerGang[playerid] = gangid;
PlayerGangRank[playerid] = 0;
GangData[gangid][gMembers]++;
new string[128];
format(string, sizeof(string), "Вы вступили в банду: %s [%s]", GangData[gangid][gName], GangData[gangid][gTag]);
SendClientMessage(playerid, GangData[gangid][gColor], string);
SetPlayerColor(playerid, GangData[gangid][gColor]);
return 1;
}
Выход из банды
Код:
LeaveGang(playerid)
{
if(PlayerGang[playerid] == -1)
{
return 0;
}
new gangid = PlayerGang[playerid];
new name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
// Проверка на лидера
if(strcmp(GangData[gangid][gLeader], name) == 0)
{
SendClientMessage(playerid, -1, "Лидер не может покинуть банду. Используйте /disband");
return 0;
}
GangData[gangid][gMembers]--;
PlayerGang[playerid] = -1;
PlayerGangRank[playerid] = 0;
SetPlayerColor(playerid, 0xFFFFFFFF);
new string[128];
format(string, sizeof(string), "Вы покинули банду: %s", GangData[gangid][gName]);
SendClientMessage(playerid, -1, string);
return 1;
}
Система территорий
Код:
enum TerritoryInfo
{
Float:tMinX,
Float:tMinY,
Float:tMaxX,
Float:tMaxY,
tOwner,
tCaptureProgress,
tCapturingGang
}
new TerritoryData[50][TerritoryInfo];
new TotalTerritories = 0;
new PlayerInTerritory[MAX_PLAYERS] = {-1, ...};
CreateTerritory(Float:minX, Float:minY, Float:maxX, Float:maxY)
{
if(TotalTerritories >= sizeof(TerritoryData))
{
return -1;
}
TerritoryData[TotalTerritories][tMinX] = minX;
TerritoryData[TotalTerritories][tMinY] = minY;
TerritoryData[TotalTerritories][tMaxX] = maxX;
TerritoryData[TotalTerritories][tMaxY] = maxY;
TerritoryData[TotalTerritories][tOwner] = -1;
TerritoryData[TotalTerritories][tCaptureProgress] = 0;
TerritoryData[TotalTerritories][tCapturingGang] = -1;
TotalTerritories++;
return TotalTerritories - 1;
}
IsPlayerInTerritory(playerid, territoryid)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
if(x >= TerritoryData[territoryid][tMinX] && x <= TerritoryData[territoryid][tMaxX] &&
y >= TerritoryData[territoryid][tMinY] && y <= TerritoryData[territoryid][tMaxY])
{
return 1;
}
return 0;
}
Захват территории
Код:
ProcessTerritoryCapture(playerid)
{
if(PlayerGang[playerid] == -1)
{
return 0;
}
new gangid = PlayerGang[playerid];
new territoryid = -1;
// Поиск территории
for(new i = 0; i < TotalTerritories; i++)
{
if(IsPlayerInTerritory(playerid, i))
{
territoryid = i;
break;
}
}
if(territoryid == -1)
{
PlayerInTerritory[playerid] = -1;
return 0;
}
PlayerInTerritory[playerid] = territoryid;
// Если территория уже принадлежит банде игрока
if(TerritoryData[territoryid][tOwner] == gangid)
{
return 0;
}
// Если никто не захватывает
if(TerritoryData[territoryid][tCapturingGang] == -1)
{
TerritoryData[territoryid][tCapturingGang] = gangid;
TerritoryData[territoryid][tCaptureProgress] = 0;
}
// Если захватывает другая банда
if(TerritoryData[territoryid][tCapturingGang] != gangid)
{
TerritoryData[territoryid][tCaptureProgress] = 0;
TerritoryData[territoryid][tCapturingGang] = gangid;
}
// Подсчет участников банды в территории
new gangMembers = 0;
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i) && PlayerGang[i] == gangid && IsPlayerInTerritory(i, territoryid))
{
gangMembers++;
}
}
// Прогресс захвата
TerritoryData[territoryid][tCaptureProgress] += gangMembers;
if(TerritoryData[territoryid][tCaptureProgress] >= 100)
{
CaptureTerritory(territoryid, gangid);
}
new string[128];
format(string, sizeof(string), "~w~Захват территории: ~r~%d%%", TerritoryData[territoryid][tCaptureProgress]);
GameTextForPlayer(playerid, string, 1000, 3);
return 1;
}
CaptureTerritory(territoryid, gangid)
{
new oldOwner = TerritoryData[territoryid][tOwner];
if(oldOwner != -1)
{
GangData[oldOwner][gTerritories]--;
GangData[oldOwner][gLosses]++;
}
TerritoryData[territoryid][tOwner] = gangid;
TerritoryData[territoryid][tCaptureProgress] = 0;
TerritoryData[territoryid][tCapturingGang] = -1;
GangData[gangid][gTerritories]++;
GangData[gangid][gWins]++;
new string[256];
format(string, sizeof(string), "~g~Территория захвачена бандой %s [%s]!", GangData[gangid][gName], GangData[gangid][gTag]);
SendClientMessageToAll(GangData[gangid][gColor], string);
return 1;
}
Ганг-чат
Код:
CMD:g(playerid, params[])
{
if(PlayerGang[playerid] == -1)
{
SendClientMessage(playerid, -1, "Вы не состоите в банде");
return 1;
}
new message[128];
if(sscanf(params, "s[128]", message))
{
SendClientMessage(playerid, -1, "Использование: /g [сообщение]");
return 1;
}
new gangid = PlayerGang[playerid];
new name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
new string[256];
format(string, sizeof(string), "[%s] %s: %s", GangData[gangid][gTag], name, message);
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i) && PlayerGang[i] == gangid)
{
SendClientMessage(i, GangData[gangid][gColor], string);
}
}
return 1;
}
Команды управления бандой
Код:
CMD:creategang(playerid, params[])
{
if(PlayerInfo[playerid][pAdmin] < 5)
{
SendClientMessage(playerid, -1, "У вас нет доступа");
return 1;
}
new name[32], tag[8], color;
if(sscanf(params, "s[32]s[8]d", name, tag, color))
{
SendClientMessage(playerid, -1, "Использование: /creategang [название] [тег] [цвет]");
return 1;
}
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
new gangid = CreateGang(name, tag, color, x, y, z, GetPlayerInterior(playerid));
if(gangid != -1)
{
new string[128];
format(string, sizeof(string), "Банда '%s' создана (ID: %d)", name, gangid);
SendClientMessage(playerid, -1, string);
}
return 1;
}
CMD:joingang(playerid, params[])
{
new gangid;
if(sscanf(params, "d", gangid))
{
SendClientMessage(playerid, -1, "Использование: /joingang [id банды]");
return 1;
}
JoinGang(playerid, gangid);
return 1;
}
CMD:leavegang(playerid, params[])
{
LeaveGang(playerid);
return 1;
}
CMD:ganginfo(playerid, params[])
{
if(PlayerGang[playerid] == -1)
{
SendClientMessage(playerid, -1, "Вы не состоите в банде");
return 1;
}
new gangid = PlayerGang[playerid];
new string[512];
format(string, sizeof(string),
"Информация о банде: %s [%s]\n\n\
Лидер: %s\n\
Участников: %d\n\
Территорий: %d\n\
Побед: %d\n\
Поражений: %d",
GangData[gangid][gName],
GangData[gangid][gTag],
GangData[gangid][gLeader],
GangData[gangid][gMembers],
GangData[gangid][gTerritories],
GangData[gangid][gWins],
GangData[gangid][gLosses]
);
ShowPlayerDialog(playerid, DIALOG_GANG_INFO, DIALOG_STYLE_MSGBOX, "Информация о банде", string, "Закрыть", "");
return 1;
}
Обновление территорий
Код:
public OnPlayerUpdate(playerid)
{
if(PlayerGang[playerid] != -1)
{
ProcessTerritoryCapture(playerid);
}
return 1;
}
Сохранение данных банды
Код:
SaveGangData(gangid)
{
new query[512];
format(query, sizeof(query),
"UPDATE gangs SET name = '%e', tag = '%e', color = %d, leader = '%e', members = %d, territories = %d, wins = %d, losses = %d, spawnx = %.2f, spawny = %.2f, spawnz = %.2f, interior = %d WHERE id = %d",
GangData[gangid][gName],
GangData[gangid][gTag],
GangData[gangid][gColor],
GangData[gangid][gLeader],
GangData[gangid][gMembers],
GangData[gangid][gTerritories],
GangData[gangid][gWins],
GangData[gangid][gLosses],
GangData[gangid][gSpawnX],
GangData[gangid][gSpawnY],
GangData[gangid][gSpawnZ],
GangData[gangid][gInterior],
gangid
);
mysql_query(g_SQL, query);
return 1;
}
Система банд добавляет глубину игровому процессу с территориальными войнами и командной игрой.