Page 1 of 2

[Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 2:35 am
by Grimwold
Throwing Axe of Returning!
I've scripted a throwing axe that flies back to the party when it hits a monster. It requires changes to multiple lua files (or you could add a single grims_returning_axe.lua and import it from init.lua) AND a script entity containing a number of functions called from hooks. [The original discussion thread is here - viewtopic.php?f=14&t=3683]

items.lua

Code: Select all

cloneObject{
  name ="returning_throwing_axe",
  baseObject="throwing_axe",
  uiName = "Throwing Axe of Returning",
  sharpProjectile = false,
  stackable = false,
}

cloneObject{
  name ="fake_returning_throwing_axe",
  baseObject="throwing_axe",
  uiName = "Fake Throwing Axe",
  sharpProjectile = false,
  stackable = false,
  attackPower = 0,
  throwingWeapon = false,
}
create returning axe item and "fake" item used for the returning graphics. The names are important and must match those in the script to work.

monsters.lua

Code: Select all

local monstersList = {"crab","crowern","cube","goromorg","green_slime","herder","herder_big","herder_small","herder_swarm","ice_lizard","ogre","scavenger","scavenger_swarm","shrakk_torr","skeleton_archer","skeleton_archer_patrol","skeleton_patrol","skeleton_warrior","snail","spider","tentacles","uggardian","warden","wyvern"
}

for i=1,# monstersList do
  cloneObject{
    name = monstersList[i],
    baseObject = monstersList[i],
    onProjectileHit = function(monster, weapon)
      return grims_returning_axe_script.projectileCheck(monster,weapon)
    end,
  }
end
clone every monster and add the onProjectileHit hook to check if monster was hit by returning axe.

init.lua

Code: Select all

cloneObject{
   name = "party",
   baseObject = "party",

   onAttack = function(champion,weapon)
      return grims_returning_axe_script.weaponCheck(champion,weapon)
   end,

   onProjectileHit  = function(champion,weapon)
      return grims_returning_axe_script.partyProjectileCheck(champion,weapon)
   end,

   onPickUpItem  = function(party,item)
      return grims_returning_axe_script.partyPickupCheck(party,item)
   end,

}
clone the party and add the 3 necessary hooks onAttack; onProjectileHit and OnPickupItem. If you already have a party clone, add these hooks.


script entity called grims_returning_axe_script

Code: Select all

-- store the ordinal value of the champion using returning Axe --
thrower_ord = 1 -- set starting thrower Ordinal value purely for the case that you first throw the axe from the mousepointer!


-- find the champion ID from the ordinal number --
function findChampionByOrdinal(ord)
  for ch = 1,4 do
    if party:getChampion(ch):getOrdinal() == ord then
      return party:getChampion(ch)
    end
  end
end


function getDistance(obj1,obj2)
  local distance = 0
  local XNumber = math.max(obj1.x,obj2.x) - math.min(obj1.x,obj2.x)
  local YNumber = math.max(obj1.y,obj2.y) - math.min(obj1.y,obj2.y)
  distance = XNumber + YNumber
  return distance
end


-- check if party attack with returning Axe --
function weaponCheck(champion,weapon)
  if weapon ~= nil then
    if weapon.name == "returning_throwing_axe" then
      thrower_ord = champion:getOrdinal()
    else
    --  hudPrint("Other Weapon")
    end
  else
   -- hudPrint("Unarmed")
  end
end


-- Check if Monster Hit by returning Axe --

function projectileCheck(monster,weapon)
  if weapon.name == "returning_throwing_axe" then
    if findEntity(weapon.id) ~= nil then
      weapon:destroy()
      local distance = getDistance(party,monster)
      local facing = (party.facing + 2)%4
      local dx,dy = getForward(facing)
      shootProjectile("fake_returning_throwing_axe", party.level, monster.x+dx, monster.y+dy, facing, 2*distance, 1, 1, 0, 0, 0, 0, false, false)
    end
  end
end


-- Check if Party hit by fake axe --
function partyProjectileCheck(champion,weapon)
local throw_champ = findChampionByOrdinal(thrower_ord)
  if weapon.name == "fake_returning_throwing_axe" then
    weapon:destroy()
    if throw_champ:getItem(7) == nil then
      throw_champ:insertItem(7,spawn("returning_throwing_axe"))
    elseif throw_champ:getItem(8) == nil then
      throw_champ:insertItem(8,spawn("returning_throwing_axe"))
    else
      spawn("returning_throwing_axe",party.level,party.x,party.y,party.facing)
    end
  end
end

-- Check if party picks up fake axe --
function partyPickupCheck(party,item)
  if item.name == "fake_returning_throwing_axe" then
    -- hudPrint("fake axe")
    item:destroy()
    -- setMouseItem(spawn("returning_throwing_axe"))
    -- spawn("returning_throwing_axe",party.level,party.x,party.y,party.facing)
    local throw_champ = findChampionByOrdinal(thrower_ord)
    if throw_champ:getItem(7) == nil then
      throw_champ:insertItem(7,spawn("returning_throwing_axe"))
    elseif throw_champ:getItem(8) == nil then
      throw_champ:insertItem(8,spawn("returning_throwing_axe"))
    else
      spawn("returning_throwing_axe",party.level,party.x,party.y,party.facing)
    end
    return false
  end
  return true
end
Do a bunch of stuff!!

NOTES
1) Axe only returns if it hits a monster with the hook (so you can prevent some monsters by removing them from the MonsterList)
2) Axe deals 0 ~ 1 damage to a front party member when it returns
3) Axe teleports to the hand of the thrower when it hits the party
4) if the party moves it will not catch the Axe, but can go and pick it up. When you do, it teleports to the hand of the thrower if possible.
5) if the the thrower has no free hands when the axe returns (or is picked up) it will land on the ground, but can be picked up normally.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 2:42 am
by Neikun
*applause*

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 2:53 am
by Batty
Didn't know you could use a loop to clone a bunch of things, nice work, BUT no demo vid? :cry:

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 2:56 am
by Grimwold
Batty wrote:Didn't know you could use a loop to clone a bunch of things, nice work, BUT no demo vid? :cry:
I don't really have anything to record gameplay video, otherwise I would have tried posting one.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 3:26 am
by Lmaoboat
I wanted to make something like this, but couldn't figure out how. Thought recently I saw the shootProjectile function, and thought about just making it part of an onUse function.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 4:03 am
by Grimwold
Here's a very short video I created with the free version of fraps... apparently I can't embed the video though.

http://www.youtube.com/watch?v=9AMdzCSl0rI

Sadly it doesn't look as impressive in the video as it does playing with the thing.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 4:04 am
by Batty
Grimwold wrote:I don't really have anything to record gameplay video, otherwise I would have tried posting one.
The free version of Fraps gives you 30 sec. max of record time, works great, easy to use.

:lol: oops late

edit: very cool, I'll have to try it, lots of good scripting you did there.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 1:18 pm
by Kuningas
I thought that'd be simple, but I gotta admit it's one hell of a job you've done there. Congratulations.

Some of that is ingenious, really. I had long hours trying to formulate a dual-wielding script, and with a method like this, that might also become a possibility.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 1:27 pm
by Soaponarope
Very cool.

Throwing characters needed something special too.

Re: [Script] Throwing Axe of Returning

Posted: Thu Oct 18, 2012 7:09 pm
by Anacone
Nice! Now someone can make Mjölnir.