Witam, Pet System kt?ry napisa?em na potrzebny konkursu.
Utw?rz plik w data /lib o nazwie pet-system.lua i wklej to:
Utw?rz plik w data /lib nazwie pet-spells.lua i wklej poni?szy kod:
Utw?rz plik w talkactions,o nazwie pet-talkactions.lua i wklej tre?? poni?ej:
w Talkactions.xml
Utw?rz plik w creaturescripts o nazwie pet-creaturescripts.lua i dodaj zawarto?? poni?ej:
Login.lua /creaturescripts scripts, dodaj:
Plik Creaturescripts.xml, dodaj:
W ka?dym pliku XML, kt?ry b?dzie s?u?y? do ka?dego zwierzaka, dodaj:
Utw?rz plik o nazwie pet trainer.lua w npc / scripts, dodaj:
Utw?rz plik o nazwie Pet Trainer.xml w NPC, i dodaj:
Uhh konfiguracja rzecz jasne oczywi?cie
Utw?rz plik w data /lib o nazwie pet-system.lua i wklej to:
Code:
-- storages for pet system
PET_UID = 80001
PET_SPECIE = 80002
PET_LEVEL = 80003
PET_EXPERIENCE = 80004
PET_HEALTH = 80005
PET_HEALTHMAX = 80006
PET_MANA = 80007
PET_MANAMAX = 80008
PET_EXHAUST = 80009
PET_ALIVE = 80010
Pets = {}
-- class for pet species
PetSpecie = {
type = "",
basehp = 0,
basemp = 0,
gainhp = 0,
gainmp = 0,
spells = {},
evolution = "",
evolve = 0,
}
-- class for pets
Pet = {
it = nil,
attributes = nil,
level = 0,
experience = 0,
health = 0,
healthmax = 0,
mana = 0,
manamax = 0,
}
-- create new instances of PetSpecie
function PetSpecie:new(type, basehp, basemp, gainhp, gainmp, spells, evolution, evolve)
local new_specie = {
type = type,
basehp = basehp,
basemp = basemp,
gainhp = gainhp,
gainmp = gainmp,
spells = spells,
evolution = evolution,
evolve = evolve,
}
local obj = setmetatable(new_specie, {__index = self})
Pets[type:lower()] = obj
return obj
end
-- create new instances of Pet
function PetSpecie:create()
local new_pet = {
it = nil,
attributes = self,
level = 1,
experience = 0,
health = self.basehp,
healthmax = self.basehp,
mana = self.basemp,
manamax = self.basemp,
}
return setmetatable(new_pet, {__index = Pet})
end
-- summon a player pet for the first time
function Pet:hatch(cid)
if getCreatureStorage(cid, PET_SPECIE) ~= -1 then
return doPlayerSendCancel(cid, "You already have a pet.")
end
local pet = doCreateMonster(self.attributes.type, getCreaturePosition(cid))
if not pet then
return false
end
if not doConvinceCreature(cid, pet) then
doRemoveCreature(pet)
return false
end
self:setit(pet)
setCreatureMaxHealth(pet, self.healthmax)
doCreatureAddHealth(pet, self.healthmax)
doCreatureSetStorage(cid, PET_SPECIE, self.attributes.type)
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your new pet has born.")
self:save()
doSendMagicEffect(getCreaturePosition(pet), CONST_ME_HOLYDAMAGE)
return self
end
-- make player pet say something
function Pet:say(strt)
doCreatureSay(self.it, strt, TALKTYPE_ORANGE_1)
end
-- gather a summoned player pet back
function Pet:back()
self:save()
doSendMagicEffect(self:position(), CONST_ME_POFF)
doCreatureSay(getCreatureMaster(self.it), "It's enough, ".. getCreatureName(self.it))
doRemoveCreature(self.it)
end
-- free a player pet forever
function Pet:release()
local cid = getCreatureMaster(self.it)
doCreatureSay(cid, "Good bye, ".. getCreatureName(self.it) .."... :'(")
doCreatureSetStorage(cid, PET_UID, -1)
doCreatureSetStorage(cid, PET_SPECIE, -1)
doCreatureSetStorage(cid, PET_LEVEL, -1)
doCreatureSetStorage(cid, PET_EXPERIENCE, -1)
doCreatureSetStorage(cid, PET_HEALTH, -1)
doCreatureSetStorage(cid, PET_HEALTHMAX, -1)
doCreatureSetStorage(cid, PET_MANA, -1)
doCreatureSetStorage(cid, PET_MANAMAX, -1)
doSendMagicEffect(self:position(), CONST_ME_POFF)
doRemoveCreature(self.it)
end
-- add experience to player pet
function Pet:addexperience(value)
local prevLevel = self.level
local nextLevelExp = getExperienceForLevel(self.level + 1)
self.experience = self.experience + value
while self.experience >= nextLevelExp do
self.healthmax = self.healthmax + self.attributes.gainhp
self.manamax = self.manamax + self.attributes.gainmp
self.level = self.level + 1
nextLevelExp = getExperienceForLevel(self.level + 1)
end
if prevLevel ~= self.level then
self.mana = self.manamax
self.health = self.healthmax
doPlayerSendTextMessage(getCreatureMaster(self.it), MESSAGE_STATUS_CONSOLE_BLUE, "Your pet advanced from level ".. prevLevel .." to level ".. self.level ..".")
setCreatureMaxHealth(self.it, self.healthmax)
doCreatureAddHealth(self.it, getCreatureMaxHealth(self.it))
self:save()
if self.attributes.evolution then
if self.attributes.evolve and self.level >= self.attributes.evolve then
doCreatureSay(getCreatureMaster(self.it), "What's happening?!")
addEvent(function()
local cid = getCreatureMaster(self.it)
local position = self:position()
doRemoveCreature(self.it)
local pet = doCreateMonster(self.attributes.evolution, position)
if not doConvinceCreature(cid, pet) then
doRemoveCreature(pet)
call_pet(cid)
return
end
doCreatureSetStorage(cid, PET_UID, pet)
setCreatureMaxHealth(pet, self.healthmax)
doCreatureAddHealth(pet, getCreatureMaxHealth(pet))
doSendMagicEffect(getCreaturePosition(pet), CONST_ME_MORTAREA)
doCreatureSetStorage(cid, PET_SPECIE, self.attributes.evolution)
end, 100)
end
end
end
end
-- make pet cast a spell
function Pet:cast(index)
local cid = getCreatureMaster(self.it)
if not self.attributes.spells[index] then
return doPlayerSendCancel(cid, "This spell is unknown.")
end
local spell = self.attributes.spells[index]
if self.level < spell.level then
doPlayerSendCancel(cid, "Your pet doesn't have enough level to cast this spell.")
return
end
if self.mana < spell.mana then
doPlayerSendCancel(cid, "Your pet doesn't have enough mana to cast this spell.")
return
end
if getCreatureStorage(cid, PET_EXHAUST) > os.clock() then
doSendMagicEffect(self:position(), CONST_ME_POFF)
doPlayerSendCancel(cid, "Your pet is exhausted.")
return
end
if spell.target then
local target = getCreatureTarget(self.it)
if target == 0 then
doPlayerSendCancel(cid, "First, select a target.")
return
end
spell.range = spell.range or 1
if getDistanceBetween(self:position(), getCreaturePosition(target)) > spell.range then
doPlayerSendCancel(cid, "Too far to cast spell.")
return
end
doSendDistanceShoot(self:position(), getCreaturePosition(target), spell.shooteffect)
doTargetCombatHealth(self.it, target, spell.type, -spell.min, -spell.max, spell.effect)
else
doAreaCombatHealth(self.it, spell.type, self:position(), (spell.area or 0), -min, -max, spell.effect)
end
self.mana = self.mana - spell.mana
doCreatureSetStorage(cid, PET_EXHAUST, os.clock() + (spell.exhaust / 1000))
doCreatureSay(cid, getCreatureName(self.it) ..", use ".. spell.name .."!")
self:say(spell.name)
end
-- set pet uid
function Pet:setit(uid)
self.it = uid
end
-- get player pet position
function Pet:position()
return getCreaturePosition(self.it)
end
-- move player pet to a direction
function Pet:move(direction)
local toPosition = getPosByDir(self:position(), direction, 1)
if getCreatureStorage(getCreatureMaster(self.it), PET_EXHAUST) > os.clock() then
doSendMagicEffect(self:position(), CONST_ME_POFF)
doPlayerSendCancel(cid, "Your pet is exhausted.")
return
end
if queryTileAddThing(self.it, toPosition) == RETURNVALUE_NOERROR then
doMoveCreature(self.it, direction)
doCreatureSetStorage(cid, PET_EXHAUST, os.clock() + 0.5)
doCreatureSay(cid, "Move, ".. getCreatureName(self.it) .."!")
end
end
-- save player pet attributes
function Pet:save()
local cid = getCreatureMaster(self.it)
doCreatureSetStorage(cid, PET_UID, self.it)
doCreatureSetStorage(cid, PET_SPECIE, getCreatureName(self.it))
doCreatureSetStorage(cid, PET_LEVEL, self.level)
doCreatureSetStorage(cid, PET_EXPERIENCE, self.experience)
doCreatureSetStorage(cid, PET_HEALTH, self.health)
doCreatureSetStorage(cid, PET_HEALTHMAX, self.healthmax)
doCreatureSetStorage(cid, PET_MANA, self.mana)
doCreatureSetStorage(cid, PET_MANAMAX, self.manamax)
end
-- get player pet and return instance
function get_pet(cid)
local uid, it = getCreatureStorage(cid, PET_UID)
for _, pet in ipairs(getCreatureSummons(cid)) do
if pet == uid then
it = pet
break
end
end
if not it then
return false
end
local this_pet = {
it = it,
attributes = Pets[getCreatureName(it):lower()],
level = getCreatureStorage(cid, PET_LEVEL),
experience = getCreatureStorage(cid, PET_EXPERIENCE),
health = getCreatureHealth(it),
healthmax = getCreatureMaxHealth(it),
mana = getCreatureStorage(cid, PET_MANA),
manamax = getCreatureStorage(cid, PET_MANAMAX),
}
return setmetatable(this_pet, {__index = Pet})
end
-- summon a existing player pet
function call_pet(cid)
if get_pet(cid) then
return doPlayerSendCancel(cid, "You cannot summon your pet more than one time.")
end
if getCreatureStorage(cid, PET_SPECIE) == -1 then
return doPlayerSendCancel(cid, "You don't have a pet.")
end
if getCreatureStorage(cid, PET_ALIVE) == 0 then
return doPlayerSendCancel(cid, "You need to revive your pet")
end
local pet = doCreateMonster(getCreatureStorage(cid, PET_SPECIE), getCreaturePosition(cid))
if not pet then
return false
end
if not doConvinceCreature(cid, pet) then
doRemoveCreature(pet)
return false
end
local health, healthmax = getCreatureStorage(cid, PET_HEALTH), getCreatureStorage(cid, PET_HEALTHMAX)
setCreatureMaxHealth(pet, healthmax)
doCreatureAddHealth(pet, healthmax)
doCreatureAddHealth(pet, (health - healthmax))
doCreatureSay(cid, "Go, ".. getCreatureName(pet) .."!")
doSendMagicEffect(getCreaturePosition(pet), CONST_ME_MAGIC_GREEN)
doCreatureSetStorage(cid, PET_UID, pet)
return true
end
-- is pet
function is_pet(cid)
return getCreatureMaster(cid) == 0 and false or isPlayer(getCreatureMaster(cid))
end
dofile(getDataDir() .."/lib/pet-spells.lua")
Pet_Rat = PetSpecie:new("Rat", 20, 0, 5, 5, {[1] = Rock_Throw, [2] = Dark_Bite}, "Cave Rat", 14)
Pet_Cave_Rat = PetSpecie:new("Cave Rat", 40, 20, 10, 10, {[1] = Dark_Bite}, "Munster", 32)
Pet_Munster = PetSpecie:new("Munster", 100, 50, 20, 20, {[1] = Dark_Bite}, false, false)
Code:
dofile("data/spells/lib/spells.lua")
Dark_Bite = {
name = "Dark Bite",
level = 1,
mana = 100,
type = COMBAT_PHYSICALDAMAGE,
effect = CONST_ME_BLOCKHIT,
shooteffect = CONST_ANI_SMALLSTONE,
target = true,
range = 1,
min = 300,
max = 500,
area = 0,
exhaust = 1000,
}
Rock_Throw = {
name = "Rock Throw",
level = 1,
mana = 10,
type = COMBAT_PHYSICALDAMAGE,
effect = CONST_ME_BLOCKHIT,
shooteffect = CONST_ANI_NONE,
target = true,
range = 1,
min = 20,
max = 25,
area = 0,
exhaust = 1000,
}
Code:
function onSay(cid, words, param, channel)
param = string.explode(param, ":")
if param[1]:lower() == "go" then
if getTilePzInfo(getCreaturePosition(cid)) then
return doPlayerSendCancel(cid, "You cannot call your pet at protection zone.")
end
local pet = get_pet(cid)
if pet then
return doPlayerSendCancel(cid, "You cannot call your pet two times.")
end
call_pet(cid)
return true
elseif param[1]:lower() == "back" then
local pet = get_pet(cid)
if not pet then
return doPlayerSendCancel(cid, "Please call your pet first.")
end
pet:back()
return true
elseif param[1]:lower() == "release" then
local pet = get_pet(cid)
if not pet then
return doPlayerSendCancel(cid, "Please call your pet first.")
end
pet:release()
return true
elseif param[1]:lower() == "cast" then
local pet = get_pet(cid)
if not pet then
return doPlayerSendCancel(cid, "Please call your pet first.")
end
local index = tonumber(param[2]) or 1
pet:cast(index)
return true
elseif param[1]:lower() == "say" then
local pet = get_pet(cid)
if not pet then
return doPlayerSendCancel(cid, "Please call your pet first.")
end
pet:say(param[2])
return true
elseif param[1]:lower() == "move" then
local pet = get_pet(cid)
if not pet then
return doPlayerSendCancel(cid, "Please call your pet first.")
end
if not isInArray({"north", "south", "east", "west"}, param[2]:lower()) then
return doPlayerSendCancel(cid, "Invalid direction.")
end
pet:move((_G[param[2]:upper()] or NORTH))
return true
elseif param[1]:lower() == "addexp" then
local pet = get_pet(cid)
if not pet then
return doPlayerSendCancel(cid, "Please call your pet first.")
end
if getPlayerGroupId(cid) < 3 then
return doPlayerSendCancel(cid, "You cannot use this command.")
end
pet:addexperience(tonumber(param[2]) or 0)
return true
end
return true
end
Code:
<talkaction words="/pet" event="script" value="pet-talkactions.lua"/>
Code:
function onKill(cid, target, lastHit)
local pet = get_pet(cid)
if not isMonster(target) or getMonsterInfo(getCreatureName(target)) and getMonsterInfo(getCreatureName(target)).experience == 0 then
return true
end
if not pet then
return true
end
pet:addexperience(getMonsterInfo(getCreatureName(target)).experience)
return true
end
function onDeath(cid, corpse, deathList)
if not is_pet(cid) then
return true
end
local master = getCreatureMaster(cid)
doPlayerSendTextMessage(master, MESSAGE_EVENT_ADVANCE, "Your pet is dead.")
doCreatureSetStorage(master, PET_ALIVE, 0)
doCreatureSetStorage(master, PET_HEALTH, getCreatureMaxHealth(cid))
return true
end
Code:
registerCreatureEvent(cid, "PetKill")
Plik Creaturescripts.xml, dodaj:
Code:
<event type="kill" name="PetKill" event="script" value="pet-creaturescripts.lua"/>
<event type="death" name="PetDeath" event="script" value="pet-creaturescripts.lua"/>
W ka?dym pliku XML, kt?ry b?dzie s?u?y? do ka?dego zwierzaka, dodaj:
Code:
<script>
<event name="PetDeath"/>
</script>
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
local petState = {}
function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
local PetPrices = {
["rat"] = {1000, 200},
}
function creatureSayCallback(cid, type, msg)
if(not npcHandler:isFocused(cid)) then
return false
end
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE and 0 or cid
if msgcontains(msg, "sell") then
local say = "I can offer you these pet species: "
for pet_name, k in pairs(PetPrices) do
local first = true
if Pets[pet_name] then
say = say .. (first == true and "" or ", ") .."{".. pet_name .. "}"
first = false
end
end
selfSay(say, cid)
talkState[talkUser] = 1
elseif msgcontains(msg, "revive") then
if getCreatureStorage(cid, PET_SPECIE) == -1 then
selfSay("You don't have a pet", cid)
return true
end
if getCreatureStorage(cid, PET_ALIVE) == 0 then
if doPlayerRemoveMoney(cid, PetPrices[getCreatureStorage(cid, PET_SPECIE):lower()][2]) then
selfSay("Your pet is now alive.", cid)
doCreatureSetStorage(cid, PET_ALIVE, 1)
else
selfSay("Sorry, you need ".. PetPrices[getCreatureStorage(cid, PET_SPECIE)][2] .." gold.", cid)
end
else
selfSay("Sorry, your pet is alive.", cid)
end
elseif talkState[talkUser] == 1 then
if PetPrices[msg] then
selfSay("A good choice, so do you want to buy a ".. msg .." pet? It will cost ".. PetPrices[msg][1] .." gold.", cid)
talkState[talkUser] = 2
petState[talkUser] = msg
else
selfSay("Sorry, I don't know this pet specie", cid)
end
elseif talkState[talkUser] == 2 then
if msgcontains(msg, "yes") then
if get_pet(cid) or getCreatureStorage(cid, PET_SPECIE) ~= -1 then
selfSay("Sorry, you already have a pet.", cid)
return true
end
local pet = petState[talkUser]
if getPlayerMoney(cid) < PetPrices[pet][1] then
selfSay("Sorry, you don't have enough money", cid)
return true
end
selfSay("This is your new pet, take care of it.", cid)
Pets[pet]:create():hatch(cid)
elseif msgcontains(msg, "no") then
selfSay("Then not.", cid)
talkState[talkUser] = 0
end
end
return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Utw?rz plik o nazwie Pet Trainer.xml w NPC, i dodaj:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Pet Trainer" script="pet trainer.lua" walkinterval="0" floorchange="0">
<health now="100" max="100"/>
<look type="128" head="17" body="54" legs="114" feet="0" addons="2"/>
<parameters>
<parameter key="message_greet" value="Hello |PLAYERNAME|, I {sell} and {revive} pets."/>
</parameters>
</npc>
Uhh konfiguracja rzecz jasne oczywi?cie
zabraniam kopiowania zawarto?ci na inne fora/serwisy