Spell Multi-Shot (For Monsters)

Discussion in 'GlobalEvents, Spells & CreatureEvents' started by Shadowsong, Mar 10, 2016.

  1. Shadowsong

    Shadowsong Game Developer & Graphic Designer

    Joined:
    Feb 23, 2010
    Messages:
    3,133
    Likes Received:
    2,360
    Best Answers:
    0
    Hey guys.

    Felt like making a small contribution, so here's a spell for monsters that I just made.

    Tested and Working on: TFS 0.3.6

    Spell Description
    Allows a monster to fire multiple projectiles at multiple targets in a single attack.
    The monster will always fire at least 1 shot, at its primary target, and several more shots will follow if you configure it so. The shots are scripted so that each shot can shoot a target only once. This means that if there are 2 players nearby, and the monster can fire 5 shots, only 2 shots will be shot at those 2 players, and no more.

    [​IMG]

    Spell Configuration

    The script has a configuration table where you can add configs for each monster that's gonna be using this ability. You can configure the range, the delay between each shot, damage, damage type, shoot and magic effect and how many shots you want them to fire.

    It can be found on line 7 of the script, under local configs:

    ["Lava Abomination"] = {
    mindmg = -300, -- Minimum damage (don't forget that this number has to be negative)
    maxdmg = -575, -- Maximum damage (don't forget that this number has to be negative)
    dmgtype = COMBAT_FIREDAMAGE, -- Damage type (for available types, check your Constants library)
    shooteff = 3, -- Number of distance effect that will be shot (can also be a constant)
    splasheff = 187, -- Number of magic effect that will be displayed when the target is shot (can also be a constant)
    delay = 200, -- Delay at which multiple shots will be fired. In miliseconds.
    shots = 2, -- How many shots will the monster fire per attack?
    shootrange = 6 -- Range at which the monster scans for targets and shoots the shots.
    }


    Spell Example
    I made this spell for a monster called Lava Abomination. This monster is made out of magma and has 2 heads, so I figured - why not make him fire 1 shot from each of his heads? Other examples include .. maybe a hunter monster that has a special bow which fires several arrows at once? It's up to your imagination.

    [​IMG]
    Setting the spell up

    Go to your monster's xml file, and under the attacks tag, add the following:

    Code (Text):
    1. <attack name="Multishot" interval="2000" chance="100"/>
    Go to spells/spells.xml and add this:
    Code (Text):
    1.  
    2.     <instant name="Multishot" words="msformonsters" lvl="999" mana="999" prem="0" range="6" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" needlearn="0" event="script" value="monster/multishot.lua">
    3.         <vocation id="0"/>
    4.     </instant>
    5.  
    In spells/monsters/ create a script file called multishot.lua and paste this code into it:
    Code (Text):
    1. --- Multishot Monster Spell ---
    2. --- by ShivaShadowsong -----
    3. --- For TFS 0.3.6 ------------
    4.  
    5. function onCastSpell(cid, var)
    6.  
    7. local configs = {
    8.     ["Lava Abomination"] = {
    9.         mindmg = -300, -- Minimum damage (don't forget that this number has to be negative)
    10.         maxdmg = -575, -- Maximum damage (don't forget that this number has to be negative)
    11.         dmgtype = COMBAT_FIREDAMAGE, -- Damage type (for available types, check your Constants library)
    12.         shooteff = 3, -- Number of distance effect that will be shot (can also be a constant)
    13.         splasheff = 187, -- Number of magic effect that will be displayed when the target is shot (can also be a constant)
    14.         delay = 200, -- Delay at which multiple shots will be fired. In miliseconds.
    15.         shots = 2, -- How many shots will the monster fire per attack?
    16.         shootrange = 6 -- Range at which the monster scans for targets and shoots the shots.
    17.     }
    18. }
    19.  
    20.     ---- Don't touch anything below unless you know what you're doing ----
    21.  
    22.     local victimtable, pass = {}, false
    23.     local self = configs[getCreatureName(cid)]
    24.     if self then
    25.         if getCreatureTarget(cid) ~= 0 then
    26.             local target, tpos, victims, shotsfired = getCreatureTarget(cid), getThingPos(getCreatureTarget(cid)), getSpectators(getThingPos(cid), self.shootrange, self.shootrange), 0
    27.          
    28.                 for i = 1, self.shots do
    29.                     if shotsfired < self.shots then
    30.                         if shotsfired == 0 then -- First shot will always be fired at the primary target, which is a mandatory target in order to use the spell
    31.                             table.insert(victimtable, target)
    32.                         else
    33.                      
    34.                             for i=1,#victims do
    35.                                 pass = false
    36.                              
    37.                                 if not(isInArray(victimtable,victims[i])) then
    38.                                     if isPlayer(victims[i]) then
    39.                                         if getPlayerGroupId(victims[i]) < 3 then
    40.                                             pass = true
    41.                                         end
    42.                                     else
    43.                                         if isPlayer(getCreatureMaster(victims[i])) then
    44.                                             pass = true
    45.                                         end
    46.                                     end
    47.                                 end
    48.                          
    49.                                 if pass == true then
    50.                                         target = victims[i]
    51.                                         table.insert(victimtable, target)
    52.                                         break
    53.                                 end
    54.  
    55.                             end
    56.                         end
    57.                         shotsfired = shotsfired + 1
    58.                     end
    59.                 end
    60.              
    61.                 for v = 1, #victimtable do
    62.                     addEvent(function()
    63.                         if isCreature(victimtable[v]) and isCreature(victimtable[v]) then
    64.                             if getDistanceBetween(getThingPos(cid), getThingPos(victimtable[v])) <= self.shootrange and isSightClear(getThingPos(cid), getThingPos(victimtable[v]), false) then
    65.                                 doSendDistanceShoot(getThingPos(cid), getThingPos(victimtable[v]), self.shooteff)
    66.                                 doTargetCombatHealth(cid, victimtable[v], self.dmgtype, self.mindmg, self.maxdmg, self.splasheff)
    67.                             end
    68.                         end
    69.                     end, (v-1)*self.delay)
    70.                 end
    71.              
    72.         end
    73.     end  
    74. return true
    75. end
    76.  

    Hope you like it. Let me know if there are any bugs with it.
    I'm not the best scripter around, so i'm sure there's some area for improvement, but for now, it is what it is.

    Enjoy.
     
  2. J.Dre

    J.Dre ClapSoft®

    Joined:
    May 18, 2011
    Messages:
    2,570
    Likes Received:
    493
    Best Answers:
    0
    Nice release.
     
    Shadowsong likes this.
  3. Vladimir Glebov

    Vladimir Glebov http://www.zorgania.com

    Joined:
    Mar 25, 2016
    Messages:
    78
    Likes Received:
    9
    Best Answers:
    0
    Its can work on tfs 1.2?
     
  4. yoiker

    yoiker Member

    Joined:
    Jan 21, 2012
    Messages:
    176
    Likes Received:
    7
    Best Answers:
    0
    Please to tfs 1.2
     
  5. Zothion

    Zothion Well-Known Member

    Joined:
    Apr 28, 2014
    Messages:
    1,086
    Likes Received:
    377
    Best Answers:
    0
    just convert it to 1.2, not that much work
     
  6. Activity

    Activity Member

    Joined:
    Apr 7, 2016
    Messages:
    159
    Likes Received:
    22
    Best Answers:
    0
    Thanks :) , good one.
     
    Shadowsong likes this.
  7. Shadowsong

    Shadowsong Game Developer & Graphic Designer

    Joined:
    Feb 23, 2010
    Messages:
    3,133
    Likes Received:
    2,360
    Best Answers:
    0
    I never coded for 1.2 so I don't know the new syntax nor do I want to learn it atm. Whoever wants, can convert it themselves and post here, I'll update the main post.
     
    Activity likes this.
  8. Zothion

    Zothion Well-Known Member

    Joined:
    Apr 28, 2014
    Messages:
    1,086
    Likes Received:
    377
    Best Answers:
    0
    it was towards those who wanted it for 1.2, you did good enough for 0.x :p
     
  9. devzan14

    devzan14 New Member

    Joined:
    Feb 3, 2015
    Messages:
    25
    Likes Received:
    2
    Best Answers:
    0
    How to edit this for TFS 1.2 and for player's spell? :) Could someone do this?
     
  10. Apollos

    Apollos Mapper

    Joined:
    Apr 22, 2009
    Messages:
    71
    Likes Received:
    51
    Best Answers:
    0
    Awesome spell, thanks man!

    This worked on my TFS 1.1, so probably works on 1.2.

    Code (Text):
    1. <instant name="Multishot" words="###50" aggressive="1" blockwalls="1" needtarget ="1" needlearn="1" script="monster/multishot.lua">
    Code (Text):
    1. --- Multishot Monster Spell ---
    2. --- by ShivaShadowsong -----
    3. --- For TFS 0.3.6 ------------
    4. function onCastSpell(cid, var)
    5. local configs = {
    6.     ["Lava Abomination"] = {
    7.         mindmg = -500, -- Minimum damage (don't forget that this number has to be negative)
    8.         maxdmg = -1000, -- Maximum damage (don't forget that this number has to be negative)
    9.         dmgtype = COMBAT_FIREDAMAGE, -- Damage type (for available types, check your Constants library)
    10.         shooteff = 3, -- Number of distance effect that will be shot (can also be a constant)
    11.         splasheff = 187, -- Number of magic effect that will be displayed when the target is shot (can also be a constant)
    12.         delay = 200, -- Delay at which multiple shots will be fired. In miliseconds.
    13.         shots = 2, -- How many shots will the monster fire per attack?
    14.         shootrange = 6 -- Range at which the monster scans for targets and shoots the shots.
    15.     }
    16. }
    17.     ---- Don't touch anything below unless you know what you're doing ----
    18.     local victimtable, pass = {}, false
    19.     local self = configs[getCreatureName(cid)]
    20.     if self then
    21.         if getCreatureTarget(cid) ~= 0 then
    22.             local target, tpos, victims, shotsfired = getCreatureTarget(cid), getThingPos(getCreatureTarget(cid.uid)), getSpectators(getThingPos(cid.uid), self.shootrange, self.shootrange), 0
    23.        
    24.                 for i = 1, self.shots do
    25.                     if shotsfired < self.shots then
    26.                         if shotsfired == 0 then -- First shot will always be fired at the primary target, which is a mandatory target in order to use the spell
    27.                             table.insert(victimtable, target)
    28.                         else
    29.                    
    30.                             for i=1,#victims do
    31.                                 pass = false
    32.                            
    33.                                 if not(isInArray(victimtable,victims[i])) then
    34.                                     if isPlayer(victims[i]) then
    35.                                         if getPlayerGroupId(victims[i]) < 3 then
    36.                                             pass = true
    37.                                         end
    38.                                     else
    39.                                         if isPlayer(getCreatureMaster(victims[i])) then
    40.                                             pass = true
    41.                                         end
    42.                                     end
    43.                                 end
    44.                        
    45.                                 if pass == true then
    46.                                         target = victims[i]
    47.                                         table.insert(victimtable, target)
    48.                                         break
    49.                                 end
    50.                             end
    51.                         end
    52.                         shotsfired = shotsfired + 1
    53.                     end
    54.                 end
    55.            
    56.                 for v = 1, #victimtable do
    57.                     addEvent(function()
    58.                         if isCreature(victimtable[v]) and isCreature(victimtable[v]) then
    59.                             if getDistanceBetween(getThingPos(cid.uid), getThingPos(victimtable[v])) <= self.shootrange and isSightClear(getThingPos(cid.uid), getThingPos(victimtable[v]), false) then
    60.                                 doSendDistanceShoot(getThingPos(cid.uid), getThingPos(victimtable[v]), self.shooteff)
    61.                                 doTargetCombatHealth(cid, victimtable[v], self.dmgtype, self.mindmg, self.maxdmg, self.splasheff)
    62.                             end
    63.                         end
    64.                     end, (v-1)*self.delay)
    65.                 end
    66.            
    67.         end
    68.     end
    69. return true
    70. end
     
    Tinkz likes this.

Share This Page

Loading...