CreatureEvent [TFS 1.2] Revive system + resurrection spell by Zbizu

Discussion in 'GlobalEvents, Spells & CreatureEvents' started by zbizu, Oct 24, 2015.

  1. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    based on @Colors revive system

    [​IMG]

    [​IMG]

    [​IMG]

    groups.xml:
    Code (Text):
    1.     <group id="0" name="player_dead" flags="13194139558159" access="0" maxdepotitems="0" maxvipentries="0" />
    creaturescripts.xml:
    Code (Text):
    1. <event type="preparedeath" name="modalDeath" script="modaldeath.lua"/>
    2.     <event type="modalwindow" name="deathMW" script="modaldeath.lua"/>
    3.     <event type="login" name="loginDeath" script="modaldeath.lua"/>
    modaldeath.lua:
    Code (Text):
    1. -- revive system by zbizu
    2. -- config
    3.     local deathStorage = 250120
    4.     local counterStorage = 250121 -- res expiration timestamp
    5.     local deathGroupId = 0
    6.     local reviveStone = 2674 -- red apple, change it
    7.     local resTime = 30 * 60 -- 30 minutes
    8.     local showCountdown = true -- shows timer above dead player
    9. -- end of config
    10.  
    11. local condition = Condition(CONDITION_OUTFIT)
    12. condition:setTicks(-1)
    13.  
    14. function Player:setHealth(value)
    15.     if not self:isPlayer() then return false end
    16.     self:addHealth(value - self:getHealth())
    17. return true
    18. end
    19.  
    20. function Player:setMana(value)
    21.     if not self:isPlayer() then return false end
    22.     self:addMana(value - self:getMana(), false)
    23. return true
    24. end
    25.  
    26.  
    27. function buildModalWindow(cid)
    28.     local player = Player(cid)
    29.     local resitem = player:getItemCount(reviveStone)
    30.    
    31.     local modal = ModalWindow(999, "You are dead", "Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto the world in exchange for a small sacrifice. " .. (resitem > 0 and "\n\n" .. ItemType(reviveStone):getName() .. " x" .. resitem or "") .. "\n\nIf you choose to return, logout or your time run\nout, death penatly will be applied.")
    32.  
    33.     modal:addButton(1, "Return")
    34.     modal:setDefaultEnterButton(1)
    35.     modal:addButton(2, "Wait")
    36.     modal:setDefaultEscapeButton(2)
    37.  
    38.     if resitem > 0 then
    39.         modal:addButton(3, "Use Item")
    40.     end
    41.  
    42.     return modal:sendToPlayer(player)
    43. end
    44.  
    45. function Player:isDead()
    46.     return self:getGroup():getId() == deathGroupId
    47. end
    48.  
    49. function Player:die()
    50.     self:toggleDeath()
    51.     self:setStorageValue(counterStorage, -1)
    52.     self:setStorageValue(deathStorage, 1)
    53.     self:addHealth(-(self:getMaxHealth()))
    54.     return true
    55. end
    56.  
    57. function sendDeathWindowOnMove(cid, lockPos)
    58.     local player = Player(cid)
    59.     if not player then return false end
    60.     if not player:isDead() then
    61.         return false
    62.     end
    63.    
    64.     if os.time() > player:getStorageValue(counterStorage) then
    65.         player:die()
    66.         return true
    67.     end
    68.    
    69.     addEvent(sendDeathWindowOnMove, 100, cid, lockPos)
    70.    
    71.     if player:getPosition() ~= lockPos then
    72.         player:teleportTo(lockPos)
    73.         buildModalWindow(cid)
    74.     end
    75.    
    76.     return true
    77. end
    78.  
    79. function sendReviveCountdown(cid)
    80.     if not showCountdown then return false end
    81.     local player = Player(cid)
    82.     if not player then return false end
    83.     if not player:isDead() then
    84.         return false
    85.     end
    86.    
    87.     local timeleft = os.date("!%X",player:getStorageValue(counterStorage) - os.time()):split(":")
    88.    
    89.    
    90.     player:say(timeleft[2] .. ":" .. timeleft[3], TALKTYPE_MONSTER_SAY)
    91.     addEvent(sendReviveCountdown, 1000, cid)
    92.     return true
    93. end
    94.  
    95. function Player:toggleDeath(countdown)
    96.     if self:isDead() then
    97.         self:setGroup(Group(1))
    98.         self:setHiddenHealth(false)
    99.         self:setHealth(math.ceil(self:getMaxHealth() * 0.3))
    100.         self:setMana(math.ceil(self:getMaxMana() * 0.3))
    101.         self:removeCondition(CONDITION_OUTFIT)
    102.         return true
    103.     end
    104.    
    105.     if countdown then
    106.         self:setStorageValue(counterStorage, os.time() + countdown)
    107.     end
    108.    
    109.     self:setGroup(Group(deathGroupId))
    110.     self:setHiddenHealth(true)
    111.     buildModalWindow(self:getId())
    112.    
    113.     local pos = self:getPosition()
    114.     sendDeathWindowOnMove(self:getId(), pos)
    115.     sendReviveCountdown(self:getId())
    116.    
    117.     local npos = Position(pos.x + 1, pos.y, pos.z)
    118.     if not Tile(npos) then
    119.         Game.createTile(npos)
    120.     end
    121.    
    122.     self:teleportTo(npos, true)
    123.     return true
    124. end
    125.  
    126. function onLogin(player)
    127.     player:registerEvent("modalDeath")
    128.     player:registerEvent("deathMW")
    129.     player:registerEvent("loginDeath")
    130.  
    131.     if player:isDead() then
    132.         if player:getStorageValue(counterStorage) == -1 then
    133.             player:toggleDeath()
    134.             return true
    135.         end
    136.        
    137.         if os.time() > player:getStorageValue(counterStorage) then
    138.             player:die()
    139.             return true
    140.         end
    141.        
    142.         player:setHiddenHealth(true)
    143.         sendDeathWindowOnMove(player:getId(), player:getPosition())
    144.         sendReviveCountdown(player:getId())
    145.     end
    146.  
    147.     return true
    148. end
    149.  
    150. function onPrepareDeath(creature, killer)
    151. -- pvp kills may act weird
    152.     if not creature:isPlayer() then
    153.         return true
    154.     end
    155.    
    156.     if creature:getStorageValue(deathStorage) == 1 then
    157.         creature:setStorageValue(deathStorage, -1)
    158.         return true
    159.     end
    160.    
    161.     creature:toggleDeath(resTime)
    162.     condition:setOutfit(creature:getSex() == PLAYERSEX_FEMALE and 3065 or 3058)
    163.     creature:addCondition(condition)
    164.     return false
    165. end
    166.  
    167. function onModalWindow(player, modalWindowId, buttonId, choiceId)
    168.     if modalWindowId ~= 999 then
    169.         return false
    170.     end
    171.    
    172.     if not player:isDead() then
    173.         return false
    174.     end
    175.    
    176.     if buttonId == 1 then
    177.         player:die()
    178.         return true
    179.     elseif buttonId == 2 then
    180.         player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You decided to wait for a healer. Move in any direction to send revival window again.")
    181.         return true
    182.     elseif buttonId == 3 then
    183.         if player:getItemCount(reviveStone) == 0 then
    184.             player:sendCancelMessage("You don't have any item to revive yourself.")
    185.             return true
    186.         end
    187.        
    188.         player:getItemById(reviveStone, true):remove(1)
    189.         player:toggleDeath()
    190.         local revst = ItemType(reviveStone)
    191.         player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You revived yourself with " .. revst:getArticle() .. " " .. revst:getName() .. ".")
    192.     end
    193.     return true
    194. end
     
    Last edited: Jan 10, 2016
    Homeslice, luddex, Gomgom and 10 others like this.
  2. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    resurrection spell (spells/scripts/res.lua):
    Code (Text):
    1. local deathGroupId = 0
    2. function Player:isDead()
    3.     return self:getGroup():getId() == deathGroupId
    4. end
    5.  
    6. function onCastSpell(creature, var, isHotkey)
    7.     local position = creature:getPosition()
    8.     local manaCost = math.ceil(creature:getMaxMana() * 0.3)
    9.     if creature:getMana() < manaCost then
    10.         creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA)
    11.         position:sendMagicEffect(CONST_ME_POFF)
    12.         return false
    13.     end
    14.  
    15.     local target = Player(variantToNumber(var))
    16.     if not target then
    17.         creature:sendCancelMessage("Incorrect target.")
    18.         position:sendMagicEffect(CONST_ME_POFF)
    19.         return false
    20.     end
    21.    
    22.     if creature:getPosition():isSightClear(target:getPosition()) then
    23.         if target:isDead() then
    24.             creature:addMana(-manaCost, false)
    25.             creature:addManaSpent(manaCost)
    26.            
    27.             target:setGroup(Group(1))
    28.             target:setHiddenHealth(false)
    29.            
    30.             target:addMana(math.ceil(target:getMaxMana() * 0.3) - target:getMana(), false)
    31.             target:addHealth(math.ceil(target:getMaxHealth() * 0.3) - target:getHealth())
    32.             target:removeCondition(CONDITION_OUTFIT)
    33.            
    34.             target:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have been resurrected by " .. creature:getName() .. ".")
    35.             return true
    36.         end
    37.         creature:sendCancelMessage("You cannot resurrect this target.")
    38.         position:sendMagicEffect(CONST_ME_POFF)
    39.         return false
    40.     end
    41.    
    42.     creature:sendCancelMessage("Target unreachable.")
    43.     position:sendMagicEffect(CONST_ME_POFF)
    44.     return false
    45. end
    46.  
    spells.xml:
    Code (Text):
    1.     <instant group="healing" spellid="84" name="Resurrect Friend" words="exura mort sio" lvl="200" mana="0" prem="1" aggressive="0" blockwalls="1" needtarget="1" playernameparam="1" params="1" exhaustion="15000" groupcooldown="1000" needlearn="0" script="res.lua">
    2.         <vocation name="Druid" />
    3.         <vocation name="Elder Druid" />
    4.     </instant>
     
    Last edited: Oct 25, 2015
    Verrine, Codex NG, Eldin and 4 others like this.
  3. Webo

    Webo Otland 4ever

    Joined:
    Oct 20, 2013
    Messages:
    567
    Likes Received:
    184
    Best Answers:
    5
    Like IT! :);):(:mad::confused::p:cool::eek::oops:o_O:rolleyes:
     
  4. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    update: added countdown above dead player (can be disabled in config)
    [​IMG]
     
    Verrine likes this.
  5. strutZ

    strutZ Australian OT Member {AKA Beastn}

    Joined:
    Nov 16, 2014
    Messages:
    1,269
    Likes Received:
    446
    Best Answers:
    3
    oh nice job i'll try it out =)
     
  6. Colors

    Colors

    Joined:
    Mar 22, 2013
    Messages:
    909
    Likes Received:
    251
    Best Answers:
    0
    Good thing that finally someone did (or show) something nice with the system :p
    Just one question, I see that you took the part where I teleported the player to the temple, now how the player is getting off the monster targets?
     
    Athenuz likes this.
  7. SN4KY

    SN4KY Member

    Joined:
    Mar 19, 2015
    Messages:
    55
    Likes Received:
    12
    Best Answers:
    0
    monsters keep attacking dead players?
     
  8. Athenuz

    Athenuz Owlz!

    Joined:
    Oct 1, 2015
    Messages:
    234
    Likes Received:
    27
    Best Answers:
    0
    Yes xD
     
  9. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    The player can wait until someone kill monsters around.
    Resurrected player respawn with 30% of his max hp and mp, sometimes it's enough to run away.
    Otherwise death is death, they should accept their fate and return to temple ^^ Let's not ruin the game.

    btw. copied group flags from @Colors script and I still have no idea what are first(or last) two flags:
    13194139558159 - dead player flags
    it's 1100 0000 (flags 36-43) ... 0110 0001 0000 1111 (flags 0-15)
    1100 <- flag 43 and 42 are enabled, tfs has 37 flags as far as I know

    edit: area spell
    [​IMG]

    spells.xml:
    Code (Text):
    1.  
    2.     <instant group="healing" spellid="82" name="Mass Resurrection" words="exura mort mas res" lvl="300" mana="0" prem="1" aggressive="0" exhaustion="120000" groupcooldown="1000" needlearn="0" script="area_res.lua">
    3.         <vocation name="Druid" />
    4.         <vocation name="Elder Druid" />
    5.     </instant>
    spells/scripts/area_res.lua:
    Code (Text):
    1. local deathGroupId = 0
    2. function Player:isDead()
    3.     return self:getGroup():getId() == deathGroupId
    4. end
    5.  
    6. function onTargetCreature(creature, target)
    7.     local player = creature:getPlayer()
    8.     local position = player:getPosition()
    9.  
    10.     if not target then return true end
    11.     if not target:isPlayer() then return true end
    12.     if not target:isDead() then return true end
    13.     if not player:getPosition():isSightClear(target:getPosition()) then
    14.         return true
    15.     end
    16.    
    17.     target:setGroup(Group(1))
    18.     target:setHiddenHealth(false)
    19.    
    20.     target:addMana(math.ceil(target:getMaxMana() * 0.3) - target:getMana(), false)
    21.     target:addHealth(math.ceil(target:getMaxHealth() * 0.3) - target:getHealth())
    22.     target:removeCondition(CONDITION_OUTFIT)
    23.    
    24.     target:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have been resurrected by " .. creature:getName() .. ".")
    25.     return true
    26. end
    27.  
    28. local combat = Combat()
    29. combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
    30. combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0)
    31. combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
    32. combat:setArea(createCombatArea(AREA_CIRCLE3X3))
    33. combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature")
    34.  
    35. function onCastSpell(creature, var)
    36.     local manaCost = math.ceil(creature:getMaxMana() * 0.7)
    37.    
    38.     if creature:getMana() < manaCost then
    39.         creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA)
    40.         position:sendMagicEffect(CONST_ME_POFF)
    41.         return false
    42.     end
    43.    
    44.     creature:addMana(-manaCost, false)
    45.     creature:addManaSpent(manaCost)
    46.     return combat:execute(creature, var)
    47. end

    btw. anyone has idea how to reset closest monsters targetting?
     
    Last edited: Oct 25, 2015
    SN4KY likes this.
  10. Athenuz

    Athenuz Owlz!

    Joined:
    Oct 1, 2015
    Messages:
    234
    Likes Received:
    27
    Best Answers:
    0
    Maybe on the creaturescript, making the group for dead player untargetable (flags maybe?) if flags doesn't works, maybe the creaturescript making the group used for dead player untargetable :p
     
    Cornex and SN4KY like this.
  11. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    and register event for closest targets only, great idea!
     
  12. Athenuz

    Athenuz Owlz!

    Joined:
    Oct 1, 2015
    Messages:
    234
    Likes Received:
    27
    Best Answers:
    0
    I'm not even a newbie scripter, but i think this does the trick:

    (From Colors thread/script)
    Code (Text):
    1.  
    2. player:addHealth(-player:getHealth())
    3.  
    If what i think is right, this sets the player HP to 0 while you choice an option, making the monsters change target since the "dead" player have 0 HP..
    Just a small idea, not sure about it xD

    Edit:

    If player teleports/revive then this gives back the hp

    Code (Text):
    1.  
    2. if buttonId == 1 then
    3. player:applyDeathAttributes(false)
    4. player:removeCondition(CONDITION_OUTFIT)
    5. player:teleportTo(Town(choiceId):getTemplePosition())
    6. player:addHealth(player:getMaxHealth())
    7. player:addMana(player:getMaxMana())
    8. player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "[onModalWindow] USED THE FUCKING REVIVE.")
    9. end
    10.  
    I hope this make it easier :p
     
    Last edited: Oct 25, 2015
  13. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    I need to do the trick without actually killing the player, 0 hp kills the player so I don't think it's possible
    First post updated. Fixed monsters issue and hp.
     
    Last edited: Jan 10, 2016
    Verrine likes this.
  14. Printer

    Printer if Printer then print("LUA") end Premium User

    Joined:
    Dec 27, 2009
    Messages:
    5,604
    Likes Received:
    1,898
    Best Answers:
    5
    Great work :)
     
  15. Colors

    Colors

    Joined:
    Mar 22, 2013
    Messages:
    909
    Likes Received:
    251
    Best Answers:
    0
    I already told you what you changed what is causing this issue, you got it wrong.

    And the death flag:
     
    strutZ, zbizu and Athenuz like this.
  16. Caduceus

    Caduceus Decapitated Soul

    Joined:
    May 10, 2010
    Messages:
    276
    Likes Received:
    16
    Best Answers:
    0
    @zbizu Is there a way to bypass when in pvp arena?
     
    Last edited: Oct 28, 2015
  17. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    @Caduceus
    below
    Code (Text):
    1. function onPrepareDeath(creature, killer)
    add position checking (if statement) and put return true inside
     
  18. Lordaeron

    Lordaeron Member

    Joined:
    Mar 15, 2014
    Messages:
    134
    Likes Received:
    7
    Best Answers:
    0
    There is somthing wrong here.

    Code (Text):
    1. function onPrepareDeath(creature, killer)
    2. -- not sure if counts kill on pvp
    3.     if not creature:isPlayer() then
    4.         return true
    5.     end
    6.    
    7.     if creature:getStorageValue(deathStorage) == 1 then
    8.         creature:setStorageValue(deathStorage, -1)
    9.         return true
    10.     end
    11.    
    12.     creature:toggleDeath(resTime)
    13.     condition:setOutfit(creature:getSex() == PLAYERSEX_FEMALE and 3065 or 3058)
    14.     creature:addCondition(condition)
    15.     return false
    16. end
     
  19. Aeronx

    Aeronx Member

    Joined:
    Dec 17, 2015
    Messages:
    361
    Likes Received:
    17
    Best Answers:
    1
    Hello guys! Did anyone fix the problem where the creatures keep attacking you while you are waiting for res?
     
  20. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,347
    Best Answers:
    1
    The solution is in this thread. Try learning some scripting instead of asking for spoonfed.
     

Share This Page

Loading...