Кодим функции: Счетчик смертей

  • Автор темы Автор темы Илья
  • Дата начала Дата начала

Илья

Друзья CG
25 Сен 2015
2,348
41
Допустим, есть код, ну или часть кода:

Код:
chek = 0

function main:InitGameMode()
ListenToGameEvent("entity_killed", Dynamic_Wrap(main, "OnHeroKilled"), self)	
end

 function main:OnHeroKilled (data)
	local killedEntity = EntIndexToHScript(data.entindex_killed)
	local number = killedEntity:GetTeamNumber()
	local name = GetTeamName(number)
	if name == "#DOTA_GoodGuys" then
	chek = chek + 1
	end
 end

Вопрос такой: можно ли сделать проще/красивее?
Мне дико не нравится то, что этот код будет проверять смерти всех юнитов. Естественно, это плохо....
Я пробовал через dota_player_killed, но мне не известны все возможные функции, которые я бы мог использовать с data от-туда, поэтому завернул так, как есть. Может, подскажете выход?

Суть кода в том, чтобы он отсчитывал смерти, в данном случае, хороших ребят. Зачем мне это нужно? В будущем моде думаю сделать победу по убийству всех противников (выкуп и перерождение отключены)
Конечно, вы можете сказать про функцию PlayerResource:GetTeamKills, но увы, она засчитывает лишь смерть от рук героя, а если крип убьет игрока, она не добавит очка и может случиться ситуация, когда из 5и противников игроки сами убьют 4х, а последнего убьет крип и все, игра не закончится.
 
Последнее редактирование модератором:
Re: Счетчик смертей

Нашел я решение. Дабы проветриться, далее последует мини-гайд-рассуждения тем, кто не является прогером и столкнулся с подобной моей проблемой:



Сумев отыскать описание всех переменных всех событий , я узнал, что же я могу использовать при событии
"dota_player_killed":
z21VHKL.png


Мгм, выбор невелик: всего три переменные, да и по сути всего одна полезная мне - PlayerID.

Тип данных: short - не помню, для чего он нужен в программировании, смысл в том, что это не типичный для большинства функций lua integer - целый.
Лады, хоть что-то.

Смотрим в код: при смерти entiti все делают так:
Код:
 local killedEntity = EntIndexToHScript(data.entindex_killed)

То есть, локальной переменной killedEntity присваивают какой-то нев....нный тип данных, другими словами, создают неопознанный мною объект. Что ж, опознаем его в этом месте.

Зная о методе EntIndexToHScript(), обращаем внимание на то, что он возвращает
3DNRths.png

Ага, handle - рукоять, в гугл переводчике.

Хорошо, значит, нужно с помощью PlayerID, что имеет тип short, получить handle. Ищем, ищем и находим:
5kVP9so.png

Жаль только, что нужен integer тип данных, а у нас short. Ну, не уверен, правильно ли я помню момент с преобразованием типов (что-то вроде, при преобразовании long в int мы теряем хвостик циферки, ибо int меньше вмещает байтиков, но да short то короче int, а значит, должно проканать!), но авось пронесет, пробуем.

Только не забываем заглядывать в шапочку методов и глазеть, с чем их едят:
RFNnBrl.png

Получаем следующую строчку:
Код:
local killedEntity = PlayerResource:GetPlayer(data.PlayerID)

Ну и все заработало, в общем.
То есть теперь код работает только лишь в случае "dota_player_killed":
Код:
 ListenToGameEvent("dota_player_killed", Dynamic_Wrap(HDG, "OnHeroKilled"), self)
И не грузит систему лишними проверками при убийстве сторонних нпц.
.
.
.
.
.​

Однако, есть еще один интересный, как по мне, способ. Гораздо хитрожопее:

Берем наш
Код:
local id = data.PlayerID

Глазеем на привлекательный метод
04NEfLH.png
Тут, конечно, просят какой-то iPlayerID, но да он же все равно int. С пивом пойдет. Находится он все там же в PlayerResource:
Код:
local number = PlayerResource:GetTeam(id)

Ну и собственно, завершаем все так же, как и всегда:
Код:
local name = GetTeamName(number)


Вот итоговых два варианта функции в полном объеме:
Код:
counterDeathsGG = 0
counterDeathsBG = 0


function HDG:InitGameMode()
  ListenToGameEvent("dota_player_killed", Dynamic_Wrap(HDG, "OnHeroKilled"), self)
end


function HDG:OnHeroKilled (data)

	local killedEntity = PlayerResource:GetPlayer(data.PlayerID)
	local number = killedEntity:GetTeamNumber()
	local name = GetTeamName(number)
	
	if name == "#DOTA_GoodGuys" then
	counterDeathsGG = counterDeathsGG + 1
	end
	if name == "#DOTA_BadGuys" then
	counterDeathsBG = counterDeathsBG + 1
	end
	
 end


Код:
counterDeathsGG = 0
counterDeathsBG = 0


function HDG:InitGameMode()
  ListenToGameEvent("dota_player_killed", Dynamic_Wrap(HDG, "OnHeroKilled"), self)
end

function HDG:OnHeroKilled (data)
	local number = PlayerResource:GetTeam(data.PlayerID)
	local name = GetTeamName(number)
	
	if name == "#DOTA_GoodGuys" then
	counterDeathsGG = counterDeathsGG + 1
	end
	if name == "#DOTA_BadGuys" then
	counterDeathsBG = counterDeathsBG + 1
	end
	
 end

Как видно, более хитрожопый метод на одну строчку меньше, но он, возможно, хуже по правилам этикета использования методов. Так же можно по идеи намутить что-то вроде
Код:
	local number = (PlayerResource:GetPlayer(data.PlayerID)):GetTeamNumber()
В первом методе, но не так красиво, как если бы использовали две переменные.
 
Последнее редактирование модератором:
Реклама: