Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Урок Gang Zone Wars by MadeMan

Статус
В этой теме нельзя размещать новые ответы.

ShiftFX

Дебютант
Банды

Код:
#define TEAM_GROVE 1
#define TEAM_BALLAS 2
#define TEAM_VAGOS 3

Создание новых зон


Код:
enum eZone
{
	Float:zMinX,
	Float:zMinY,
	Float:zMaxX,
	Float:zMaxY,
	zTeam
}
new ZoneInfo[][eZone] = {
	{2337.9004,-1808.8383,2590.2043,-1610.3673,TEAM_GROVE},
	{2084.7,-1808.8383,2337.9004,-1610.3673,TEAM_BALLAS},
	{2590.2043,-1808.8383,2842.3,-1610.3673,TEAM_VAGOS}
};
new ZoneID[sizeof(ZoneInfo)];
Я создал 3 зоны, 1 для каждой команды.
Давайте посмотрим на первую
Код:
{2337.9004,-1808.8383,2590.2043,-1610.3673,TEAM_GROVE},
Если вы посмотрите на перечисление, вы видите, что означает, что каждое число.

2337.9004 - zMinX
-1808.8383 - ZMinY
2590.2043 - zMaxX
-1610.3673 - ZMaxY
TEAM_GROVE - zTeam

Координаты zMinX, zMinY, zMaxX, zMaxY используются в функции GangZoneCreate для создания зон.

Вы должны создать зону банды в OnGameModeInit или в OnFilterScriptInit, если вы делаете filterscript.

Код:
for(new i=0; i < sizeof(ZoneInfo); i++)
{
	ZoneID[i] = GangZoneCreate(ZoneInfo[i][zMinX], ZoneInfo[i][zMinY], ZoneInfo[i][zMaxX], ZoneInfo[i][zMaxY]);
}
Вы также должны показать ганг зоны игроку. Вы можете сделать это в OnPlayerSpawn.

Код:
for(new i=0; i < sizeof(ZoneInfo); i++)
{
	GangZoneShowForPlayer(playerid, ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam]));
}
Кроме того, необходима функцию GetTimeZoneColor

Код:
stock GetTeamZoneColor(teamid)
{
	switch(teamid)
	{
		case TEAM_GROVE: return 0x00FF0088;
		case TEAM_BALLAS: return 0xFF00FF88;
		case TEAM_VAGOS: return 0xFFFF0088;
	}
	return -1;
}
Обратите внимание, что я добавил 88 до конца цветов. Это свидетельствует о прозрачности. Если вы хотите, чтобы сделать зоны более прозрачной, используйте меньшие значения, как 55. Если вы хотите, чтобы сделать зоны менее прозрачным, используйте большие значения, как АА.

Теперь ганг зоны должны работать.

Добавление новых зон

Если вы хотите добавить больше зон, вам нужно получить координаты.
Вы можете сделать это с помощью сохранения [комментарий] команды / в любом сервере SA-MP или в режиме отладки.
Просто зайдите в игру и найдите место для зоны банды.


Вы должны использовать / сохранить в 2-х местах: в пункте 1 и пункта 2 (см рисунок):
1. Перейдите к пункту 1 и сделайте "/save example min"
2. Перейдите на пункт 2 и сделайте "/save example max"

Тогда вы должны иметь строки в Мои документы \ GTA San Andreas User Files \ SAMP \ savedpositions.txt

Код:
AddPlayerClass(107,1429.3770,-1732.4554,13.3828,355.2560,0,0,0,0,0,0); // example min
AddPlayerClass(107,1529.1932,-1592.1989,13.3828,90.5102,0,0,0,0,0,0); // example max
Вам нужно только эти координаты

Код:
1429.3770,-1732.4554
1529.1932,-1592.1989
Так что если вы хотите добавить зону для Grove, у вас есть все то, что вам нужно, чтобы создать новую зону банды

1429.3770 - zMinX
-1732.4554 - ZMinY
1529.1932 - zMaxX
-1592.1989 - ZMaxY
TEAM_GROVE - zTeam

Затем добавьте эту строку в ZoneInfo

Код:
{1429.3770,-1732.4554,1529.1932,-1592.1989,TEAM_GROVE}
Таким образом, ZoneInfo должен выглядеть следующим образом

Код:
new ZoneInfo[][eZone] = {
	{2337.9004,-1808.8383,2590.2043,-1610.3673,TEAM_GROVE},
	{2084.7,-1808.8383,2337.9004,-1610.3673,TEAM_BALLAS},
	{2590.2043,-1808.8383,2842.3,-1610.3673,TEAM_VAGOS},
	{1429.3770,-1732.4554,1529.1932,-1592.1989,TEAM_GROVE}
};
Атака зон

Теперь, когда у вас есть ваши зоны размещены, давайте сделаем их уязвимыми.

Во-первых, мы должны сделать некоторые дополнения к нашему коду.

Добавьте эти новые глобальные переменные

Код:
new ZoneAttacker[sizeof(ZoneInfo)] = {-1, ...};
new ZoneAttackTime[sizeof(ZoneInfo)];
Если война продолжается, зона должна мигать. Сделайте эти изменения в OnPlayerSpawn

Код:
for(new i=0; i < sizeof(ZoneInfo); i++)
{
	GangZoneShowForPlayer(playerid, ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam]));
	if(ZoneAttacker[i] != -1) GangZoneFlashForPlayer(playerid, ZoneID[i], GetTeamZoneColor(ZoneAttacker[i]));
}
Есть много способов начать капт, но я покажу вам 2 из них.

Атака зон #1


Для того, чтобы начать войну, вы должны иметь некоторых члены команды на вражеской зоне.

Нам потребуются некоторые дефайны и стоки функций

Код:
#define TAKEOVER_TIME 120 // сколько секунд нужно, чтобы взять на себя зону
#define MIN_MEMBERS_TO_START_WAR 3 // сколько членов банды, необходимых в зоне, чтобы начать войну
Определим их так, что они могут быть легко изменены позже.

Код:
new Teams[] = {
	TEAM_GROVE,
	TEAM_BALLAS,
	TEAM_VAGOS
};
Нам нужно сделать массив всех наших команд, чтобы потом использовать его в петлю. Добавим все команды здесь.

Код:
stock IsPlayerInZone(playerid, zoneid)
{
	new Float:x, Float:y, Float:z;
	GetPlayerPos(playerid, x, y, z);
	return (x > ZoneInfo[zoneid][zMinX] && x < ZoneInfo[zoneid][zMaxX] && y > ZoneInfo[zoneid][zMinY] && y < ZoneInfo[zoneid][zMaxY]);
}

stock GetPlayersInZone(zoneid, teamid)
{
	new count;
	for(new i=0; i < MAX_PLAYERS; i++)
	{
	    if(IsPlayerConnected(i) && GetPlayerTeam(i) == teamid && IsPlayerInZone(i, zoneid))
	    {
			count++;
	    }
	}
	return count;
}
Настроим таймер в OnGameModeInit или OnFilterScriptInit, если вы делаете filterscript.

Код:
SetTimer("ZoneTimer", 1000, true);
Добавим публичную функцию времени

Код:
public ZoneTimer()
{
	for(new i=0; i < sizeof(ZoneInfo); i++) // loop all zones
	{
		if(ZoneAttacker[i] != -1) // zone is being attacked
		{
			if(GetPlayersInZone(i, ZoneAttacker[i]) >= MIN_MEMBERS_TO_START_WAR) // team has enough members in the zone
			{
				ZoneAttackTime[i]++;
				if(ZoneAttackTime[i] == TAKEOVER_TIME) // zone has been under attack for enough time and attackers take over the zone
				{
					GangZoneStopFlashForAll(ZoneID[i]);
					ZoneInfo[i][zTeam] = ZoneAttacker[i];
					GangZoneShowForAll(ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam])); // update the zone color for new team
					ZoneAttacker[i] = -1;
				}
			}
			else // attackers failed to take over the zone
			{
				GangZoneStopFlashForAll(ZoneID[i]);
				ZoneAttacker[i] = -1;
			}
		}
		else // check if somebody is attacking
		{
			for(new t=0; t < sizeof(Teams); t++) // loop all teams
			{
				if(Teams[t] != ZoneInfo[i][zTeam] && GetPlayersInZone(i, Teams[t]) >= MIN_MEMBERS_TO_START_WAR) // if there are enough enemies in the zone
				{
					ZoneAttacker[i] = Teams[t];
					ZoneAttackTime[i] = 0;
					GangZoneFlashForAll(ZoneID[i], GetTeamZoneColor(ZoneAttacker[i]));
				}
			}
		}
	}
}
Готово. Теперь, если есть достаточно врагов в зоне, война начнется и продлится пока враги не покинули зону или не истекло время, чтобы захватить зону.

Zone Attack #2

Для того, чтобы начать войну, вам нужно убить несколько врагов на вражеской зоне.

Нам потребуются некоторые дефайны

Код:
#define TAKEOVER_TIME 120 // сколько секунд нужно, чтобы взять на себя зону
#define MIN_DEATHS_TO_START_WAR 3 // сколько членов банды должны быть убиты в зоне, чтобы начать войну
Определим их так, что они могут быть легко изменены позже.

Настройка таймера в OnGameModeInit или OnFilterScriptInit, если вы делаете filterscript.

Код:
SetTimer("ZoneTimer", 1000, true);
Добавим публичную функцию времени (не забудьте передать его)

Код:
public ZoneTimer()
{
	for(new i=0; i < sizeof(ZoneInfo); i++) // loop all zones
	{
		if(ZoneAttacker[i] != -1) // zone is being attacked
		{
			if(GetPlayersInZone(i, ZoneAttacker[i]) >= 1) // there must be at least 1 attacker left
			{
				ZoneAttackTime[i]++;
				if(ZoneAttackTime[i] == TAKEOVER_TIME) // zone has been under attack for enough time and attackers take over the zone
				{
					GangZoneStopFlashForAll(ZoneID[i]);
					ZoneInfo[i][zTeam] = ZoneAttacker[i];
					GangZoneShowForAll(ZoneID[i], GetTeamZoneColor(ZoneInfo[i][zTeam])); // update the zone color for new team
					ZoneAttacker[i] = -1;
				}
			}
			else // attackers failed to take over the zone
			{
				GangZoneStopFlashForAll(ZoneID[i]);
				ZoneAttacker[i] = -1;
			}
		}
	}
}
Теперь нам нужно, чтобы вызвать атаку в OnPlayerDeath

Код:
if(IsPlayerConnected(killerid) && GetPlayerTeam(playerid) != GetPlayerTeam(killerid)) // not a suicide or team kill
{
	new zoneid = GetPlayerZone(playerid);
	if(zoneid != -1 && ZoneInfo[zoneid][zTeam] == GetPlayerTeam(playerid)) // zone member has been killed in the zone
	{
		ZoneDeaths[zoneid]++;
		if(ZoneDeaths[zoneid] == MIN_DEATHS_TO_START_WAR)
		{
			ZoneDeaths[zoneid] = 0;
			ZoneAttacker[zoneid] = GetPlayerTeam(killerid);
			ZoneAttackTime[zoneid] = 0;
			GangZoneFlashForAll(ZoneID[zoneid], GetTeamZoneColor(ZoneAttacker[zoneid]));
		}
	}
}
Нам также нужна глобальная смертность зоне переменной и функции GetPlayerZone.

Код:
new ZoneDeaths[sizeof(ZoneInfo)];
Код:
stock GetPlayerZone(playerid)
{
	for(new i=0; i < sizeof(ZoneInfo); i++)
	{
		if(IsPlayerInZone(playerid, i))
		{
			return i;
		}
	}
	return -1;
}
Готово. Теперь, если там было достаточно убийств в зоне, война начнется и продлится пока враги не покинули капт или пока не закончилось время, чтобы захватить его.


Конец
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу