Ir para conteúdo
  • Cadastre-se

Suporte (TFS 1.0) Target não funciona no Pokemon do NPC de duelo


Posts Recomendados

Quando o duelo é iniciado contra o NPC (ginásio, aleatório, missão) não consigo dar target no Pokémon do NPC, e as skills também não dão dano. Já o pokemon do NPC pode me atacar e matar normalmente.

 

Segue meu script abaixo:

Spoiler

-- Last Storages: 9312, 9712
if (NpcBattle == nil) then
    local NPC_BATTLE_TIMEOUT = 60 -- one minute
    local NPC_TIME_BETWEEN_BATTLES = 23 * 60 * 60 -- 24 hours
    local NPC_TIME_BETWEEN_BATTLES_FOREVER = -2
    local NPC_DIFFICULTY_DYNAMIC = 0 -- Depends on player level
    local NPC_POKEMON_EXPERIENCE_RATE = 2.0

    --local NPC_LEVEL_STORAGE_BASE = 9500 -- Just to remind
    local NPC_LEVEL_MAX = 100
    local NPC_GROW_PER_LEVEL = 3 -- How much the NPC Pokemon will grow with each NPC level

    --local LAST_BATTLE_TIME_STORAGE_BASE = 9100 -- Just to remind

    local STORAGE_BASE = 9000
    local NPC_STORAGES = {
        CURRENT_BATTLE_STATUS = STORAGE_BASE + 1,
        OPPONENT = STORAGE_BASE + 2,
        POKEMON1_STATUS = STORAGE_BASE + 3,
        POKEMON2_STATUS = STORAGE_BASE + 4,
        POKEMON3_STATUS = STORAGE_BASE + 5,
        POKEMON4_STATUS = STORAGE_BASE + 6,
        POKEMON5_STATUS = STORAGE_BASE + 7,
        POKEMON6_STATUS = STORAGE_BASE + 8,
        BATTLE_TIMEOUT = STORAGE_BASE + 9
    }

    local POKEMONNUMBER_TO_VAR = {
        [1] = NPC_STORAGES.POKEMON1_STATUS,
        [2] = NPC_STORAGES.POKEMON2_STATUS,
        [3] = NPC_STORAGES.POKEMON3_STATUS,
        [4] = NPC_STORAGES.POKEMON4_STATUS,
        [5] = NPC_STORAGES.POKEMON5_STATUS,
        [6] = NPC_STORAGES.POKEMON6_STATUS
    }

    local NPC_BATTLE_STATUS = {
        ISNT_BATTLEING = -1,
        IS_BATTLEING = 0
    }

    local NPC_POKEMON_STATUS = {
        CANNOT_USE = -1,
        CAN_USE = 0
    }

    local TALK_STATE = {
        ERASE = 0,
        ACCEPTING_BATTLE = 1
    }

    local BATTLE_END_MODES = {
        PLAYER_LOGOUT = 0,
        PLAYER_WIN = 1,
        PLAYER_LOSS = 2,
        PLAYER_AWAY = 3
    }

    local NPC_DIALOGS = {
        POKEMON_DOWN = {
            "Grr...",
            "I guess I underestimated you...",
            "So you aren't so weak.",
            "Let's see if you can beat this"
        },
        BATTLE_START = {
            "Alright, prepare yourself!",
            "Yep! Let's battle!",
            "Let's see if you can do."
        },
        PLAYER_WITHOUT_POKEMON = {
            "Where is your Pokemon?",
            "Where is your Pokemon? Afraid?",
            "First call your Pokemon!"
        },
        NPC_LOSS = {
            "Grr...",
            "You're very lucky...",
            "Congratulations!"
        },
        NPC_WIN = {
            "Haha! Where is the Pokemon trainer?",
            "Yes! I'm the best! No chance for you.",
            "More luck next time."
        }
    }
    --[[ // ]]
    local NpcsByName = {}
    NpcBattle = {
        name = "",
        uid = 0,
        pokemons = {},
        currentPokemons = {},
        rewardBaseExp = 0,
        rewardItems = {},
        rewardUniqueItems = {},
        rewardRespect = 0,
        rewardBadge = nil,
        lastBattleTimeStorage = 0,
        requiredRespect = 0,
        oneWin = false,
        difficulty = 10,
        required = nil,
        onWin = nil,
        cooldowns = {},
        levelStorage = 0,
        baseBet = 0,
        currentBet = 0,
        npcHandler = nil,
        requiredLevel = 0,
        changes = {}, -- new pokemon that the NPC will carry when the player win x times structure = changes{{level = 1, pokemon = "Pikachu"}, {level = 2, pokemon = Charmander}, ...}
        payRespect = 0,
        evolve = true,
        lastDefeatTimeStorage = nil,
        lastOrder = 0,
        pokemonMaxLevel = NPC_LEVEL_MAX,
        specialMove = nil, -- A move that all Pokemon from this NPC will use
        pokemonDefeatExperienced = false,
        onEnd = nil,
        onDefeatNpcPokemon = nil,
        requiredMessage = nil,
        pokemonMovesets = nil,
        currentPokemonId = -1,
        pokemonTeamEvolvable = true,
        extraStats = nil,
        lossSpeech = nil,
        winSpeech = nil,
        battleInterval = nil,
        defeatedPokemonCount = 0,
        linealOrder = false
    }

    -- local REGISTERED_STORAGES = {}

    function NpcBattle:new(name, lastBattleTimeStorage, levelStorage, npcHandler, lastDefeatTimeStorage)
        if (not npcHandler) then
            log(LOG_TYPES.ERROR, "NpcBattle:new missing npcHandler", name, lastBattleTimeStorage, levelStorage)
            return
        end

        if (not levelStorage) then
            log(LOG_TYPES.ERROR, "NpcBattle:new missing levelStorage", name, lastBattleTimeStorage)
            return
        end

        if (not lastBattleTimeStorage) then
            log(LOG_TYPES.ERROR, "NpcBattle:new missing lastBattleTimeStorage", name)
            return
        end

        if (not name or type(name) ~= "string") then
            log(LOG_TYPES.ERROR, "NpcBattle:new missing name")
            return
        end

        --[[if (table.find(REGISTERED_STORAGES, lastBattleTimeStorage)) then  This is buggy, cuz if we put more then one NPC at the map (same NPC) the warning will show up
                log(LOG_TYPES.ERROR, "NpcBattle:new duplicated last battle time storage", name, lastBattleTimeStorage)
            else
                REGISTERED_STORAGES[#REGISTERED_STORAGES + 1] = lastBattleTimeStorage
            end

            if (table.find(REGISTERED_STORAGES, levelStorage)) then
                log(LOG_TYPES.ERROR, "NpcBattle:new duplicated level storage", name, levelStorage)
            else
                REGISTERED_STORAGES[#REGISTERED_STORAGES + 1] = levelStorage
            end]]

        local obj = {}
        obj.name = name
        obj.lastBattleTimeStorage = lastBattleTimeStorage
        obj.levelStorage = levelStorage
        obj.npcHandler = npcHandler
        obj.lastDefeatTimeStorage = lastDefeatTimeStorage

        setmetatable(obj, self)
        self.__index = self

        NpcsByName[name] = obj
        if (getCreatureIcon(getNpcId()) == CREATURE_ICONS.NONE) then
            setCreatureIcon(getNpcId(), CREATURE_ICONS.BATTLE)
        end

        return obj
    end

    function NpcBattle:setBattleInterval(v)
        self.battleInterval = v
    end

    function NpcBattle:setCustomPokemonLevel(v)
        self.customPokemonLevel = v
    end

    function NpcBattle:setLossSpeech(v)
        self.lossSpeech = v
    end

    function NpcBattle:setWinSpeech(v)
        self.winSpeech = v
    end

    function NpcBattle:setPokemonMovesets(movesets)
        self.pokemonMovesets = movesets
    end

    function NpcBattle:setPokemons(pokemons)
        self.pokemons = pokemons
    end

    function NpcBattle:setRewardBaseExp(rewardBaseExp)
        self.rewardBaseExp = rewardBaseExp
    end

    function NpcBattle:setRewardItems(rewardItems)
        self.rewardItems = rewardItems
    end

    function NpcBattle:setRewardUniqueItems(rewardUniqueItems)
        self.rewardUniqueItems = rewardUniqueItems
    end

    function NpcBattle:setRewardRespect(rewardRespect)
        self.rewardRespect = rewardRespect
    end

    function NpcBattle:setRewardBadge(rewardBadge)
        self.rewardBadge = rewardBadge
    end

    function NpcBattle:setRequiredRespect(requiredRespect)
        self.requiredRespect = requiredRespect
    end

    function NpcBattle:setOneWin(oneWin)
        self.oneWin = oneWin
    end

    function NpcBattle:setDifficulty(difficulty)
        self.difficulty = difficulty
    end

    function NpcBattle:setRequired(required)
        self.required = required
    end

    function NpcBattle:setRequiredMessage(msg)
        self.requiredMessage = msg
    end

    function NpcBattle:setOnWin(onWin)
        self.onWin = onWin
    end

    function NpcBattle:setOnEnd(v)
        self.onEnd = v
    end

    function NpcBattle:setOnDefeatNpcPokemon(v)
        self.onDefeatNpcPokemon = v
    end

    function NpcBattle:setBaseBet(baseBet)
        self.baseBet = baseBet
    end

    function NpcBattle:setRequiredLevel(requiredLevel)
        self.requiredLevel = requiredLevel
    end

    function NpcBattle:addChange(level, pokemon)
        table.insert(self.changes, { level = level, pokemon = pokemon })
    end

    function NpcBattle:setPayRespect(payRespect)
        self.payRespect = payRespect
    end

    function NpcBattle:setEvolve(evolve)
        self.evolve = evolve
    end

    function NpcBattle:setPokemonMaxLevel(v)
        self.pokemonMaxLevel = v
    end

    function NpcBattle:setSpecialMove(v)
        self.specialMove = v
    end

    function NpcBattle:setPokemonDefeatExperienced(v)
        self.pokemonDefeatExperienced = v
    end

    function NpcBattle:setRequiredStorage(v)
        self.requiredStorage = v
    end

    function NpcBattle:setPokemonTeamEvolvable(v)
        self.pokemonTeamEvolvable = v
    end

    function NpcBattle:setPokemonExtraStats(v)
        self.extraStats = v
    end

    function NpcBattle:setLinealOrder(v)
        self.linealOrder = v
    end

    --[[ // ]]
    -- IS
    function NpcBattle:isBattleing()
        return getCreatureStorage(self.uid, NPC_STORAGES.CURRENT_BATTLE_STATUS) == NPC_BATTLE_STATUS.IS_BATTLEING
    end

    function NpcBattle:isPokemonOnline()
        return #getCreatureSummons(self.uid) > 0
    end

    -- GET
    function NpcBattle:getPokemons()
        return self.pokemons
    end

    function NpcBattle:getPokemon()
        return getCreatureSummons(self.uid)[1]
    end

    function NpcBattle:getBattleTimeoutRemaing()
        return getCreatureStorage(self.uid, NPC_STORAGES.BATTLE_TIMEOUT)
    end

    function NpcBattle:getRequiredRespect()
        return self.requiredRespect
    end

    function NpcBattle:getMoveCooldown(move)
        return (self.cooldowns[move] and self.cooldowns[move] - getCurrentTimeInSeconds()) or 0
    end

    --[[ The NPC level is based on how many wins the player gets against him, many wins = npc stronger  ]]
    function NpcBattle:getLevel(pid)
        if (self.evolve) then
            local v = getCreatureStorage(pid, self.levelStorage)
            return (v and v > 0 and v <= self.pokemonMaxLevel) and v or 1
        end
        return 1
    end

    function NpcBattle:getPokemonMove(pokemonUid, targetUid)
        local moves = self.pokemonMovesets and self.pokemonMovesets[self.currentPokemonId] or getPokemonDefaultSkills(getPokemonReferenceName(pokemonUid))
        if (self.specialMove) then
            moves[#moves + 1] = self.specialMove
        end

        -- First try a random move, if cant use it, try from the strongest to down
        local move = table.random(moves)
        if (not self:canPokemonUseMove(move, pokemonUid, targetUid)) then
            move = nil
            for i = #moves, #moves, -1 do
                if (self:canPokemonUseMove(moves[i], pokemonUid, targetUid)) then
                    move = moves[i]
                    break
                end
            end
        end

        return move
    end

    -- SET
    function NpcBattle:setBattleStatus(status)
        doCreatureSetStorage(self.uid, NPC_STORAGES.CURRENT_BATTLE_STATUS, status)
    end

    function NpcBattle:setOpponent(opponent)
        doCreatureSetStorage(self.uid, NPC_STORAGES.OPPONENT, opponent)
        doNpcSetOpponent(self.uid, opponent) -- Source function
    end

    function NpcBattle:setPokemonStatus(pokemonNumber, status)
        doCreatureSetStorage(self.uid, POKEMONNUMBER_TO_VAR[pokemonNumber], status)
    end

    function NpcBattle:setBattleTimeout(battleTimeout)
        doCreatureSetStorage(self.uid, NPC_STORAGES.BATTLE_TIMEOUT, battleTimeout)
    end

    function NpcBattle:setPlayerLastBattleTimeWithNpc(pid, forever)
        if (isNumber(forever)) then
            doCreatureSetStorage(pid, self.lastBattleTimeStorage, forever)
        else
            doCreatureSetStorage(pid, self.lastBattleTimeStorage, (forever and NPC_TIME_BETWEEN_BATTLES_FOREVER or os.time()))
        end
    end

    function NpcBattle:setMoveCooldown(move, cooldown)
        if (not cooldown) then
            cooldown = getPokemonSkillCooldownTime(move)
        end
        self.cooldowns[move] = cooldown + getCurrentTimeInSeconds()
    end

    function NpcBattle:setLevel(pid, level)
        doCreatureSetStorage(pid, self.levelStorage, (level <= self.pokemonMaxLevel and level or
                self.pokemonMaxLevel))
    end

    -- CAN
    function NpcBattle:canPokemonUseMove(move, pokemonUid, targetUid)
        if (self:getMoveCooldown(move) > 0 or getPokemonSkillWildBlock(move) or
                getMonsterLevel(pokemonUid) < getPokemonSkillRequiredLevel(getCreatureName(pokemonUid), move) or
                (getPokemonSkillMakeHeal(move) and getCreatureHealth(pokemonUid) / getCreatureMaxHealth(pokemonUid) > 0.5)) then
            return false
        end

        if (getInstantSpellInfo(SKILL_FUNCTION_PREFIX .. move).needdirection == 1) then
            local pokemonPos, targetPos = getCreaturePosition(pokemonUid), getCreaturePosition(targetUid)
            if (pokemonPos.x ~= targetPos.x and pokemonPos.y ~= targetPos.y) then
                return false
            end
            doCreatureSetLookDirection(pokemonUid, getDirectionTo(pokemonPos, targetPos))
        end
        return true
    end

    function NpcBattle:canPlayerBattleWithNpc(pid)
        if (getPlayerDueling(pid)) then
            return __L(pid, "You can't battle against me while you're dueling.")
        end

        if (self.payRespect > 0 and getPlayerRespect(pid) < self.payRespect) then
            return string.format(__L(pid, "You need pay %s respect points to battle against me."), self.payRespect)
        end

        if (getPlayerLevel(pid) < self.requiredLevel) then
            return string.format(__L(pid, "You need at least level %s to battle against me."), self.requiredLevel)
        end

        self:doUpdateCurrentBet(pid)
        if (self.currentBet > 0 and getPlayerMoney(pid) < self.currentBet) then
            return string.format(__L(pid, "You need at least %s dollars to bet."), self.currentBet)
        end

        if (getPlayerRespect(pid) < self.requiredRespect) then
            return string.format(__L(pid, "Sorry kid, you need at least %s respect points to do a battle with me."), self.requiredRespect)
        end

        if (self.rewardBadge ~= nil) then
            if (getPlayerItemCount(pid, self.rewardBadge.newItemId) > 0) then
                return __L(pid, "You already have my badge, there is no reason to a new battle.")
            end
        end

        local lastBattleTime = getCreatureStorage(pid, self.lastBattleTimeStorage)
        if (lastBattleTime == NPC_TIME_BETWEEN_BATTLES_FOREVER) then
            return __L(pid, "You beat me before, there is no reason to a new battle.")

        elseif (lastBattleTime > -1) then
            local interval = self.battleInterval ~= nil and self.battleInterval or NPC_TIME_BETWEEN_BATTLES
            -- If default 24h, we can disable the remaing time if the player dueled before the serversave
            if (interval == NPC_TIME_BETWEEN_BATTLES and lastBattleTime <= getGlobalStorageValue(GLOBAL_STORAGES.SERVER_START_TIME)) then
                interval = 0
            end

            local remaingTime = (lastBattleTime + interval) - os.time()
            if (remaingTime > 0) then
                return string.format(__L(pid, "Sorry, you must wait %s seconds to battle with me again."), table.concat(string.timediff(remaingTime, pid)))
            end
        end

        if ((self.requiredStorage and getCreatureStorage(pid, self.requiredStorage) < 0) or
                (self.required and not self.required(pid))) then
            return self.requiredMessage and self.requiredMessage or __L(pid, "You can't duel against me yet.")
        end

        if (not isSightClear(getCreaturePosition(pid), getCreaturePosition(self.uid), false)) then
            return __L(pid, "First get next to me.")
        end

        if (isPokemonOnline(pid)) then
            local pokemon = getPlayerPokemon(pid)
            if (isMonster(pokemon) and isPokemonUsingHealthPotion(pokemon) or isPokemonUsingEnergyPotion(pokemon)) then
                return __L(pid, "You can't battle against me while your Pokemon is using potions.")
            end
        end

        if (getTilePzInfo(getCreaturePosition(pid))) then
            return __L(pid, "You can't duel against me while you are in a protection zone.")
        end

        return true
    end

    -- DO
    function NpcBattle:doMovesCooldownReset()
        self.cooldowns = {}
    end

    function NpcBattle:doPlayerGiveBadge(pid, badge)
        doTransformItem(getPlayerItemById(pid, true, badge.oldItemId).uid, badge.newItemId)
    end

    function NpcBattle:doPokemonsStatusReset()
        for i = 1, #self.currentPokemons do
            self:setPokemonStatus(i, NPC_POKEMON_STATUS.CAN_USE)
        end
    end

    function NpcBattle:doBattleTimeoutReset()
        self:setBattleTimeout(NPC_BATTLE_TIMEOUT)
    end

    function NpcBattle:doCallPokemon(pokemonName, pid)
        self:doMovesCooldownReset()
        doAddExhaust(self.uid)

        local spawnPosition = getCreaturePosition(self.uid)
        local pokemon = doSummonCreature(pokemonName, spawnPosition, false)

        local pos = getPositionAdjacent(pokemon, spawnPosition)
        if (pos) then
            doTeleportThing(pokemon, pos)
        end

        doConvinceCreature(self.uid, pokemon)
        doSendMagicEffect(spawnPosition, balls["poke"].effects.use)
        registerCreatureEvent(pokemon, "npcPokemonDeath")
        doCreatureSay(self.uid, string.format(__L(pid, "Go, %s!"), pokemonName), TALKTYPE_MONSTER)

        addEvent(function()
            if (isCreature(pokemon)) then
                doSendCreatureEffect(pokemon, CREATURE_EFFECTS.RED_FADE_IN)
            end
        end, 10)

        local level = 0
        if (self.customPokemonLevel ~= nil) then
            level = self.customPokemonLevel(pid)
        elseif (self.difficulty ~= NPC_DIFFICULTY_DYNAMIC) then
            level = self.difficulty + ((self:getLevel(getNpcOpponent(self.uid)) - 1) * NPC_GROW_PER_LEVEL)
        else
            level = getPlayerLevel(getNpcOpponent(self.uid))
            level = level >= 10 and level or 10
            level = level <= 90 and level or 90
            level = getRandom(level - 20, level)
        end

        level = (level <= self.pokemonMaxLevel and level or self.pokemonMaxLevel)
        level = (level <= POKEMON_LEVEL_MAX and level or POKEMON_LEVEL_MAX)
        level = (level > 0 and level or 1)

        setMonsterExtraPoints(pokemon, level + 10)
        setMonsterLevel(pokemon, level)
        if (self.pokemonDefeatExperienced) then
            setCreatureSkillLoss(pokemon, true) -- Enable exp
            setMonsterExperienceRate(pokemon, NPC_POKEMON_EXPERIENCE_RATE)
        end

        if (self.extraStats) then
            setMonsterVarPokeStat(pokemon, MONSTER_POKE_STATS.MAXHEALTH, self.extraStats)
            setMonsterVarPokeStat(pokemon, MONSTER_POKE_STATS.ATTACK, self.extraStats)
            setMonsterVarPokeStat(pokemon, MONSTER_POKE_STATS.DEFENSE, self.extraStats)
            setMonsterVarPokeStat(pokemon, MONSTER_POKE_STATS.SPECIALATTACK, self.extraStats)
            setMonsterVarPokeStat(pokemon, MONSTER_POKE_STATS.SPECIALDEFENSE, self.extraStats)
            setMonsterVarPokeStat(pokemon, MONSTER_POKE_STATS.SPEED, self.extraStats)
        end
    end

    local function getElementMultiplerBetweenPokemons(pokemon1, pokemon2)
        if (not pokemon1 or not pokemon2) then
            return 0
        end

        local result = 0
        local pokemon1elements = getPokemonTypes(nil, pokemon1)
        local pokemon2elements = getPokemonTypes(nil, pokemon2)

        for i = 1, #pokemon1elements do
            for j = 1, #pokemon2elements do
                result = result + getElementMultipler(pokemon1elements[i], pokemon2elements[j])
            end
        end

        return result
    end

    local function findMaxInTable(inTable)
        if (#inTable < 1) then
            return nil
        end

        local resultKey, resultValue, tableKey, tableValue = -1, -1, nil, nil

        for tableKey = 1, #inTable do
            tableValue = inTable[tableKey]

            if (tableValue > -1 and tableValue > resultValue) then
                resultKey = tableKey
                resultValue = tableValue
            end
        end

        if (resultValue > -1) then
            return resultKey
        end

        return nil
    end

    function NpcBattle:doCallNextPokemon()
        local pid = getNpcOpponent(self.uid)
        self.defeatedPokemonCount = (self.currentPokemonId and (self.defeatedPokemonCount + 1) or 0)
        if (self.defeatedPokemonCount > 0 and self.onDefeatNpcPokemon) then
            self:onDefeatNpcPokemon(pid, self.defeatedPokemonCount)
        end

        if (self.linealOrder) then
            if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON1_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
                self:doCallPokemon(self.currentPokemons[1], pid)
                self:setPokemonStatus(1, NPC_POKEMON_STATUS.CANNOT_USE)
                self.currentPokemonId = 1
                return true
            end

            if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON2_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
                self:doCallPokemon(self.currentPokemons[2], pid)
                self:setPokemonStatus(2, NPC_POKEMON_STATUS.CANNOT_USE)
                self.currentPokemonId = 2
                return true
            end

            if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON3_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
                self:doCallPokemon(self.currentPokemons[3], pid)
                self:setPokemonStatus(3, NPC_POKEMON_STATUS.CANNOT_USE)
                self.currentPokemonId = 3
                return true
            end

            if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON4_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
                self:doCallPokemon(self.currentPokemons[4], pid)
                self:setPokemonStatus(4, NPC_POKEMON_STATUS.CANNOT_USE)
                self.currentPokemonId = 4
                return true
            end

            if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON5_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
                self:doCallPokemon(self.currentPokemons[5], pid)
                self:setPokemonStatus(5, NPC_POKEMON_STATUS.CANNOT_USE)
                self.currentPokemonId = 5
                return true
            end

            if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON6_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
                self:doCallPokemon(self.currentPokemons[6], pid)
                self:setPokemonStatus(6, NPC_POKEMON_STATUS.CANNOT_USE)
                self.currentPokemonId = 6
                return true
            end

            return false
        end

        local npcPokemonsMultiplers = {}
        local npcOpponentPokemonName = getPlayerPokemonName(pid)

        if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON1_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
            table.insert(npcPokemonsMultiplers, 1, getElementMultiplerBetweenPokemons(self.currentPokemons[1], npcOpponentPokemonName))
        else
            table.insert(npcPokemonsMultiplers, 1, -1)
        end

        if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON2_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
            table.insert(npcPokemonsMultiplers, 2, getElementMultiplerBetweenPokemons(self.currentPokemons[2], npcOpponentPokemonName))
        else
            table.insert(npcPokemonsMultiplers, 2, -1)
        end

        if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON3_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
            table.insert(npcPokemonsMultiplers, 3, getElementMultiplerBetweenPokemons(self.currentPokemons[3], npcOpponentPokemonName))
        else
            table.insert(npcPokemonsMultiplers, 3, -1)
        end

        if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON4_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
            table.insert(npcPokemonsMultiplers, 4, getElementMultiplerBetweenPokemons(self.currentPokemons[4], npcOpponentPokemonName))
        else
            table.insert(npcPokemonsMultiplers, 4, -1)
        end

        if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON5_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
            table.insert(npcPokemonsMultiplers, 5, getElementMultiplerBetweenPokemons(self.currentPokemons[5], npcOpponentPokemonName))
        else
            table.insert(npcPokemonsMultiplers, 5, -1)
        end

        if (getCreatureStorage(self.uid, NPC_STORAGES.POKEMON6_STATUS) == NPC_POKEMON_STATUS.CAN_USE) then
            table.insert(npcPokemonsMultiplers, 6, getElementMultiplerBetweenPokemons(self.currentPokemons[6], npcOpponentPokemonName))
        else
            table.insert(npcPokemonsMultiplers, 6, -1)
        end

        local bestPokemonToUseNow = findMaxInTable(npcPokemonsMultiplers)
        if (bestPokemonToUseNow) then
            self:doCallPokemon(self.currentPokemons[bestPokemonToUseNow], pid)
            self:setPokemonStatus(bestPokemonToUseNow, NPC_POKEMON_STATUS.CANNOT_USE)
            self.currentPokemonId = bestPokemonToUseNow
            return true
        end

        return false
    end

    function NpcBattle:doBattleEnd(pid, battleEndMode)
        if (battleEndMode == BATTLE_END_MODES.PLAYER_WIN) then
            if (self.lossSpeech) then
                doCreatureSay(self.uid, __L(pid, self.lossSpeech), TALKTYPE_SAY)
            else
                doCreatureSay(self.uid, __L(pid, table.random(NPC_DIALOGS.NPC_LOSS)), TALKTYPE_SAY)
            end

            if (self.rewardBaseExp > 0 or self.rewardBadge ~= nil or #self.rewardItems > 0 or
                    #self.rewardUniqueItems > 0 or self.currentBet > 0) then
                doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "You won %s and received your reward."), self.name))
            else
                doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "You won %s."), self.name))
            end

            doPlayerAddBattleWin(pid)
            doPlayerAddRespect(pid, (self.rewardRespect * 2))
            doPlayerAddStatistic(pid, PLAYER_STATISTIC_IDS.DEFEAT_NPC, 1)

            local previousLevel = self:getLevel(pid)
            self:setLevel(pid, previousLevel + 1)

            if (self.rewardBaseExp > 0) then
                doPlayerAddExperience(pid, self.rewardBaseExp * previousLevel)
                doSendAnimatedText(getCreaturePosition(pid), "+EXP!", COLOR_LIGHTGREEN)
            end

            if (self.rewardBadge ~= nil) then
                self:doPlayerGiveBadge(pid, self.rewardBadge)
                doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "Congratulations! You received the %s from %s."), getItemNameById(self.rewardBadge.newItemId), self.name))
            end

            doPlayerAchievementCheck(pid, ACHIEVEMENT_IDS.KANTO_BADGES)

            for i = 1, #self.rewardItems, 2 do
                doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "You received: %s [%sx]."), getItemNameById(self.rewardItems[i]), self.rewardItems[i + 1]))
                doPlayerAddItem(pid, self.rewardItems[i], self.rewardItems[i + 1], true)
            end

            for i = 1, #self.rewardUniqueItems, 2 do
                local item = doCreateUniqueItemEx(pid, self.rewardUniqueItems[i], self.rewardUniqueItems[i + 1])
                if (item) then
                    if (doPlayerAddItemEx(pid, item, false) == RETURNVALUE_NOERROR) then
                        doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "You received: %s [%sx]."), getItemNameById(self.rewardUniqueItems[i]), self.rewardUniqueItems[i + 1]))
                    else
                        doPlayerAddDepotItem(pid, 0, item)
                        doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "You received: %s [%x] directly into your depot."), getItemNameById(self.rewardUniqueItems[i]), self.rewardUniqueItems[i + 1]))
                    end
                else
                    log(LOG_TYPES.ERROR, "NpcBattle:doBattleEnd - Can't create reward unique item.",
                        getCreatureName(pid), self.rewardUniqueItems[i], self.rewardUniqueItems[i + 1])
                end
            end

            if (self.currentBet > 0) then
                doPlayerAddMoney(pid, math.floor(self.currentBet * 2))
            end

            if (self.oneWin) then
                self:setPlayerLastBattleTimeWithNpc(pid, true)
            end

            if (self.lastDefeatTimeStorage) then
                doCreatureSetStorage(pid, self.lastDefeatTimeStorage, os.time())
            end

            if (self.onWin) then
                self.onWin(pid)
            end

        elseif (battleEndMode == BATTLE_END_MODES.PLAYER_LOSS) then
            if (self.winSpeech) then
                doCreatureSay(self.uid, __L(pid, self.winSpeech), TALKTYPE_SAY)
            else
                doCreatureSay(self.uid, __L(pid, table.random(NPC_DIALOGS.NPC_WIN)), TALKTYPE_SAY)
            end
            doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, string.format(__L(pid, "You have been defeated by %s!"), self.name))
            doPlayerAddBattleLoss(pid)

        elseif (battleEndMode == BATTLE_END_MODES.PLAYER_AWAY) then
            doCreatureSay(self.uid, table.random(NPC_DIALOGS.NPC_WIN), TALKTYPE_SAY)
            doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, "You and your opponent were too far from each other and the battle was canceled.")
            doPlayerAddBattleLoss(pid)
        end

        if (self:isPokemonOnline()) then
            local npcPokemon = self:getPokemon()

            doCreatureSay(self.uid, string.format(__L(pid, "Back, %s!"), getCreatureName(npcPokemon)), TALKTYPE_SAY)
            doSendMagicEffect(getCreaturePosition(npcPokemon), balls["poke"].effects.use)
            doRemoveCreature(npcPokemon)
        end

        self:setBattleStatus(NPC_BATTLE_STATUS.ISNT_BATTLEING)
        self.npcHandler:releaseFocus(pid)

        if (isPlayer(pid)) then
            setPlayerBattleing(pid, false)
            setPlayerDisconnectAtExit(pid, true)
            doCreatureSetNoMove(pid, false)

            if (self.onEnd) then
                self.onEnd(pid, battleEndMode == BATTLE_END_MODES.PLAYER_WIN, self.uid)
            end
        end
    end

    function NpcBattle:doBattleCheck(pid, battleTimeRemaing, decreaseTimeout, playerLastFreeCap, checkAlivePokemon)
        if (not isPlayer(pid)) then
            self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_LOGOUT)
            return
        end

        local playerCap = getPlayerFreeCap(pid)
        if (playerLastFreeCap and playerCap ~= playerLastFreeCap) then
            doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, "You modified your Pokemon team during battle! You're out!")
            self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_LOSS)
            return
        end

        if (battleTimeRemaing == 0) then
            doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, "Your time has ended.")
            self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_LOSS)
            return
        end

        local playerPosition = getCreaturePosition(pid)
        local npcPosition = getCreaturePosition(self.uid)
        if (not npcPosition) then
            return
        end

        if (getDistanceBetween(npcPosition, playerPosition) > 6 or playerPosition.z ~= npcPosition.z) then
            self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_AWAY)
            return
        end

        if (self:isPokemonOnline()) then
            local playerPokemon = getPlayerPokemon(pid)

            if (isCreature(playerPokemon)) then
                local npcPokemon = self:getPokemon()

                if (not hasTarget(npcPokemon)) then
                    doCreatureSetTarget(npcPokemon, playerPokemon)
                end

                if (not isExhaust(self.uid)) then
                    local move = self:getPokemonMove(npcPokemon, playerPokemon)
                    if (move) then
                        self:doPokemonUseMove(npcPokemon, move)
                    end
                end

                if (getRandom(0, 100) <= 25 or getDistanceBetween(getCreaturePosition(npcPokemon), getCreaturePosition(playerPokemon)) > 3) then
                    self:doOrderPokemon(npcPokemon, playerPokemon, pid)
                end

            elseif (getPlayerDuelPokemonRemaing(pid) <= 0) then
                self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_LOSS)
                return

            elseif (decreaseTimeout) then
                if (checkAlivePokemon) then
                    local tmpBalls = getPlayerAllBallsWithPokemon(pid)
                    local alives = #tmpBalls

                    if (alives < PLAYER_BALL_MAX) then -- Maybe this player hasnt six Pokemon, so the timeout is useless
                        for _, ball in pairs(tmpBalls) do
                            local ballName = ballsNames[ball.itemid]
                            if (not ballName or ball.itemid == balls[ballName].discharged) then
                                alives = alives - 1
                            end
                        end

                        if (alives <= 0) then
                            self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_LOSS)
                            return
                        end

                    else
                        checkAlivePokemon = nil -- Isnt need check if the player got six Pokemon, the timeout will work fine
                    end
                end

                local timeout = self:getBattleTimeoutRemaing()
                if (timeout <= 0) then
                    doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, "Your time has ended.")
                    self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_LOSS)
                    return

                else
                    doSendAnimatedText(playerPosition, timeout, TEXTCOLOR_RED)
                    self:setBattleTimeout(timeout - 1)
                    decreaseTimeout = false
                end
            else
                decreaseTimeout = true
            end
        else
            if (self:doCallNextPokemon()) then
                doCreatureSay(self.uid, __L(pid, table.random(NPC_DIALOGS.POKEMON_DOWN)), TALKTYPE_SAY)
            else
                self:doBattleEnd(pid, BATTLE_END_MODES.PLAYER_WIN)
                return
            end
        end
        addEvent(self.doBattleCheck, 500, self, pid, battleTimeRemaing - 0.5, decreaseTimeout, playerCap, checkAlivePokemon)
    end

    function NpcBattle:doBattleStart(pid)
        self:setBattleStatus(NPC_BATTLE_STATUS.IS_BATTLEING)
        self:setOpponent(pid)
        self:doUpdateCurrentPokemons(pid)
        self:doPokemonsStatusReset()
        self:doBattleTimeoutReset()
        self:doCallNextPokemon()
        self:setPlayerLastBattleTimeWithNpc(pid)
        if (self.currentBet > 0) then doPlayerRemoveMoney(pid, self.currentBet) end
        if (self.payRespect > 0) then doPlayerAddRespect(pid, -self.payRespect) end
        setPlayerDuelPokemonRemaing(pid, 6)
        setPlayerBattleing(pid, true)
        doAddCondition(pid, pokemonCallDelayCondition)
        doCreatureSay(self.uid, __L(pid, table.random(NPC_DIALOGS.BATTLE_START)), TALKTYPE_SAY)
        setPlayerDisconnectAtExit(pid, false)
        doCreatureSetNoMove(pid, true)
        self:doBattleCheck(pid, 10 * 60, true, nil, true)
    end

    function NpcBattle:doPokemonUseMove(pokemonUid, move)
        if (doPokemonUseSkill(pokemonUid, move)) then
            self:setMoveCooldown(move)
            doAddExhaust(self.uid)
        end
    end

    function NpcBattle:doUpdateCurrentPokemons(pid)
        local npcLevel = self:getLevel(pid)
        self.currentPokemons = table.copy(self.pokemons)

        -- Add all possibly pokemons to my team
        for i, change in ipairs(self.changes) do
            if (npcLevel >= change.level) then
                table.insert(self.currentPokemons, change.pokemon)
            end
        end

        -- If I get more then I can carry, remove random
        while (#self.currentPokemons > 6) do
            table.remove(self.currentPokemons, math.random(1, #self.currentPokemons))
        end

        -- What level my pokemons are now
        local level
        if (self.difficulty ~= NPC_DIFFICULTY_DYNAMIC) then
            level = self.difficulty + ((npcLevel - 1) * NPC_GROW_PER_LEVEL)
            level = (level <= POKEMON_LEVEL_MAX and level or POKEMON_LEVEL_MAX)
        else
            level = getPlayerLevel(pid)
            level = level >= 10 and level or 10
            level = level <= 90 and level or 90
            level = math.random(level - 5, level)
        end

        -- Evolve them, if possible
        if (self.pokemonTeamEvolvable) then
            for i = 1, #self.currentPokemons do
                local evolutions = getPokemonEvolutions(self.currentPokemons[i])
                while (evolutions and #evolutions > 0) do
                    local tmpEvolutions = evolutions
                    evolutions = nil

                    for k, v in ipairs(tmpEvolutions) do
                        if (level >= v.requiredLevel) then
                            self.currentPokemons[i] = v.name
                            evolutions = getPokemonEvolutions(self.currentPokemons[i])
                            break
                        end
                    end
                end
            end
        end
    end

    function NpcBattle:doUpdateCurrentBet(pid)
        self.currentBet = self.baseBet * self:getLevel(pid)
    end

    function NpcBattle:doOrderPokemon(pokemonUid, targetUid, pid)
        local pos = getPositionAdjacent(pokemonUid, getCreaturePosition(targetUid))
        if (pos) then
            if (not getPathToEx(pokemonUid, pos)) then
                doTeleportThing(pokemonUid, getCreaturePosition(targetUid))
                return
            end
            --doCreatureWalkToPosition(pokemonUid, pos)

            if ((os.time() - self.lastOrder) > 4) then
                doCreatureSay(self.uid, string.format(__L(pid, "%s, go there!"), getCreatureNickname(pokemonUid)), TALKTYPE_MONSTER)
                self.lastOrder = os.time()
            end
        end
    end

    -- Global functions
    function NpcBattle:doTalkStart(npcUid, pid)
        self.uid = npcUid
        if (self:isBattleing()) then
            selfSay("I'm battling at the moment, please wait.", pid)
            return TALK_STATE.ERASE

        else
            local result = self:canPlayerBattleWithNpc(pid)
            if (result == true) then
                selfSay(string.format(__L(pid, "Do you really want to battle with me?%s%s"),
                    (self.currentBet > 0 and (string.format(__L(pid, " (You will bet %s dollars)"), self.currentBet)) or ""),
                    (self.payRespect > 0 and (string.format(__L(pid, " (You will pay %s respect points)"), self.payRespect)) or "")), pid)
                return TALK_STATE.ACCEPTING_BATTLE

            else
                selfSay(result, pid)
                return TALK_STATE.ERASE
            end
        end
    end

    function NpcBattle:doTalkEnd(npcUid, pid, talkState)
        self.uid = npcUid
        if (talkState == TALK_STATE.ACCEPTING_BATTLE) then
            if (self:isBattleing()) then
                selfSay("I'm battling at the moment, please wait.", pid)
                return TALK_STATE.ERASE

            elseif (not isPokemonOnline(pid) and #getCreatureSummons(pid) == 0) then
                selfSay(__L(pid, table.random(NPC_DIALOGS.PLAYER_WITHOUT_POKEMON)), pid)
                return TALK_STATE.ERASE

            else
                local result = self:canPlayerBattleWithNpc(pid)
                if (result == true) then
                    self:doBattleStart(pid)
                else
                    selfSay(result, pid)
                    return TALK_STATE.ERASE
                end
            end
        else
            selfSay("Huh?", pid)
        end
        return TALK_STATE.ERASE
    end

    function NpcBattle:doForceBattleStart(npcUid, pid)
        if (self:isBattleing()) then
            return false
        end

        self.uid = npcUid
        self:doBattleStart(pid)
        return true
    end

    function getNpcOpponent(nid)
        return getCreatureStorage(nid, NPC_STORAGES.OPPONENT)
    end

    function getNpcBattleByName(name)
        return NpcsByName[name]
    end

    function getPlayerDefeatedNPC(cid, npcName)
        local r = getCreatureStorage(cid,
            (type(npcName) == 'string' and getNpcBattleByName(npcName).levelStorage or npcName)) -- npcName can be the storage too, because I can normaly call this function only inside NPCs
        return r > 1
    end

    function getPlayerLastDefeatedNpc(cid, lastDefeatTimeStorage)
        return getCreatureStorage(cid, lastDefeatTimeStorage)
    end

    function doPlayerEraseDefeatedNpc(cid, npcName)
        if (type(npcName) ~= 'string') then
            log(LOG_TYPES.ERROR, "npcBattle:doPlayerEraseDefeatedNPC - npcName is not a string.", getCreatureName(cid), npcName)
            return
        end

        doCreatureSetStorage(cid, getNpcBattleByName(npcName).levelStorage, -1)
        doCreatureSetStorage(cid, getNpcBattleByName(npcName).lastBattleTimeStorage, -1)
    end
end

 

 

 

 

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

  • Conteúdo Similar

    • Por braianlomas
      Como faço para corrigir esse problema para meu cliente, eu uso o tfs 0.3.6  
      Quero resolver esse problema que tenho no meu cliente, como e onde posso resolver?  
      Eu uso o tfs 0.3.6, não tenho as fontes do cliente, se você puder me dar eu vou amá-las para sempre  
       

       
    • Por A.Mokk
      Ola pessoal, estou tentando compilar o TFS 1.5 Downgrade para 8.60 atraves do MSVC 2022, ao tentar compilar da o seguinte erro:
       
       
      Fiz o download do MSVC, GitDash, TFS-SDK-3.2, e de varios boosts que tentei, ao fazer o seguinte procedimento no GitDash:
       
      Ao chegar em ./bootstrap-vcpkg.bat o GitDash nao consegue realizar o procedimento corretamente, alguem poderia me ajudar ?

      Tentei de diversas formas mas o mesmo erro sempre persiste, atualmente meu servidor utiliza TFS 0.4, consigo compilar sem nenhum problema no MSVC 2010, porem, as limitações do TFS 0.4 estão me fazendo precisar atualizar, se alguem souber como corrigir esses erros eu agradeço !

      Tutoriais utilizados :
      Compiling on Windows (vcpkg) · otland/forgottenserver Wiki · GitHub
      Compiling on Windows · otland/forgottenserver Wiki · GitHub
      Compilando TFS 1.3 com vídeo-aula - Tutoriais Infraestrutura & Proteção - Tibia King - Tudo sobre Tibia, OTServ e Bots!
      Compilar TFS 1.3 Vcpkg - Tutoriais Infraestrutura & Proteção - Tibia King - Tudo sobre Tibia, OTServ e Bots!
       
      O que acontece no Powershell:
       
    • Por thunmin
      .Qual servidor ou website você utiliza como base? 
      Canary 2.3.6
      Qual o motivo deste tópico? 
      Queria fazer com que os players não pudessem mexer no aleta sio, pois, agora os mesmos estão conseguindo mexer nos itens
      Está surgindo algum erro? Se sim coloque-o aqui. 
       
      Você tem o código disponível? Se tiver publique-o aqui: 
         
      Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 
       
    • Por thunmin
      .Qual servidor ou website você utiliza como base? 
      canary para o cliente 13.16
      Qual o motivo deste tópico? 
      Não consigo encontrar onde ajusta
      to com o problema no 13.16  o exausted, por exemplo os kinas era pra combar exori, erori gran e exori min, porém não ta indo ta dando exausted o char ta soltando magia ou runa e não consegue usar as potions
      Está surgindo algum erro? Se sim coloque-o aqui. 
       
      Você tem o código disponível? Se tiver publique-o aqui: 
         
      Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 
       
    • Por Andersontatuador
      Olá galera da TK, me chamo Anderson estou procurando alguém profissional em otservs e site.
      Já tenho um servidor o site e o cliente preciso só de uma pessoal competente, que esteja empenhado a trabalhar,
      não quero nada de graça, pois nessa onda fui mais roubado do quer eu pagar um profissional.
      caso alguém se interesse entrar em contato comigo através do whatsapp
      82 9 9304-9462
       
      Está surgindo algum erro? Se sim coloque-o aqui. 
       
      Você tem o código disponível? Se tiver publique-o aqui: 
         
      Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 
       
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo