Поджигание - смерть - фраг

Тема в разделе "Программирование / Скриптинг", создана пользователем iamdss, 15 июл 2015.

  1. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    По просьбам игроков добавил к стрелам, выпущенным из арбалета, пламя. Использовал штатную функцию SM. Стрелы горят, воткнувшиеся стрелы наносят урон огнём, а при попадании по игрокам - поджигают их:

    Код:
    public OnPlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
    {
    	new client = GetClientOfUserId(GetEventInt(event, "userid"));
    	new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
    	if (IsValidClient(client) && IsValidClient(attacker))
    	{
    		decl String:AllWeapon[20];
    		GetClientWeapon(attacker, AllWeapon, 20);
    		if (StrEqual("weapon_crossbow", AllWeapon, false))
    		{
    			IgniteEntity(client, 1.5);
    		}
    	}
    }
    Но если игрок не был добил атакующим, а умер от догорания, фраг атаковавшему не засчитывается, игрок совершает суицид. Как засчитать фраг тому, кто поджёг? И есть ли способы поджигания лучше штатной IgniteEntity?
     
  2. gibs

    gibs Фитиль народного волненья

    Сообщения:
    536
    Симпатии:
    133
    env_fire . Если урон наносишь от этой ентити, то через сдк хукс заменяй атакующего.
     
    iamdss, AlmazON и Danyas нравится это.
  3. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Какими функциями?
     
  4. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    iamdss, в SDKHooks в SDKHook_OnTakeDamage есть &iAttacker это значит что передается ссылка на оригинальное значение, тоесть прямая адресация. Просто делаешь iAttacker = iEntity.
    Это если я верно понял.
    Еще урон наносить можно так: https://sm.alliedmods.net/api/index.php?fastload=show&id=1028&
    И так просто указываешь свою ентити
     
    iamdss нравится это.
  5. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Дошли руки, вроде разобрался.

    Код:
    public OnClientPutInServer(client)  
    {
    	SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
    }
    
    public Action:OnTakeDamage(client, &attacker, &inflictor, &Float:damage, &damagetype)  
    {
    	decl String:classname[64]; 
    	GetEntityClassname(attacker, classname, sizeof(classname)); 
    	if(StrEqual(classname, "entityflame", false))
    	{
    		inflictor = attacker;
    		attacker = GetEntPropEnt(attacker, Prop_Send, "m_hOwnerEntity");
    		return Plugin_Changed;
    	}
    	return Plugin_Continue;  
    }
    Надеюсь, всё верно. Как протестирую, отпишу.

    Добавлено через 32 минуты
    Проверил. Не срабатывает. Без изменений. Видимо, я неверно понял сей коллбек... Поправьте меня, кому не трудно.
     
    Последнее редактирование: 17 июл 2015
  6. gibs

    gibs Фитиль народного волненья

    Сообщения:
    536
    Симпатии:
    133
    Убивай ентити огня не сразу, а через какое-то время. Вероятно. в логи сыпет ошибки, что ентити не валидная. Но а так, в принципе, правильно. Урон точно наносится от env_fire?
    Нанесение урона обычно получается на следующем фрейме, так как сперва проходят всякие трассировки и прочее. Я так лично несколько раз заменял атакующего. К тому же, если взять параметры коллбека с вейпоном, то можно заменить сам вейпон, и в прэ хуке player_death заменять оружие для отображения нужной иконки в худе.
     
    iamdss нравится это.
  7. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Я использую стандартную SM функцию IgniteEntity с таймингом 1,5 секунды:

    Код:
    public OnPlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
    {
    	new client = GetClientOfUserId(GetEventInt(event, "userid"));
    	new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
    	if (IsValidClient(client) && IsValidClient(attacker))
    	{
    		decl String:AllWeapon[20];
    		GetClientWeapon(attacker, AllWeapon, 20);
    		if (StrEqual("weapon_crossbow", AllWeapon, false))
    		{
    			IgniteEntity(client, 1.5);
    		}
    	}
    }

    Поэтому урон приходит от энтити класса entityflame и убивать вручную её не требуется. Нужно непременно воспользоваться env_fire?

    Спасибо, действительно, ошибки. Поправил.

    Было бы отлично. Не найдётся куска кода? Обычно не прошу готовый, но это для меня пока китайская азбука.
     
  8. gibs

    gibs Фитиль народного волненья

    Сообщения:
    536
    Симпатии:
    133
    Если ты используешь стандартный игнайт, то для меня реально большая загадка что значит "GetEntPropEnt(attacker, Prop_Send, "m_hOwnerEntity");". Ты сам овнера устанавливал? Что ты пытаешься вытянуть? Вернёт ведь -1.
    Проблема не в китайской азбуке, или чем бы оно тебе не казалось. Проблема в том, что ты стараешься не думать то, что ты делаешь)))
     
    iamdss нравится это.
  9. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Немного оффтопа:
    Трудно думать в отсутствие нормальной документации. Сурсмодовская вики комментирует функции крайне скудно (я как бы и так догадываюсь, что, например IgniteEntity - Ignites an entity on fire), нет кросслинков, нет примеров кода. Впрочем, и за это им спасибо. Я привык к нормальной документации, из которой можно почерпнуть всё, что нужно. Пример - msdn. К тому же, я не сишник, в противном случае, мне было бы удобнее собрать свой вариант сервера ДМ из исходников, которые открыты. Но SM имеет один плюс - переносимость. Хотя всё равно это костыли. Мышки плакали, кололись, но продолжали жрать кактус ©


    Действительно. Только сейчас я это понял. Владельца-то нет. Вот тут, кстати, ещё один вопрос. Как установить ему владельца? И возможно ли? Догадываюсь, что невозможно. В принципе, из кусков кода с форума я собрал поджигание и буду тестировать вечером, наверное, это было бы будет даже лучше.

    И ещё вопрос. Могу ли я присваивать сущностям произвольные поля? Это очень полезно, если надо прицепить к сущности какую-то дополнительную информацию, чтобы не хранить её в переменных сурсмода и не заботиться о памяти.

    Вопросы ещё будут, заглядывайте иногда =) Спасибо за помощь.
     
  10. gibs

    gibs Фитиль народного волненья

    Сообщения:
    536
    Симпатии:
    133
    Ну есть сдк, и вики валвовская. Всё довольно понятно даже на интуитивном уровне. Все коллбеки всегда имеются в .inc файле, их никто просто так с потолка не берёт.
     
    iamdss нравится это.
  11. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    PHP:
    SetEntPropEnt(entityProp_Send"m_hOwnerEntity"client); 
    Вроде как нет.
    Но если это что-то простое, типа индекса то можно запилит в тагрейт нейм
     
    iamdss нравится это.
  12. Reiko1231

    Reiko1231 AlexTheRegent

    Сообщения:
    235
    Симпатии:
    568
    Не гарантирую работу в HL2DM, но в CSS вроде как работает:
    Код:
    // в игрока попали с нужного нам оружия
    	...
    	// поджигаем клиента
    	IgniteEntity(iClient, 2.0);
    	// после этого к игроку добавляется эффект огня, который мы получаем
    	new iFireEntity = GetEntPropEnt(iClient, Prop_Data, "m_hEffectEntity");
    	// устанавливаем ему овнера, кто его поджег
    	SetEntPropEnt(iFireEntity, Prop_Data, "m_hOwnerEntity", iAttacker);
    	...
    
    // перед событием "игрок умер" (player_death, EventHookMode_Pre)
    public Action:Ev_PlayerDeath(Handle:hEvent, const String:sEvName[], bool:bDontBroadcast)
    {
    	// получаем оружие, которым его убили
    	decl String:sWeapon[64]; GetEventString(hEvent, "weapon", sWeapon, sizeof(sWeapon));
    	// если это entityflame
    	if ( strcmp(sWeapon, "entityflame") == 0 ) {
    		// получаем самого игрока, получаем эффект на нем (огонь), и владельца этого эффекта
    		new iClient = GetClientOfUserId(GetEventInt(hEvent, "userid")),
    			iFireEntity = GetEntPropEnt(iClient, Prop_Data, "m_hEffectEntity"),
    			iFireOwner = GetEntPropEnt(iFireEntity, Prop_Data, "m_hOwnerEntity");
    		
    		// если владелец эффекта игрок и он на сервере
    		if ( iFireOwner > 0 && iFireOwner <= MaxClients && IsClientInGame(iFireOwner) ) {
    			// устанавливаем убийцу вручную
    			SetEventInt(hEvent, "attacker", GetClientUserId(iFireOwner));
    			// меняем оружие убийства, если это необходимо, для отображения в правом верхнем углу
    			SetEventString(hEvent, "weapon", "awp");
    		}
    	}
    	return Plugin_Continue;
    }
    
    Вроде как нет. Будет ошибка, что такое поле не найдено. Но у некоторых сущностей есть поля, которые наверное не используются, и в них можно что-нибудь хранить. Находятся методом тыка, например, prop_dynamic имеет такое поле "m_PredictableID" в ксс, но если в ксго это поле изменить, то слетают некоторые настройки объекта, и в целом этим лучше не пользоваться.
     
    iamdss, AlmazON и R1KO нравится это.
  13. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.505
    Симпатии:
    1.961
    Строковые поля (из smlib):
    PHP:
    stock Entity_SetParentName(entity, const String:name[], any:...)
    {
        
    decl String:format[128];
        
    VFormat(formatsizeof(format), name3);
        
    DispatchKeyValue(entity"parentname"format);
    }
    stock Entity_SetGlobalName(entity, const String:name[], any:...)
    {
        
    decl String:format[128];
        
    VFormat(formatsizeof(format), name3);
        
    DispatchKeyValue(entity"globalname"format);
    }
    stock Entity_SetTargetName(entity, const String:name[], any:...)
    {
        
    decl String:format[128];
        
    VFormat(formatsizeof(format), name3);
        
    DispatchKeyValue(entity"target"format);
    }
    stock Entity_SetName(entity, const String:name[], any:...)
    {
        
    decl String:format[128];
        
    VFormat(formatsizeof(format), name3);
        
    DispatchKeyValue(entity"targetname"format);
    }
    А return Plugin_Changed;? Всё-таки событие изменяем (внутри функции стоило дописать).
     
    iamdss нравится это.
  14. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    Не знал что при IgniteEntity ентити огня устанавливается клиенту в m_hEffectEntity.
    Это пригодится.
     
    iamdss нравится это.
  15. gibs

    gibs Фитиль народного волненья

    Сообщения:
    536
    Симпатии:
    133
    Функция игнайта автоматом ставит.
     
    iamdss нравится это.
  16. iamdss

    iamdss

    Сообщения:
    117
    Симпатии:
    0
    Спасибо за ценную информацию, материала более чем достаточно. Отпишу по результатам.

    Добавлено через 3 часа 56 минут
    Проверил. Похоже, это:

    или не так работает в ДМ, или в ДМ другой параметр ивента отвечает за килл. Игрок умирает, в HUD отображается верно, но килл не засчитывается. Сейчас попытаюсь найти что-то в документации.

    Это верно, но не работает. Если возвращаем Plugin_Changed, то ни в HUD не отображается убийство, ни фраг не засчитывается. Как будто ничего не меняли. Я затрудняюсь сказать, почему так.

    Добавлено через 5 часов 21 минуту
    В принципе, с фрагами всё просто, выдаю вручную:

    Код:
    val = GetClientFrags(attacker);
    SetEntProp(attacker, Prop_Data, "m_iFrags", val + 1);
    
    val = GetClientDeaths(client);
    SetEntProp(client, Prop_Data, "m_iDeaths", val + 1);
    Не знаю, насколько я угадал, но это работает.

    На вопрос про Plugin_Changed ответа не нашёл. Без него всё работает правильно, как ни странно.

    А можно ли управлять свойствами огня, созданного через IgniteEntity?
     
    Последнее редактирование: 17 июл 2015