Сегодня я вам расскажу, как можно сделать простые задания С
С помошью данного гайда вы сможете сделать квесты типа:
Я приведу в пример два варианта настройки квеста
Первое задание:
Надеюсь сегодня вы научились, чему-то новому
Если есть какие-то идеи по улучшению гайда, то я готов выслушать !
С помошью данного гайда вы сможете сделать квесты типа:
- Принеси мне палку = дам тебе толкалку
- две кларетки принеси = и мангусик получи
- каждый принесенный меч = улучшаю в убермеч
- в общем можно придумать много чего интересного, зависит только от вашей фантазии
- необходимый предмет для выполнения задания (обязательно)
- необходимое количество предметов(стаков) для выполнения задания от 0 до бесконечности (обязательно)
- количество опыта, даваемое каждому игроку за выполнение задания (опционально)
- количество золота, даваемое каждому игроку за выполнение задания (опционально)
- предмет, даваемый игроку за выполнение задания (опционально)
- нужен ли значок над головой у юнита, дающего задания (опционально), 1-да, 0-нет
- название квеста, который следующим после выполнения(опционально)
- данное задание можно выполнять несколько раз. Взаимоисключает предыдущий пункт (опционально), 1-да, 0-нет
Я приведу в пример два варианта настройки квеста
- в луа файле
- в дд файле
Первое задание:
- необходимый предмет = "clarity potion"
- необходимое количество = 2
- награда опыта = 1500
- награда золота = 750
- награда предмет = "enchanted mango"
- значок над головой = 1(да)
- название следующего квеста = "quest_test2"
- данное задание можно выполнять несколько раз = 0 (нет)
- необходимый предмет = "belt of strength"
- необходимое количество = 1
- награда опыта = 1500
- награда золота = 750
- награда предмет = "ogre axe"
- значок над головой = 0(нет)
- название следующего квеста = nil(нет)
- данное задание можно выполнять несколько раз = 1 (да)
Код:
"npc_dota_test_1"
{
// General
//
"BaseClass" "npc_dota_creature" // Class of entity of link to.
"Model" "models/heroes/chaos_knight/chaos_knight.vmdl" // Model.
"ModelScale" "0.75" // old 1.0
"Level" "5"
// Abilities
//----------------------------------------------------------------
"Ability1" "quest_test1"
// Movement
//----------------------------------------------------------------
"MovementCapabilities" "DOTA_UNIT_CAP_MOVE_GROUND" // Type of locomotion - ground, air
"MovementSpeed" "325" // Speed
"MovementTurnRate" "1" // Turning rate.
//Inventory
"Creature"
{
"AttachWearables"
{
"Wearable1" { "ItemDef" "181" } //Horse
"Wearable2" { "ItemDef" "183" } //Shoulders
"Wearable3" { "ItemDef" "184" } //Helmet
"Wearable4" { "ItemDef" "185" } //Weapon
"Wearable5" { "ItemDef" "186" } //Shield
}
}
}
"npc_dota_test_2"
{
// General
//
"BaseClass" "npc_dota_creature" // Class of entity of link to.
"Model" "models/heroes/chaos_knight/chaos_knight.vmdl" // Model.
"ModelScale" "0.75" // old 1.0
"Level" "5"
// Abilities
//----------------------------------------------------------------
"Ability1" "quest_test01"
// Movement
//----------------------------------------------------------------
"MovementCapabilities" "DOTA_UNIT_CAP_MOVE_GROUND" // Type of locomotion - ground, air
"MovementSpeed" "325" // Speed
"MovementTurnRate" "1" // Turning rate.
//Inventory
"Creature"
{
"AttachWearables"
{
"Wearable1" { "ItemDef" "181" } //Horse
"Wearable2" { "ItemDef" "183" } //Shoulders
"Wearable3" { "ItemDef" "184" } //Helmet
"Wearable4" { "ItemDef" "185" } //Weapon
"Wearable5" { "ItemDef" "186" } //Shield
}
}
}
Код:
"quest_test1"
{
// General
//-------------------------------------------------------------------------------------------------------------
"BaseClass" "ability_lua"
"ScriptFile" "abilities/quest/quest_template"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"AbilityTextureName" "jakiro_liquid_fire"
// Special
//-------------------------------------------------------------------------------------------------------------
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"value_required" "2"
}
"02"
{
"var_type" "FIELD_INTEGER"
"reward_exp" "1500"
}
"03"
{
"var_type" "FIELD_INTEGER"
"reward_gold" "750"
}
}
}
"quest_test2"
{
// General
//-------------------------------------------------------------------------------------------------------------
"BaseClass" "ability_lua"
"ScriptFile" "abilities/quest/quest_template"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"AbilityTextureName" "jakiro_liquid_fire"
// Special
//-------------------------------------------------------------------------------------------------------------
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"value_required" "1"
}
"02"
{
"var_type" "FIELD_INTEGER"
"reward_exp" "1500"
}
"03"
{
"var_type" "FIELD_INTEGER"
"reward_gold" "750"
}
}
}
"quest_test01"
{
// General
//-------------------------------------------------------------------------------------------------------------
"BaseClass" "ability_datadriven"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"AbilityTextureName" "jakiro_liquid_fire"
// Special
//-------------------------------------------------------------------------------------------------------------
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"value_required" "2"
}
"02"
{
"var_type" "FIELD_INTEGER"
"reward_exp" "1500"
}
"03"
{
"var_type" "FIELD_INTEGER"
"reward_gold" "750"
}
}
"OnCreated"
{
"RunScript"
{
"ScriptFile" "abilities/quest/quest_template"
"Function" "OnQuestCreated"
"quest_item" "item_clarity"
"reward_item" "item_enchanted_mango"
"particle" "1"
"next_quest" "quest_test02"
"reusable" "0"
}
}
}
"quest_test02"
{
// General
//-------------------------------------------------------------------------------------------------------------
"BaseClass" "ability_datadriven"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"AbilityTextureName" "jakiro_liquid_fire"
// Special
//-------------------------------------------------------------------------------------------------------------
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"value_required" "1"
}
"02"
{
"var_type" "FIELD_INTEGER"
"reward_exp" "1500"
}
"03"
{
"var_type" "FIELD_INTEGER"
"reward_gold" "750"
}
}
"OnCreated"
{
"RunScript"
{
"ScriptFile" "abilities/quest/quest_template"
"Function" "OnQuestCreated"
"quest_item" "item_belt_of_strength"
"reward_item" "item_ogre_axe"
"particle" "0"
//"next_quest" "quest_test02"
"reusable" "1"
}
}
}
Код:
LinkLuaModifier("modifier_quest_template", "abilities/quest/quest_template", LUA_MODIFIER_MOTION_NONE)
quest_template = class({})
function quest_template:GetIntrinsicModifierName()
return "modifier_quest_template"
end
--------------------------------------------------------
------------------------------------------------------------
modifier_quest_template = class({
IsHidden = function(self) return false end,
IsPurgable = function(self) return false end,
IsDebuff = function(self) return false end,
IsBuff = function(self) return true end,
RemoveOnDeath = function(self) return true end,
GetAttributes = function(self) return MODIFIER_ATTRIBUTE_MULTIPLE end,
})
function modifier_quest_template:OnCreated()
if IsServer() then
local ability = self:GetAbility()
self.value_required = ability:GetSpecialValueFor("value_required")
self.reward_exp = ability:GetSpecialValueFor("reward_exp")
self.reward_gold = ability:GetSpecialValueFor("reward_gold")
-- self.value_required = ability.value_required
-- self.reward_exp = ability.reward_exp
-- self.reward_gold = ability.reward_gold
self.quest_item = ability.quest_item
self.reward_item = ability.reward_item
self.particle = ability.particle
self.current_quest = ability:GetName()
self.next_quest = ability.next_quest
self.reusable = ability.reusable
if self.particle == 1 then
local parent = self:GetParent()
local effect = "particles/generic_gameplay/generic_has_quest.vpcf"
local pfx = ParticleManager:CreateParticle(effect, PATTACH_OVERHEAD_FOLLOW, parent)
self:AddParticle(pfx, true, false, 111, false, false)
end
print(self.value_required)
print(self.reward_exp)
print(self.reward_gold)
print(self.quest_item)
print(self.reward_item)
print(self.particle)
print(self.current_quest)
print(self.next_quest)
print(self.reusable)
self:StartIntervalThink(0.1)
end
end
function modifier_quest_template:OnIntervalThink()
local parent = self:GetParent()
local heroes = FindUnitsInRadius(parent:GetTeamNumber(),
parent:GetAbsOrigin(),
nil,
350,
DOTA_UNIT_TARGET_TEAM_BOTH,
DOTA_UNIT_TARGET_HERO,
DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_NO_INVIS,
FIND_CLOSEST,
false)
for i = 1, #heroes do
local hero = heroes[1]
for j = 0,9 do
local item = hero:GetItemInSlot(j)
if item and item:GetName() == self.quest_item then
local item_charges = item:GetCurrentCharges()
if self.value_required < 2 or item_charges >= self.value_required then
hero:RemoveItem( item )
if self.reward_exp > 0 then
hero:GiveExperiencePlayers( self.reward_exp )
end
if self.reward_gold > 0 then
hero:GiveGoldPlayers( self.reward_gold )
end
EmitGlobalSound("ui.inv_pickup_highvalue")
if self.reward_item then
parent:DropQuestItem( hero, self.reward_item )
end
if self.reusable == 0 then
if self.current_quest then
parent:RemoveAbility(self.current_quest)
self:Destroy()
end
if self.next_quest then
parent:AddAbility(self.next_quest):SetLevel(1)
end
end
end
end
end
end
end
quest_test1 = class(quest_template)
function quest_test1:Spawn()
self.quest_item = "item_clarity" -- название предмета, который нужен для завершения задания
self.reward_item = "item_enchanted_mango" -- название предмета, который получен за прохождение задания(опционально)
self.particle = 1 -- нужен ли эффект над головой ? 1 - да, 0 - нет
self.next_quest = "quest_test2" -- название следующего квеста (опционально)
self.reusable = 0 -- данный квест можно выполнять много кратно. 0 - нет, 1 - да
end
quest_test2 = class(quest_template)
function quest_test2:Spawn()
self.quest_item = "item_belt_of_strength" -- название предмета, который нужен для завершения задания
self.reward_item = "item_ogre_axe" -- название предмета, который получен за прохождение задания(опционально)
self.particle = 0 -- нужен ли эффект над головой ? 1 - да, 0 - нет
self.next_quest = nil -- название следующего квеста (опционально)
self.reusable = 1 -- данный квест можно выполнять много кратно. 0 - нет, 1 - да
end
---------------------------------------------------------------
---------------------------------------------------------------
function OnQuestCreated(data)
Timers:CreateTimer(0, function()
local ability = data.ability
local caster = data.caster
ability.quest_item = data.quest_item or nil
ability.reward_item = data.reward_item or nil
ability.particle = data.particle or nil
ability.next_quest = data.next_quest or nil
ability.reusable = data.reusable or nil
caster:AddNewModifier(caster, ability, "modifier_quest_template", nil)
end)
end
---------------------------------------------------------------
---------------------------------------------------------------
if IsServer() then
function CDOTA_BaseNPC:DropQuestItem( target, item_name )
local unit = self
local spawnPoint = unit:GetAbsOrigin()
local newItem = CreateItem( item_name, nil, nil )
local drop = CreateItemOnPositionForLaunch( spawnPoint, newItem )
local initialPoint = target:GetAbsOrigin() + RandomVector( RandomFloat( 50, 125 ) )
newItem:LaunchLootInitialHeight( false, 0, 150, 0.75, initialPoint )
end
function CDOTA_BaseNPC:GiveGoldPlayers( gold )
local team = self:GetTeam()
for index=0 ,9 do
if PlayerResource:HasSelectedHero(index) then
local player = PlayerResource:GetPlayer(index)
local hero = PlayerResource:GetSelectedHeroEntity(index)
local hero_team = hero:GetTeam()
if hero_team == team then
hero:ModifyGold(gold, false, 0)
SendOverheadEventMessage( player, OVERHEAD_ALERT_GOLD, hero, gold, nil )
end
end
end
end
function CDOTA_BaseNPC:GiveExperiencePlayers( experience )
local team = self:GetTeam()
for index=0 ,9 do
if PlayerResource:HasSelectedHero(index) then
local player = PlayerResource:GetPlayer(index)
local hero = PlayerResource:GetSelectedHeroEntity(index)
local hero_team = hero:GetTeam()
if hero_team == team then
hero:AddExperience(experience, 0, false, true )
end
end
end
end
end
--------------------------------------------------------
------------------------------------------------------------
modifier_quest_template = class({
IsHidden = function(self) return false end,
IsPurgable = function(self) return false end,
IsDebuff = function(self) return false end,
IsBuff = function(self) return true end,
RemoveOnDeath = function(self) return true end,
GetAttributes = function(self) return MODIFIER_ATTRIBUTE_MULTIPLE end,
})
function modifier_quest_template:OnCreated()
if IsServer() then
local ability = self:GetAbility()
self.value_required = ability:GetSpecialValueFor("value_required")
self.reward_exp = ability:GetSpecialValueFor("reward_exp")
self.reward_gold = ability:GetSpecialValueFor("reward_gold")
-- self.value_required = ability.value_required
-- self.reward_exp = ability.reward_exp
-- self.reward_gold = ability.reward_gold
self.quest_item = ability.quest_item
self.reward_item = ability.reward_item
self.particle = ability.particle
self.current_quest = ability:GetName()
self.next_quest = ability.next_quest
self.reusable = ability.reusable
if self.particle == 1 then
local parent = self:GetParent()
local effect = "particles/generic_gameplay/generic_has_quest.vpcf"
local pfx = ParticleManager:CreateParticle(effect, PATTACH_OVERHEAD_FOLLOW, parent)
self:AddParticle(pfx, true, false, 111, false, false)
end
print(self.value_required)
print(self.reward_exp)
print(self.reward_gold)
print(self.quest_item)
print(self.reward_item)
print(self.particle)
print(self.current_quest)
print(self.next_quest)
print(self.reusable)
self:StartIntervalThink(0.1)
end
end
function modifier_quest_template:OnIntervalThink()
local parent = self:GetParent()
local heroes = FindUnitsInRadius(parent:GetTeamNumber(),
parent:GetAbsOrigin(),
nil,
350,
DOTA_UNIT_TARGET_TEAM_BOTH,
DOTA_UNIT_TARGET_HERO,
DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_NO_INVIS,
FIND_CLOSEST,
false)
for i = 1, #heroes do
local hero = heroes[1]
for j = 0,9 do
local item = hero:GetItemInSlot(j)
if item and item:GetName() == self.quest_item then
local item_charges = item:GetCurrentCharges()
if self.value_required < 2 or item_charges >= self.value_required then
hero:RemoveItem( item )
if self.reward_exp > 0 then
hero:GiveExperiencePlayers( self.reward_exp )
end
if self.reward_gold > 0 then
hero:GiveGoldPlayers( self.reward_gold )
end
-- EmitGlobalSound("ui.inv_pickup_highvalue")
if self.reward_item then
parent:DropQuestItem( hero, self.reward_item )
end
if self.reusable == 0 then
if self.current_quest then
parent:RemoveAbility(self.current_quest)
self:Destroy()
end
if self.next_quest then
parent:AddAbility(self.next_quest):SetLevel(1)
end
end
end
end
end
end
end
quest_test1 = class(quest_template)
function quest_test1:Spawn()
self.quest_item = "item_clarity" -- название предмета, который нужен для завершения задания
self.reward_item = "item_enchanted_mango" -- название предмета, который получен за прохождение задания(опционально)
self.particle = 1 -- нужен ли эффект над головой ? 1 - да, 0 - нет
self.next_quest = "quest_test2" -- название следующего квеста (опционально)
self.reusable = 0 -- данный квест можно выполнять много кратно. 0 - нет, 1 - да
end
quest_test2 = class(quest_template)
function quest_test2:Spawn()
self.quest_item = "item_belt_of_strength" -- название предмета, который нужен для завершения задания
self.reward_item = "item_ogre_axe" -- название предмета, который получен за прохождение задания(опционально)
self.particle = 0 -- нужен ли эффект над головой ? 1 - да, 0 - нет
self.next_quest = nil -- название следующего квеста (опционально)
self.reusable = 1 -- данный квест можно выполнять много кратно. 0 - нет, 1 - да
end
---------------------------------------------------------------
---------------------------------------------------------------
function OnQuestCreated(data)
Timers:CreateTimer(0, function()
local ability = data.ability
local caster = data.caster
ability.quest_item = data.quest_item or nil
ability.reward_item = data.reward_item or nil
ability.particle = data.particle or nil
ability.next_quest = data.next_quest or nil
ability.reusable = data.reusable or nil
caster:AddNewModifier(caster, ability, "modifier_quest_template", nil)
end)
end
Надеюсь сегодня вы научились, чему-то новому
Если есть какие-то идеи по улучшению гайда, то я готов выслушать !
Последнее редактирование: