[TFS 1.1] Monster Arena

Discussion in 'GlobalEvents, Spells & CreatureEvents' started by Summ, Mar 19, 2015.

  1. Summ

    Summ (\/)(;,,;)(\/) Y not? Staff Member Global Moderator

    Joined:
    Oct 15, 2008
    Messages:
    4,144
    [​IMG] Monster Arena Player vs. Player

    Description:
    You need 2 people for this minigame. You stand on the tiles and pull the lever.
    Inside the arena each player will get a random summon, which will then attack the enemy's monster. The player whose summon kills the other monster first wins and gets rewarded.

    Map:
    Mediafire: http://www.mediafire.com/download/qnnqj1rmilmrd5a/monsterarena.otbm
    [​IMG]

    Scripts:

    Actions
    actions.xml
    Code:
    <action actionid="1500" script="monsterarena.lua"/>
    actions/scripts/monsterarena.lua
    Code:
    MonsterArena = {
        fromPosition = { Position(1022, 1030, 7), Position(1024, 1030, 7) },
        toPosition = { Position(1020, 1021, 7), Position(1022, 1021, 7) },
        spawnPosition = { Position(1020, 1022, 7), Position(1022, 1020, 7) },
        area = {
            from = Position(1015, 1016, 7),
            to = Position(1027, 1026, 7)
        },
        exitPosition = Position(1022, 1028, 7),
        reward = {itemId = 2160, count = 10},
    
        blockItemId = 3402,
    
        -- Only convincable / summonable monsters
        -- You can create custom monsters which are stronger and convincable
        monsters = {'Troll', 'Rat', 'Tortoise', 'Orc Berserker', 'Minotaur'},
        event = 'MonsterArenaDeath',
    
        players = {}
    }
    
    function MonsterArena.hasPlayer(player)
        local position = player:getPosition()
        return position.x >= MonsterArena.area.from.x and position.y >= MonsterArena.area.from.y
                and position.x <= MonsterArena.area.to.x and position.y <= MonsterArena.area.to.y
                and position.z == MonsterArena.area.from.z
    end
    
    function MonsterArena.isOccupied()
        for _, pid in ipairs(MonsterArena.players) do
            local player = Player(pid)
            if player and MonsterArena.hasPlayer(player) then
                return true
            end
        end
        return false
    end
    
    function MonsterArena.clean()
        for i = 1, #MonsterArena.players do
            MonsterArena.players[i] = nil
        end
    end
    
    function onUse(player, item, fromPosition, target, toPosition, isHotkey)
        if item.itemid ~= 1945 then
            item:transform(1946)
            return true
        end
    
        if MonsterArena.isOccupied() then
            player:sendCancelMessage('The monster arena is currently occupied.')
            return true
        end
    
        local players = {}
        for _, fromPosition in ipairs(MonsterArena.fromPosition) do
            local creature = Tile(fromPosition):getTopCreature()
            if not creature or not creature:isPlayer() then
                player:sendCancelMessage('You need another player for the monster arena.')
                return true
            end
            table.insert(players, creature)
        end
    
        MonsterArena.clean()
    
        local summons = {}
        for i, player in ipairs(players) do
            player:teleportTo(MonsterArena.toPosition[i])
            MonsterArena.fromPosition[i]:sendMagicEffect(CONST_ME_POFF)
            MonsterArena.toPosition[i]:sendMagicEffect(CONST_ME_TELEPORT)
    
            local monsterName = MonsterArena.monsters[math.random(#MonsterArena.monsters)]
            local monster = Game.createMonster(monsterName, MonsterArena.spawnPosition[i], true)
            monster:setMaster(player)
            monster:registerEvent(MonsterArena.event)
            table.insert(summons, monster)
    
            Game.createItem(MonsterArena.blockItemId, 1, MonsterArena.spawnPosition[i])
    
            player:sendTextMessage(MESSAGE_INFO_DESCR, string.format('A %s is fighting for you this round!', monsterName))
            table.insert(MonsterArena.players, player.uid)
        end
    
        players[1]:setTarget(summons[2])
        players[2]:setTarget(summons[1])
    
        item:transform(1945)
        return true
    end
    
    Creaturescript
    creaturescripts.xml
    Code:
    <event type="death" name="MonsterArenaDeath" script="monsterarenadeath.lua"/>
    creaturescripts/scripts/monsterarenadeath.lua
    Code:
    function onDeath(monster, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
        local winnerPlayer = killer:getMaster()
        local loserPlayer = monster:getMaster()
    
        local reward = MonsterArena.reward
        if reward then
            winnerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, 'Your monster won the fight and earned a reward for you!')
            winnerPlayer:addItem(reward.itemId, reward.count)
        else
            winnerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, 'Your monster won the fight!')
        end
    
        loserPlayer:sendTextMessage(MESSAGE_INFO_DESCR, 'Your monster lost the fight!')
    
        winnerPlayer:teleportTo(MonsterArena.exitPosition)
        loserPlayer:teleportTo(MonsterArena.exitPosition)
        MonsterArena.exitPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
    
        for _, position in ipairs(MonsterArena.spawnPosition) do
            local item = Tile(position):getItemById(MonsterArena.blockItemId)
            if item then
                item:remove()
            end
        end
    
        killer:remove()
        return true
    end
    
     
  2. Eldin

    Eldin Eldin Projects Premium User

    Joined:
    Jun 12, 2008
    Messages:
    1,259
    Looking forward to test this out! :)

    Kind Regards,
    Eldin.
     
  3. StreamSide

    StreamSide Joseluis Gonzalez

    Joined:
    Aug 31, 2007
    Messages:
    2,515
    can I kiss u? great job again bro
     
  4. abbe

    abbe Premium User Premium User

    Joined:
    Dec 21, 2008
    Messages:
    233
    "You need another player for the monster Arena", 2 people standing on the tiles, tried setting the tiles to actionid 1500 aswell but it didnt work
     
  5. Hugofasima

    Hugofasima Website: thenosegang.servegame.com

    Joined:
    Jun 24, 2015
    Messages:
    206
    Perfect!!!!
     
  6. Scrappy Coco

    Scrappy Coco Member

    Joined:
    Dec 27, 2014
    Messages:
    95
    Good Job Summ tenks for much.
     
  7. Hugofasima

    Hugofasima Website: thenosegang.servegame.com

    Joined:
    Jun 24, 2015
    Messages:
    206
    Hi! My TFS is 1.1, I did something wrong?

    I'm getting this error on Distro


    Code:
    Lua Script Error: [CreatureScript Interface]
    data/creaturescripts/scripts/events/monsterarenadeath.lua:onDeath
    data/creaturescripts/scripts/events/monsterarenadeath.lua:7: attempt to index lo
    cal 'winnerPlayer' (a nil value)
    stack traceback:
            [C]: in function '__index'
            data/creaturescripts/scripts/events/monsterarenadeath.lua:7: in function
    <data/creaturescripts/scripts/events/monsterarenadeath.lua:1>
    
    The script is:

    Code:
    function onDeath(monster, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
        local winnerPlayer = killer:getMaster()
        local loserPlayer = monster:getMaster()
    
        local reward = MonsterArena.reward
        if reward then
            winnerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, 'Your monster won the fight and earned a reward for you!')
            winnerPlayer:addItem(reward.itemId, reward.count)
        else
            winnerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, 'Your monster won the fight!')
        end
    
        loserPlayer:sendTextMessage(MESSAGE_INFO_DESCR, 'Your monster lost the fight!')
    
        winnerPlayer:teleportTo(MonsterArena.exitPosition)
        loserPlayer:teleportTo(MonsterArena.exitPosition)
        MonsterArena.exitPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
    
        for _, position in ipairs(MonsterArena.spawnPosition) do
            local item = Tile(position):getItemById(MonsterArena.blockItemId)
            if item then
                item:remove()
            end
        end
    
        killer:remove()
        return true
    end
    If is needed:
    local deathListEnabled = true
    local maxDeathRecords = 5

    function onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
    local playerId = player:getId()
    if nextUseStaminaTime[playerId] ~= nil then
    nextUseStaminaTime[playerId] = nil
    end

    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
    if not deathListEnabled then
    return
    end

    local byPlayer = 0
    local killerName
    if killer ~= nil then
    if killer:isPlayer() then
    byPlayer = 1
    else
    local master = killer:getMaster()
    if master and master ~= killer and master:isPlayer() then
    killer = master
    byPlayer = 1
    end
    end
    killerName = killer:getName()
    else
    killerName = "field item"
    end

    local byPlayerMostDamage = 0
    local mostDamageKillerName
    if mostDamageKiller ~= nil then
    if mostDamageKiller:isPlayer() then
    byPlayerMostDamage = 1
    else
    local master = mostDamageKiller:getMaster()
    if master and master ~= mostDamageKiller and master:isPlayer() then
    mostDamageKiller = master
    byPlayerMostDamage = 1
    end
    end
    mostDamageName = mostDamageKiller:getName()
    else
    mostDamageName = "field item"
    end

    local playerGuid = player:getGuid()
    db.query("INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" .. playerGuid .. ", " .. os.time() .. ", " .. player:getLevel() .. ", " .. db.escapeString(killerName) .. ", " .. byPlayer .. ", " .. db.escapeString(mostDamageName) .. ", " .. byPlayerMostDamage .. ", " .. (unjustified and 1 or 0) .. ", " .. (mostDamageUnjustified and 1 or 0) .. ")")
    local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid)

    local deathRecords = 0
    local tmpResultId = resultId
    while tmpResultId ~= false do
    tmpResultId = result.next(resultId)
    deathRecords = deathRecords + 1
    end

    if resultId ~= false then
    result.free(resultId)
    end

    local limit = deathRecords - maxDeathRecords
    if limit > 0 then
    db.asyncQuery("DELETE FROM `player_deaths` WHERE `player_id` = " .. playerGuid .. " ORDER BY `time` LIMIT " .. limit)
    end

    if byPlayer == 1 then
    local targetGuild = player:getGuild()
    targetGuild = targetGuild and targetGuild:getId() or 0
    if targetGuild ~= 0 then
    local killerGuild = killer:getGuild()
    killerGuild = killerGuild and killerGuild:getId() or 0
    if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(playerId, killer:getId()) then
    local warId = false
    resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND ((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR (`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))")
    if resultId ~= false then
    warId = result.getDataInt(resultId, "id")
    result.free(resultId)
    end

    if warId ~= false then
    db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(player:getName()) .. ", " .. killerGuild .. ", " .. targetGuild .. ", " .. os.time() .. ", " .. warId .. ")")
    end
    end
    end
    end
    end

    -------------------------------------- @edit


    SOLVED!

    https://otland.net/threads/error-attempt-to-index-local-a-nil-value.234683/#post-2263964
     
    Last edited: Jul 20, 2015
  8. Ahead

    Ahead Member

    Joined:
    Dec 27, 2013
    Messages:
    167
    Which would i have to add to the code if i want people to get removed certain item to take part in the event?

    Thanks!. Awesome script.
     
  9. Frikx

    Frikx Maroxy Scripts (XenoBot)

    Joined:
    Mar 10, 2013
    Messages:
    97
    Why do you "killer:remove()"? : (((
     
  10. silveralol

    silveralol Well-Known Member

    Joined:
    Mar 16, 2010
    Messages:
    1,227
    the killers is the summon of the winner player, if not remove it, if he fight again will have two summons
     
  11. Frikx

    Frikx Maroxy Scripts (XenoBot)

    Joined:
    Mar 10, 2013
    Messages:
    97
    You are right.
     
  12. Oualid

    Oualid Active Member

    Joined:
    Aug 24, 2014
    Messages:
    306
    Is it possible to make it impossible to stop attacking the other summon? Because people can block the spawn if they attack their opponents monster and then stop attacking it because then their summon will stop attacking either. Or maybe add something like kick after "X" amount of time if there still is no winner kick all players and send a message.
     
    Last edited: Nov 3, 2016
  13. Oualid

    Oualid Active Member

    Joined:
    Aug 24, 2014
    Messages:
    306
  14. Oualid

    Oualid Active Member

    Joined:
    Aug 24, 2014
    Messages:
    306
  15. Oualid

    Oualid Active Member

    Joined:
    Aug 24, 2014
    Messages:
    306
    Couple months later...... Bump
     
  16. Oualid

    Oualid Active Member

    Joined:
    Aug 24, 2014
    Messages:
    306
  17. Oualid

    Oualid Active Member

    Joined:
    Aug 24, 2014
    Messages:
    306

Share This Page