Создание башни

tasman208

Активный
30 Мар 2016
128
0
Делаю скрипт на создание мини башни на месте игрока предметом вот код для ее спавна, но спавнит он башню не на месте героя а в центре карты, почему так?
Код:
function tower() 
 if _G.team == 1 then
  local player = PlayerResource:GetPlayer(0.5)
  local pos = player:GetAbsOrigin()
  local unit = CreateUnitByName("npc_dota_tower_good", pos, true, nil, nil, DOTA_TEAM_GOODGUYS )
  else
  local player = PlayerResource:GetPlayer(0.5)
  local pos = player:GetAbsOrigin()
  local unit = CreateUnitByName("npc_dota_tower_bad", pos, true, nil, nil, DOTA_TEAM_BADGUYS )
 end   
end
 
Последнее редактирование модератором:
Почему в GetPlayer() указываешь 0.5? Там же id героя нужен.
 
[quote author=tasman208 link=topic=806.msg3292#msg3292 date=1459702610]
Делаю скрипт на создание мини башни на месте игрока предметом вот код для ее спавна, но спавнит он башню не на месте героя а в центре карты, почему так?
Код:
function tower() 
 if _G.team == 1 then
  local player = PlayerResource:GetPlayer(0.5)
  local pos = player:GetAbsOrigin()
  local unit = CreateUnitByName("npc_dota_tower_good", pos, true, nil, nil, DOTA_TEAM_GOODGUYS )
  else
  local player = PlayerResource:GetPlayer(0.5)
  local pos = player:GetAbsOrigin()
  local unit = CreateUnitByName("npc_dota_tower_bad", pos, true, nil, nil, DOTA_TEAM_BADGUYS )
 end   
end
[/quote]
Ты путаешь понятия игрока и героя. Игрок всегда находится в центре карты, и он управляет героем.
Получай героя через
Код:
local hero = player:GetAssignedHero()
а от него бери координаты через hero:GetAbsOrigin()
 
Последнее редактирование модератором:
Переделал, но все равно вышка спавнится в центре карты
Код:
function tower()
 if _G.team == 1 then
 	 local i = 0
 	if PlayerResource:IsValidPlayer(i) then 
  	local player = PlayerResource:GetPlayer(i)
  	local hero = player:GetAssignedHero()
  	local pos = hero:GetAbsOrigin()
  	local unit = CreateUnitByName("npc_dota_tower_good", pos + RandomVector( RandomFloat( 0, 200 ) ), true, nil, nil, DOTA_TEAM_GOODGUYS )
	end
end
end
 
Последнее редактирование модератором:
Скинь где и как ты вызываешь эту функцию.

Ну и сейчас у тебя код проверяет только игрока с индексом 0, а их может быть больше. Но это не должно влиять на твой спавн, нулевой игрок всегда есть.
 
Код:
"item_tower_create"
	{
		"BaseClass"						"item_datadriven"
		"ID"							"2009"	
		"AbilityTextureName"			"item_tower_create"
		"AbilityBehavior"				"DOTA_ABILITY_BEHAVIOR_NO_TARGET"
	
		"AbilityCooldown"				"180"
		
		"ItemKillable"         "1"
		"ItemSellable"         "1"
		"ItemDroppable"         "1"
		"ItemPermanent"					"0"
		
		"ItemCost"						"5000"
		"ItemStackable"					"1"
		"ItemShareability"				"ITEM_FULLY_SHAREABLE_STACKING"
		"ItemInitialCharges"			"1"
	
		"AbilitySpecial"
		{
			"01"
			{
				"var_type"				"FIELD_INTEGER"
				"duration"				"6"
			}
		}
	
		"OnSpellStart"
		{
			"RunScript"
			{
				"ScriptFile"	"script"
				"Function"		"tower"
			}	
			"SpendCharge"
			{}	
		}
	}
И еще вопрос. Как узнать id героя, который использовал предмет, чтобы использовать его тут?
Код:
 function Activate()
  ListenToGameEvent("dota_player_used_ability", OnUsed, nil)
 end
 
 function OnUsed()
  if PlayerResource:IsValidPlayer(0) then
   local player = PlayerResource:GetPlayer(0)
   local num = player:GetTeamNumber() 
   local name = GetTeamName(num)
    if name == "#DOTA_GoodGuys" then
     _G.team = 1
    else
     _G.team = 2
    end
  end
 end
 
Последнее редактирование модератором:
И еще вопрос. Как узнать id героя, который использовал предмет, чтобы использовать его тут?
Ты должен кое что знать о передаче функций в луа, у них есть параметры, так называемые ключи, или они же аргументы события. Их посмотреть можно довольно просто.

В datadriven-скилле/предмете.
Код:
"OnSpellStart"
		{
			"RunScript"
			{
				"ScriptFile"	"script"
				"Function"		"tower"
                "MyArgument1" "5"
                "MyArgument2" "blabla"
                "MyArgument3" "%AbilityDamage"
			}	
			"SpendCharge"
			{}	
		}

Тогда в скрипте мы принимает событие вызова скрипта:
Код:
function tower(keys)
	local arg1 		= keys.MyArgument1 			-- сами передали из datadriven
	local arg2 		= keys.MyArgument2 			-- сами передали из datadriven 
	local art3 		= keys.MyArgument3 			-- сами передали из datadriven
	local caster 	= keys.caster				-- автоматические передает сам datadriven БЕЗ нашего участия
	local ability	= keys.ability				-- автоматические передает сам datadriven БЕЗ нашего участия
	local player	= caster:GetPlayerOwner() 	-- получим игрока отвечающего за кастера, если таковой существует, в противном случае получим nil(нулевой указатель)

	for keyname, keyvalue in pairs(keys) do		-- мы пройдемся по всем передаваемым ключам сюда для их просмотра и вывода их в консоль, вместе с их значениями.
		print(keyname, keyvalue)						
	end


	--[[
	тут другие действия твоей абилки
	]]
end

P.S. Герой(hero) и игрок(player) разные сущности, абсолютно. Игрок не может использовать способности, это делает герой/юнит. Но у игрока есть список подконтрольных ему юнитов.
P.S.S. Если все же нужен айди игрока то используй unit:GetPlayerOwnerID()
 
Последнее редактирование модератором:
С башней не работает так же как с определением команды пишет ошибку при попытке создать башню
[ W VScript ]: Script Runtime Error: ...ota_addons\crusadecommanders\scripts\vscripts\script.lua:87: Parameter type mismatch
[ W VScript ]: stack traceback:
[ W VScript ]: [C]: in function 'GetPlayer'

Вот код
Код:
function tower(keys)
 	if _G.team == 1 then
  local player = PlayerResource:GetPlayer(keys.PlayerID)
  local hero = player:GetAssignedHero()
  local pos = hero:GetAbsOrigin()
  local unit = CreateUnitByName("npc_dota_tower_good", pos + RandomVector( RandomFloat( 0, 200 ) ), true, nil, nil, DOTA_TEAM_GOODGUYS )
  else
  local player = PlayerResource:GetPlayer(keys.PlayerID)
  local hero = player:GetAssignedHero() 
  local pos = hero:GetAbsOrigin()
  local unit = CreateUnitByName("npc_dota_tower_bad", pos + RandomVector( RandomFloat( 0, 200 ) ), true, nil, nil, DOTA_TEAM_BADGUYS )
 end   
end
Что тут нужно передавать в GetPlayer ?
 
Последнее редактирование модератором:
С башней не работает так же как с определением команды пишет ошибку при попытке создать башню

Вот код
Что тут нужно передавать в GetPlayer ?
PlayerResource и ID игрока как аргумент. Я использую так:
Код:
local player = PlayerResource:GetPlayer(playerid)
Думаю у тебя нету Keys.PlayerID, проверь таблицу keys на наличие этого поля.
И блин, зачем ты получаешь героя через игрока. Делай наоборот, тот кто скастовал умение идет всегда как кастер: keys.caster , а если это крип подконтрольный герою то используй keys.caster:GetOwnerEntity() для получения героя, или keys.caster:GetPlayerOwner() что бы получить игрока, или keys.caster:GetPlayerOwnerID() для получения ID игрока.
 
Последнее редактирование модератором:
Мне нужно узнать координаты героя, чтобы перед ним поставить башню, но ничего из этого не дает координаты героя
 
Ох, парень, блин. Даешь огрызок кода и спрашиваешь, что не так. Для полноценной картины нужна вся цепочка: от главного скрипта до тела твоей функции.

Если ты хочешь реализовать предмет, что создает башню в точке: просто реализуешь создание башни через эту точку.

Но ты зачем-то геморойничаешь: делаешь абилку без цели, чтобы она именно перед носом игрока создавала башню. Ладно, хорошо, давай погеморойничаем.

Вот твоя вещь:
Код:
"item_tower_create"
	{
		"BaseClass"					"item_datadriven"
		"ID"							"2009"	
		"AbilityTextureName"				"item_tower_create"
		"AbilityBehavior"					"DOTA_ABILITY_BEHAVIOR_NO_TARGET"
	
		"AbilityCooldown"				"180"
		
		"ItemKillable"         			"1"
		"ItemSellable"         			"1"
		"ItemDroppable"         		"1"
		"ItemPermanent"					"0"
		
		"ItemCost"						"5000"
		"ItemStackable"					"1"
		"ItemShareability"				"ITEM_FULLY_SHAREABLE_STACKING"
		"ItemInitialCharges"				"1"
	
		"OnSpellStart"
		{
			"RunScript"
			{
				"ScriptFile"		"script.lua"
				"Function"		"tower"
			}	

		}
	}


Вот содержимое script.lua:

Код:
function tower(keys)
local pos = keys.caster:GetAbsOrigin() + (keys.caster:GetForwardVector() * 150)

 if _G.team == 1 then
   	 	CreateUnitByName("npc_dota_tower_good", pos), true, nil, nil, DOTA_TEAM_GOODGUYS )
  else
   	 	CreateUnitByName("npc_dota_tower_bad", pos), true, nil, nil, DOTA_TEAM_BADGUYS )
  end
   
end

Все, ничего лишнего. Можно было сделать еще более, гораздо, проще через точку каста.
Спросишь, зачем это: keys.caster:GetForwardVector() * 150 ? Потому что иначе будешь спавнить башню прям под героем.
 
Последнее редактирование модератором:
Если башня все равно не будет создаваться, то дело в твоем if _G.team. Удали его и проверь, работает ли так:

Код:
function tower(keys)
local caster = keys.caster
local pos = caster:GetAbsOrigin() + (caster:GetForwardVector() * 150)

 if caster:GetTeamNumber() == "#DOTA_GoodGuys" then
   	 	CreateUnitByName("npc_dota_tower_good", pos), true, nil, nil, DOTA_TEAM_GOODGUYS )
  else
   	 	CreateUnitByName("npc_dota_tower_bad", pos), true, nil, nil, DOTA_TEAM_BADGUYS )
  end
   
end

Если и так не работает, скидывай лог консоли с ошибкой и постарайся сам отыскать ту строчку, на которую жалуется компилятор. В крайнем случае, скидывай код с пронумерованными строчками!
 
Последнее редактирование модератором:
Первый вариант работает, правда скобка после pos не нужна
Код:
function tower(keys)
local caster = keys.caster
local pos = keys.caster:GetAbsOrigin() + (keys.caster:GetForwardVector() * 150)
 if _G.team == 1 then
   	 	CreateUnitByName("npc_dota_tower_good", pos, true, nil, nil, DOTA_TEAM_GOODGUYS )
  else
   	 	CreateUnitByName("npc_dota_tower_bad", pos, true, nil, nil, DOTA_TEAM_BADGUYS )
  end 
end
Но башня все равно создается в центре
 
Последнее редактирование модератором:
У тебя было
Код:
CreateUnitByName("npc_dota_tower_good", pos), true, nil, nil, DOTA_TEAM_GOODGUYS )
выдало ошибку. Сделал так
Код:
CreateUnitByName("npc_dota_tower_good", pos, true, nil, nil, DOTA_TEAM_GOODGUYS )
Вот из главного мода
Код:
function Activate()
  ListenToGameEvent("dota_player_used_ability", OnUsed, nil)
 end

function OnUsed(keys)
   local player = PlayerResource:GetPlayer(keys.PlayerID)
   local num = player:GetTeamNumber() 
   local name = GetTeamName(num)
    if name == "#DOTA_GoodGuys" then
     _G.team = 1
    else
     _G.team = 2
    end
 end
 
Последнее редактирование модератором:
А, не да, скобку верно убрал.

Это весь твой addon_game_mode.lua?
 
вот весь, не думаю что многое изменится)
Код:
require( 'timers' )
require( 'barebones' )

_G.team = 0
_G.upg = 1
_G.upb = 1
_G.megag = 1
_G.megab = 1
_G.siegeg = 1
_G.siegeb = 1
_G.healg = 1
_G.healb = 1
_G.king = 1
_G.kinb = 1
_G.wolfg = 1
_G.wolfb = 1
_G.golemg = 1
_G.golemb = 1
_G.satyrg = 1
_G.satyrb = 1
_G.skeletg = 1
_G.skeletb = 1
_G.ogreg = 1
_G.ogreb = 1

 function Activate()
  ListenToGameEvent("dota_player_used_ability", OnUsed, nil)
 end

function OnUsed(keys)
   local player = PlayerResource:GetPlayer(keys.PlayerID)
   local num = player:GetTeamNumber() 
   local name = GetTeamName(num)
    if name == "#DOTA_GoodGuys" then
     _G.team = 1
    else
     _G.team = 2
    end
 end
 
Последнее редактирование модератором:
Скинь код вещицы. Если она у тебя одна в npc_items_custom.txt, то весь кидай.

То же самое и с башней.
 
Код:
"npc_dota_tower_good"          // имя нашего юнита
		{
			// General
			//
			"BaseClass"					"npc_dota_tower"	// Класс юнита
			"Model"						"models/props_structures/tower_good.mdl"// Модель
			"SoundSet"					"Tower.Water"					// Название набора эффектов
			"MinimapIcon"				""               // Иконка на мини-карте (по желанию)
			"MinimapIconSize"			"0"
			"ModelScale"				"0.5"
			"Level"						"1"
 
			// Abilities
			//----------------------------------------------------------------
 
			"Ability1"					""			// 1 способность
			"Ability2"					""			// 2 способность
			"Ability3"					""			// 3 способность
			"Ability4"					""			// 4 способность
			"Ability5"					""			// 5 способность
			"Ability6"					""			// 6 способность (Экстра)
			"Ability7"					""			// 7 способность (Экстра)
			"Ability8"					""			// 8 способность (Экстра)
 
			// Защита
			//----------------------------------------------------------------
			"ArmorPhysical"				"10"		// физическая защита
			"MagicalResistance"			"0"			// Магическая защита
 
			// Атака
			//----------------------------------------------------------------
			"AttackCapabilities"		"DOTA_UNIT_CAP_RANGED_ATTACK"
			"AttackDamageMin"			"25"		// Минимальный урон
			"AttackDamageMax"			"30"		// Максимальный урон
			"AttackDamageType"			"DAMAGE_TYPE_ArmorPhysical" // Тип наносимого урона урона(в данном случае физический)
			"AttackRate"				"0.25"			// Скорость атаки
			"AttackAnimationPoint"		"0.0"		// Нормальное время анимации между атаками
			"AttackAcquisitionRange"	"800"		// 
			"AttackRange"				"1150"		// Дальность атаки
			"ProjectileModel"			"particles/base_attacks/ranged_tower_good.vpcf"		// Используемый эффект снаряда(атаки)
			"ProjectileSpeed"			"1250"		// скорость снаряда
 
			// Характеристики(атрибуты, статы как вам угодно)
			//----------------------------------------------------------------
			"AttributePrimary"		"DOTA_ATTRIBUTE_STRENGTH"  //Основная характеристика
			"AttributeBaseStrength"		"0"			// Базовое значение силы
			"AttributeStrengthGain"		"0"			// Бонус силы за каждый лвл
			"AttributeBaseIntelligence"	"0"			// Базовое значение интеллекта
			"AttributeIntelligenceGain"	"0"			// Бонус интеллекта за каждый лвл
			"AttributeBaseAgility"		"0"			// Базовое значение ловкости
			"AttributeAgilityGain"		"0"			// Бонус ловкости за каждый лвл
 
			// Точно не знаю как работает параметр, но возможно =>
			//----------------------------------------------------------------
			"BountyXP"					"5"		// "опыт за убийство юнита"
			"BountyGoldMin"				"5"		// минимальное золото 
			"BountyGoldMax"				"10"		// максимальное золото
 
			// Bounds
			//----------------------------------------------------------------
			"BoundsHullName"			"DOTA_HULL_SIZE_TOWER"			// Hull type used for navigation/locomotion.
			"ProjectileCollisionSize"	"50"
			"RingRadius"				"130"
			"HealthBarOffset"			"260"
 
			// Передвижение
			//----------------------------------------------------------------
			"MovementCapabilities"		"DOTA_UNIT_CAP_MOVE_NONE"			// Тип юнита (наземный или воздушный)
			"MovementSpeed"				"0"			// скорость передвижения
			"MovementTurnRate"			"1.0"			// Turning rate.
 
			// Status
			//----------------------------------------------------------------
			"StatusHealth"				"800"		    // Базовое здоровье
			"StatusHealthRegen"			"10"			// Регенерация в сек.
			"StatusMana"				"0"			// Базовая мана
			"StatusManaRegen"			"0"			// Регенерация в сек.
 
			// Команда
			//----------------------------------------------------------------
			"TeamName"					"DOTA_TEAM_GOODGUYS"			// Имя команды
			"CombatClassAttack"			"DOTA_COMBAT_CLASS_ATTACK_SIEGE"
			"CombatClassDefend"			"DOTA_COMBAT_CLASS_DEFEND_STRUCTURE"
			"UnitRelationshipClass"		"DOTA_NPC_UNIT_RELATIONSHIP_TYPE_BUILDING"
 
			// Дальность обзора
			//----------------------------------------------------------------
			"VisionDaytimeRange"		"1500"		// В дневное время
			"VisionNighttimeRange"		"1500"		// В ночное время
		}

Код:
"item_tower_create"
	{
		"BaseClass"						"item_datadriven"
		"ID"							"2009"	
		"AbilityTextureName"			"item_tower_create"
		"AbilityBehavior"				"DOTA_ABILITY_BEHAVIOR_NO_TARGET"
	
		"AbilityCooldown"				"180"
		
		"ItemKillable"         "1"
		"ItemSellable"         "1"
		"ItemDroppable"         "1"
		"ItemPermanent"					"0"
		
		"ItemCost"						"5000"
		"ItemStackable"					"1"
		"ItemShareability"				"ITEM_FULLY_SHAREABLE_STACKING"
		"ItemInitialCharges"			"1"
	
		"AbilitySpecial"
		{
			"01"
			{
				"var_type"				"FIELD_INTEGER"
				"duration"				"6"
			}
		}
	
		"OnSpellStart"
		{
			"RunScript"
			{
				"ScriptFile"	"script"
				"Function"		"tower"
			}	
			"SpendCharge"
			{}	
		}
	}
 
Последнее редактирование модератором:
У тебя вещь реализована неправильно. Если тот код в game mode, то так:

Код:
"ScriptFile"	"addon_game_mode.lua"
"Function"		"tower"


И убери лишнее, как я тебе писал.
 
Последнее редактирование модератором:
Реклама: