Просмотр полной версии : [Вопрос] Убийство командой
vovandolg
08.04.2016, 06:28
Есть же /sethp и ей подобные, так вот что я хочу сделать.
Надо так чтобы килл другого игрока командой засчитало ещё и кто убил, не просто переменные забить как делается,
а прогнать каким то образом через калбэк OnPlayerDeath(playerid, killerid, reason);
Если юзать выдачу HP и сразу калбэк то получается абракадабра вплоть до багов или киков от фейк киллов,
если юзать чисто OnPlayerDeath то не че не происходит(оно и ежу понятно он вызывается при смерти, а не для смерти),
это вообще реализуемо или я только зря теряю время?
А теперь ещё раз и по-русски
vovandolg
08.04.2016, 07:33
ааа...
когда убиваешь стволом другого игрока срабатывает OnPlayerDeath
когда сетаешь хп другой игрок помирает от INVALID_PLAYER_ID
а мне надо сделать в команде(и в одном паблике потом ещё) имитацию убийства,
что Вася убил Петю и на выбор чем он убил...
ааа...
когда убиваешь стволом другого игрока срабатывает OnPlayerDeath
когда сетаешь хп другой игрок помирает от INVALID_PLAYER_ID
а мне надо сделать в команде(и в одном паблике потом ещё) имитацию убийства,
что Вася убил Петю и на выбор чем он убил...
Ну вот сама функция
stock FakeKill(killer, killee, weaponid)//killer - ID убийцы | killee - ID умершего игрока.
{
if(!IsPlayerConnected(killer))//Если убийца не подключён
{
SendDeathMessage(INVALID_PLAYER_ID, killee, WEAPON_DROWN);//Указываем про самоубийство
return 0;
}
if(!IsPlayerConnected(killee))//Если убитый не подключён
{
return -1;
}
else
{
SendDeathMessage(killer, killee, weaponid);
//И тут остальные действия, связанные с убийством (выдача денег/работа с другими переменными)
}
return 1;
}
Использование:
FakeKill(ID_убийцы, ID_убитого, ID_оружия);
Пример использования:
CMD:fakekill(playerid,params[])
{
new killer,
killee,
weaponid;
if(!sscanf(params, "iii", killer, killee, weaponid))
return SendClientMessage(playerid, 0x0000FFFF, "Использование: {FFFFFF}/kill <ID убийцы> <ID убиваемого игрока> <ID оружия>");
if(FakeKill(killer, killee, weaponid) == -1) return SendClientMessage(playerid, 0xFF0000FF, "Ошибка: {FFFFFF}ID, который вы указали в качестве убийцы, не подключён");
SendClientMessage(playerid, 0x0000FFFF, "Использование: {FFFFFF}Вы совершили фейковое убийство");
return 1;
}
Функция возвращает:
-1 - если убитый игрок не подключён (никаких действий не произойдёт)
0 - если убийца не подключён (отправит в чат сообщение о суициде
1 - если оба игрока подключены (отправит сообщение о убийстве
vovandolg
08.04.2016, 09:50
Мне надо чтобы при сетании на ноль калбэк OnPlayerDeath прогоняло весь, а не вывод мессэйджа о смерти)
Так как в этом калбэке много инфы в посмертии, а такие мелочи я и сам могу сделать)
TheMallard
08.04.2016, 10:01
Могу предположить что можно завести спец-переменную для таких случаев и записать админа-убийцу.
Типа:
public OnPlayerDeath(...)
{
new my_killerid;
if(p_info[playerid][killedByAdmin] != -1)
my_killerid = p_info[playerid][killedByAdmin];
else
my_killerid = killerid;
.....
}
https://wiki.sa-mp.com/wiki/CallRemoteFunction_RU
https://wiki.sa-mp.com/wiki/CallLocalFunction_RU это не проще?
TheMallard
08.04.2016, 10:08
Тогда уж легче напрямую вызвать, но зачем два раза вызывать калбэк?
Тогда уж легче напрямую вызвать, но зачем два раза вызывать калбэк?
Вызывая напрямую можно всю динамическую память забить, если быть кривожопомруком. А если ты не кривожопорук, то напрямую точно не будешь вызывать:) Мое предложение итак бред, понял это как только нажал на кномпку "отправить сообщение", после установки нуль-ХП игроку он умрет и колбэк OnPlayerDeath выполнится, после чего еще раз выполнится (CallLocalFunction) и оба раза с разными аргументами:) Нужен костыль с перехватами и подменой аргументов.
Добавлено:
Такая последовательность событий мне пришла в голову, состоит из 5-ти шагов.
шаг 1:
new
player_killerid [MAX_PLAYERS],
player_reason [MAX_PLAYERS]
;
шаг 2:
CMD: kill()
{
PlayerFakeDeath (params [0], playerid, params [1]) // в params [0] ид убитого в [1] причина (оружие).
}
шаг 3:
PlayerFakeDeath (playerid, killerid, reason)
{
SetPlayerHealth (playerid, 0.0);
player_killerid [playerid] = killerid;
player_reason [playerid] = reason;
}
шаг 4
public OnPlayerDeath (playerid, killerid, reason)
{
if (player_killerid [playerid] != 0xFFFF)
killerid = player_killerid [playerid];
if (player_reason [playerid] != 0xFF)
reason = player_reason [playerid];
//ваш код
}
шаг 5
public OnPlayerSpawn (playerid)
{
player_killerid [playerid] = 0xFFFF;
player_reason [playerid] = 0xFF;
//ваш код
}
и лучше перестраховаться проверкой на INVALID_PLAYER_ID, дабы избежать выхода за пределы массивов player_killerid и player_reason
vovandolg
08.04.2016, 11:39
Могу предположить что можно завести спец-переменную для таких случаев и записать админа-убийцу.
Типа:
public OnPlayerDeath(...)
{
new my_killerid;
if(p_info[playerid][killedByAdmin] != -1)
my_killerid = p_info[playerid][killedByAdmin];
else
my_killerid = killerid;
.....
}
Такое тоже умеем)
Вот только в паблике этого калбэка свои проверки и переменные которые обязательны к воспроизведению при такой смерти)
Вызывая напрямую можно всю динамическую память забить, если быть кривожопомруком. А если ты не кривожопорук, то напрямую точно не будешь вызывать:)
У меня вызов идёт из команды и в посмертии от сетания, рекурсии не будет, единственное что калбэк срабатывает два раза,
Позже вечерком ещё тестану как замыслил, отпишусь...
- - - Добавлено - - -
Как бы так вам толком объяснить чтобы не писали лишний мусор,
игрок умирает и идёт запись в аргументы OnPlayerDeath(playerid, killerid, reason);
При сетании идут аргументы самоубийства или поцеловал землю вроде того и убийца 0xFFFF,
а мне нужно чтобы в аргументы писануло кто и как убил, вот и вызываю второй раз этот калбэк!:pleasantry:
я ведь написал пример, скорее всего рабочий:)
PlayerFakeDeath (3, 5, 38); //получаем - игрок с идом 5 убил игрока с идом 3 из минигана
аргументы в том-же порядке что и в OnPlayerDeath, для удобства
vovandolg
08.04.2016, 12:03
Версия как и у DeimoS, но мысля появилась кое какая.
Разве что сделать так
stock __death_public(playerid,killerid,reason)
{
//весь код из паблика сюда
}
public OnPlayerDeath(playerid, killerid, reason)
{
if(!GetPVarInt(playerid,"DD"))
{
DeletePVar(playerid,"DD");
__death_public(playerid,killerid,reason);
}
return 1;
}
//А в команде флаг pvar
if(amount <= 0.0)
{
SetPVarInt(playerid,"DD",1);
__death_public(playerid,killerid,reason);//и тут указывать что на ум придёт)
}
SetPlayerHealth(plaerid, amount);
Так меньше нагрузки будет я думаю)
Версия как и у DeimoS, но мысля появилась кое какая.
Разве что сделать так
stock __death_public(playerid,killerid,reason)
{
//весь код из паблика сюда
}
public OnPlayerDeath(playerid, killerid, reason)
{
if(!GetPVarInt(playerid,"DD"))
{
DeletePVar(playerid,"DD");
__death_public(playerid,killerid,reason);
}
return 1;
}
//А в команде флаг pvar
if(amount <= 0.0)
{
SetPVarInt(playerid,"DD",1);
__death_public(playerid,killerid,reason);//и тут указывать что на ум придёт)
}
SetPlayerHealth(plaerid, amount);
Так меньше нагрузки будет я думаю)
Именно это я и подразумевал под
//И тут остальные действия, связанные с убийством (выдача денег/работа с другими переменными)
Вывод сообщения о смерти - лишь копирование тех действий, которые бы произошли при обычной смерти, если у тебя DM мод с килл-листом. Да и просто пример.
Либо можно просто продублировать код коллбэка OnPlayerDeath в команде. Точнее, только то, что тебе нужно будет.
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot