DeathMatch_Beta

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #1
Хочу переписать DM. Чтобы не обсуждать это дело здесь (т.к. это немного другой плагин), предлагаю делать этот тут.

Что имеется на данный момент:
  1. Автоматическое возрождение игроков при смерти (с задержкой в пол секунды)
  2. Удаление трупов после смерти
  3. Защиту при появлении игрока
  4. Удаление зон покупки оружия.
  5. Автоматическое пополнение патронов.

Что планируется добавить:
  1. Меню оружия при спавне.
  2. Удаление оружия при выбрасывании и смерти.
  3. Автоматический баланс игроков.
  4. Запрет конца раунда.
  5. Удаление заложников.

На все перечисленные функции будут введены переменные, для того, чтобы каждый мог настроить всё под себя.

Последняя на данный момент версия кода:

PHP:
#pragma semicolon 1
#include <sourcemod>
#include <cstrike>
#include <sdktools>

new Handle:Timer_Respawn[MAXPLAYERS+1] = {INVALID_HANDLE, ... },
	Handle:Timer_Dissolve[MAXPLAYERS+1] = {INVALID_HANDLE, ... },
	Handle:Timer_Protect[MAXPLAYERS+1] = {INVALID_HANDLE, ... };
	
new Handle:g_Dissolve_Enabled = INVALID_HANDLE,
	Handle:g_NoBuyZone_Enabled = INVALID_HANDLE;

new bool:g_dissolve_enabled,
	bool:g_nobuyzone_enabled,
	bool:g_spawn_protect;

new g_ActiveWepOffs = -1;

public Plugin:myinfo = 
{
	name = "DeathMatch",
	author = "R1KO & KorDen",
	version = "1.0",
	url = "http://hlmod.ru"
};

public OnPluginStart()
{
	CreateConVar("cssdm_version", "2.1.6-compat", "Fake cvar for monitors", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
	g_Dissolve_Enabled = CreateConVar("dm_dissolve_enabled", "1", "Включить/Выключить расстворение трупов.");
	g_NoBuyZone_Enabled = CreateConVar("dm_nobuyzone_enabled", "1", "Включить/Выключить запрет зон закупок.");
	g_Spawn_Protect = CreateConVar("dm_spawn_protect", "1.0", "Время защиты игрока при спавне (0 - отключено).");
	HookEvent("player_death", OnPlayerDeath);
	HookEvent("player_spawn", OnPlayerSpawn);
	HookEvent("player_team", OnPlayerTeam);
	g_ActiveWepOffs = FindSendPropOffs("CCSPlayer", "m_hActiveWeapon"); 
	if (g_ActiveWepOffs > 0) 
	{ 
		HookEvent("weapon_reload", Event_CheckDepleted); 
		HookEvent("weapon_fire_on_empty", Event_CheckDepleted); 
	}
}

public OnMapStart()
{
	//---------------
    g_dissolve_enabled  = GetConVarBool(g_Dissolve_Enabled);
    g_nobuyzone_enabled = GetConVarBool(g_NoBuyZone_Enabled);
    g_spawn_protect = GetConVarFloat(g_Spawn_Protect);

	//----------------
	if(g_nobuyzone_enabled)
    {
		new i = -1;
		while ((i = FindEntityByClassname(i, "func_buyzone")) != -1)
		{
			if (IsValidEntity(i)) AcceptEntityInput(i, "Kill");
	}
} 

public Event_CheckDepleted(Handle:event, const String:name[], bool:dontBroadcast) 
{ 
	new client = GetClientOfUserId(GetEventInt(event, "userid")); 
	new entity = GetEntDataEnt2(client, g_ActiveWepOffs); 
	if (entity > 0) SetEntProp(client, Prop_Data, "m_iAmmo", 200, 4, GetEntProp(entity, Prop_Data, "m_iPrimaryAmmoType")); 
} 

public OnPlayerTeam(Handle:event, const String:name[], bool:silent)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if (client > 0)
	{
		new team = GetEventInt(event, "team");
		if (team > 1)
			Timer_Respawn[client] = CreateTimer(1.0, f_Respawn, client);
		else
			KillTimerS(client);
	}
}

public OnPlayerSpawn(Handle:event, const String:name[], bool:silent)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if (client > 0)
	{
		if(g_spawn_protect > 0)
		{
			SetEntProp(client, Prop_Data, "m_takedamage", 0);
			team = GetClientTeam(client);
			if (team == 2) SetNewColor(client, 255, 75, 75, 200);
			else if (team==3) SetNewColor(client, 75, 75, 255, 200);
			Timer_Protect[client] = CreateTimer(g_spawn_protect, ProtectTimer_CallBack, client);
		}
	}
}

public Action:ProtectTimer_CallBack(Handle:timer, any:client)
{
	if (IsClientInGame(client) && IsPlayerAlive(client))
	{
		SetEntProp(client, Prop_Data, "m_takedamage", 2);
		SetNewColor(client, 255, 255, 255, 255);
	}
	// Timer_Protect[client] = INVALID_HANDLE;
	KillTimer(Timer_Protect[client]);
}

SetNewColor(client, r, g, b, a)
{
	SetEntityRenderMode(client, RENDER_TRANSCOLOR);
	SetEntityRenderColor(client, r, g, b, a);
}

public OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if(g_dissolve_enabled)
	{
		if (IsValidEntity(client) && IsClientInGame(client))
		{
			new ragdoll = GetEntPropEnt(client, Prop_Send, "m_hRagdoll");
			if(ragdoll > 0)
			{
				new Handle:datapack = INVALID_HANDLE;
				Timer_Dissolve[client] = CreateDataTimer(2.0, f_Dissolve, datapack, TIMER_FLAG_NO_MAPCHANGE);
				WritePackCell(datapack, ragdoll);
				WritePackCell(datapack, client);
				ResetPack(datapack);
			}
		}
	}
	Timer_Respawn[client] = CreateTimer(3.0, f_Respawn, client);
}

public Action:f_Dissolve(Handle:timer, Handle:datapack)
{
	new ragdoll = ReadPackCell(datapack);
	new client = ReadPackCell(datapack);
	if(IsValidEntity(ragdoll))
		AcceptEntityInput(ragdoll, "kill");
	// Timer_Dissolve[client] = INVALID_HANDLE;
	KillTimer(Timer_Dissolve[client]);
}

public Action:f_Respawn(Handle:timer, any:client)
{
	//Timer_Respawn[client] = INVALID_HANDLE;
	KillTimer(Timer_Respawn[client]);
	if (IsClientInGame(client) && !IsPlayerAlive(client))
		CS_RespawnPlayer(client);
}

public OnClientDisconnect(client)
	KillTimerS(client);

KillTimerS(client)
{
	if (Timer_Respawn[client] != INVALID_HANDLE)
	{
		KillTimer(Timer_Respawn[client]);
		Timer_Respawn[client] = INVALID_HANDLE;
	}
	if (Timer_Dissolve[client] != INVALID_HANDLE)
	{
		KillTimer(Timer_Dissolve[client]);
		Timer_Dissolve[client] = INVALID_HANDLE;
	}
	if (Timer_Protect[client] != INVALID_HANDLE)
	{
		KillTimer(Timer_Protect[client]);
		Timer_Protect[client] = INVALID_HANDLE;
	}
}

Свои пожелания/предложения/обнаруженные баги отписывать ниже.
 
Последнее редактирование:

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
1. Удаление зон покупок
PHP:
public OnMapStart()
{
	new i = -1;
	while ((i = FindEntityByClassname(i, "func_buyzone")) != -1)
	{
		if (IsValidEntity(i))
		{
			AcceptEntityInput(i, "Kill");
		}
	}
}

2. Значения переменные получи при старте карты и сохрани их, затем используй

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

4. При возрождении игрока рано получаешь команду игрока

5. Остальное в старой теме, исправь
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Из планов:
"Меню оружия при спавне."
Предлагаю переписать CSS:DM Equipment - нужно оставить такое же меню

"Автоматическое пополнение патронов."
У меня уже есть, хотя там есть нюансы (для оптимизации всем оружиям дается 200 патронов, меньше проверок, а смысла в них ведь нет, и так бесконечные же фактически) но в целом я могу переписать полноценно.

"Удаление оружия при выбрасывании и смерти."
Можно взять из скажем Weapon Cleanup код

"Автоматический баланс игроков."
Опять же, есть плагины баланса на DM.

"Запрет конца раунда."
Не надо. На большинстве DM стоит Stripper: Source и он с этой задачей справляется гораздо лучше.

Вообще я хотел бы чтобы такой DM был модульный, а не монолитным плагином. Монолит уже есть на AM, и это выглядит бредово.
Если сделать модульную систему - тогда можно будет как раз делать кобинации, например, для Knife DM - только ядро, для каких-то других модов - скажем aim_ - без модуля оружия и так далее.

Стоит сделать отключение дезинтеграции трупов, так как скажем на моем x64 сервере это уже отход от оптимизации
Стоит оптимизировать код в плане получения значений переменных etc
 
  • Мне нравится
Реакции: R1KO

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #4
1. Сделал
2. Есть
3. Вроде сделал.
4. Исправил
 
Последнее редактирование:

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
2. Эм.. глупый вопрос: как ? ))
Создаешь глобальную переменную, при старте плагина получаешь значение (GetConVarFloat, Bool, Int, String) переменной (CreateConVar), приравниваешь (Твой квар = полученный результат), используешь уже глобальную переменную затем
 
  • Мне нравится
Реакции: R1KO

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #6
"Автоматическое пополнение патронов."
У меня уже есть, хотя там есть нюансы (для оптимизации всем оружиям дается 200 патронов, меньше проверок, а смысла в них ведь нет, и так бесконечные же фактически) но в целом я могу переписать полноценно.
Буду благодарен.

"Удаление оружия при выбрасывании и смерти."
Можно взять из скажем Weapon Cleanup код

"Автоматический баланс игроков."
Опять же, есть плагины баланса на DM.

Хочу вынуть эти функции из плагинов, оптимизировать, добавить/убрать кое-что.
"Запрет конца раунда."
Не надо. На большинстве DM стоит Stripper: Source и он с этой задачей справляется гораздо лучше.
Соглашусь, хотя вообще сам не блокирую конец раунда, мне и так номрально. Это я так, для народа.

Вообще я хотел бы чтобы такой DM был модульный, а не монолитным плагином. Монолит уже есть на AM, и это выглядит бредово.
Если сделать модульную систему - тогда можно будет как раз делать кобинации, например, для Knife DM - только ядро, для каких-то других модов - скажем aim_ - без модуля оружия и так далее.

Когда всё будет хорошо работать, можно разделить, как SMAC.

Стоит сделать отключение дезинтеграции трупов, так как скажем на моем x64 сервере это уже отход от оптимизации
Для этого есть квар.

Стоит оптимизировать код в плане получения значений переменных etc
эм..))

Добавлено через 8 минут
else if (GetEventInt(event, "oldteam") > 0) KillTimerS(client);

Непонимаю зачем.


---------------------------------
Обновил код.

Добавлено через 21 минуту
Удалене оружия (галимый вариант):

PHP:
public OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	new String:weapon[64];
	if ( IsValidEdict(client) && IsValidEntity(client) )
	{
		GetEdictClassname(client, weapon, sizeof(weapon));
		if ( ( StrContains(weapon, "weapon_") != -1 || StrContains(weapon, "item_") != -1 ) && GetEntDataEnt2(i, g_WeaponParent) == -1 )
		RemoveEdict(client);

	}	
	return Plugin_Continue;
}
 
Последнее редактирование:

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Когда всё будет хорошо работать, можно разделить, как SMAC.

Нужно уже изначально закладыать, иначе тогда это ничем не будет отличаться от уже существующих плагинов, если все равно надо будет ковыряться и разделять
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #8
KorDen, на какие части предлагаешь разбить ?
 

SenatoR

Участник
Сообщения
773
Реакции
344
Предлагаю сделать 2-3 основных модуля.
1)Модуль удаления всего и вся (Пленты,заложники,оружие,рагдолы)
2)Сам дематч
3)Модуль оружия
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Базовое пополнение патронов. Два нюанса:
1) Пополняются сразу до 200, даже если это AWP с 30 патронами в запасе. Фактически ведь не важно, но некоторых напрягает... Зато оптимизация на высоте :D
2) Патроны не пополняются, если перезарядка идет при опустошении боймы (пополняется только когда перезарядка через R). Если кончились патроны, можно стрельнуть из пустого оружия (что многие не догадываются сделать) - тут же пополнятся.

Для исправления #2 в оригинале сделана целая куча кода OnPlayerRunCmd, что мне ужасно не нравится по вполне понятным причинам, хотя в принципе можно и реализовать тот метод, но немного проще...

Собственно сам плагин:
PHP:
#include <sourcemod>
new g_ActiveWepOffs = -1;
public OnPluginStart()
{
	g_ActiveWepOffs = FindSendPropOffs("CCSPlayer", "m_hActiveWeapon");
	if (g_ActiveWepOffs > 0)
	{
		HookEvent("weapon_reload", Event_CheckDepleted);
		HookEvent("weapon_fire_on_empty", Event_CheckDepleted);
	}
}
public Event_CheckDepleted(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	new entity = GetEntDataEnt2(client, g_ActiveWepOffs);
	if (entity > 0)
		SetEntProp(client, Prop_Data, "m_iAmmo", 200, 4, GetEntProp(entity, Prop_Data, "m_iPrimaryAmmoType"));
}
 
  • Мне нравится
Реакции: R1KO

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #11
KorDen, добавил в 1-й пост.
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Кстати, я так подумал.. Если действительно разорачивать модульный DeathMatch - может сделать в BitBucket или GitHub?
Мне больше нравится битбакет (hg удобнее по мне, гитхаб ведь только гит.)
Поэтому думаю стоит нам сделать объединенный репозиторий. Пришлите (to DoK и R1KO) мне в личку (или в стим) ваши email, я скину вам инвайты (чтобы больше юзеров для репозитория получить на будущее, и расскажу что можно будет делать интересного. Думаю будет гораздо удобнее.
Кстати рико, добавь меня в стиме (или у тебя его нет? Тогда джаббер или в крайнем случае аська)


UPD:
[
TJNMN9A.png
НУ ТОЧНО, БИТБАКЕТ НАШЕ ВСЕ :DDDD
 
  • Мне нравится
Реакции: R1KO

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #13
Кстати рико, добавь меня в стиме (или у тебя его нет? Тогда джаббер или в крайнем случае аська)
Ахах.. стим акк отдал, остального тоже нет)))
Ладно, попробую найти себе новый стим.
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Прикинул, что с такими идеями можно и серьезный модульный DM забацать :)
Поэтому решил (заодно буду углубляться в системы контроля версий) создать репозиторий - http://hg.sky-play.ru/cs-s-deathmatch-lite - пока там выложены самые простейшие версии ядра (на базе Knife DM), пополнения патронов и DM Bonus. Постепенно думаю вырастем до действительно серьезной системы :)
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #17
Забыл еще вот что, спавн игрока должен быть на разных точках, файлы из обычного дм можно заюзать, если файла нет - стандартные точки.
 

SenatoR

Участник
Сообщения
773
Реакции
344
Про форварды и нативы не забывайте только, иначе хрень у вас получится.
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Про форварды и нативы не забывайте только, иначе хрень у вас получится.

Смотря что брать - не все нужно/имеет смысл делать в нативах... Я хочу постараться плагины сделать как можно более простыми и не зависимыми - таким образом например DM Bonus и автопополнение патронов фактически может без проблем работать и на паблике, и так далее. Там где действительно нужно - они будут, но таких мест на мой взгляд очень мало. Или есть какие-то конкретные идеи?
 
  • Мне нравится
Реакции: R1KO

SenatoR

Участник
Сообщения
773
Реакции
344
Нет, идей на тему дм у меня нету.
Никогда не интересовался данным модом.
Мб чуть позже подкину код с одним из вариантов воскрешения.
 
Сверху Снизу