• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Meat Hook Multi Instanced

Status
Not open for further replies.
Level 1
Joined
Jun 25, 2006
Messages
3
Hello everybody.

I need a Jass code for "Meat Hook" from DotA. My problem is that i can´t use the GUI Hook from this site, because I want to use this spell for a multiplayer map where all heros have the hook ability.

I would appreciate it if you could post a map with the hole spell.

Thanks in advance and happy World Cup watchin´ :D

Greetz Mordred :wink:
 
Level 5
Joined
May 22, 2006
Messages
150
Hey, that was a really funny task. ^^

Here is your code:
It is a single trigger, which you should name "MH Cast".

JASS:
function Trig_MH_Retract_Actions takes integer mH_Links,unit mH_Unit1,unit mH_Unit2 returns boolean
  local boolean stop = false
  local location mH_LinkPos = GetUnitLoc(udg_MH_Link[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))+4+mH_Links])
  call SetUnitPositionLoc(mH_Unit2,mH_LinkPos)
  call RemoveUnit(udg_MH_Link[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))+4+mH_Links])
  set mH_Links = mH_Links - 1
  if mH_Links == 0 then
    set mH_Unit1 = null
    set mH_Unit2 = null
    set stop = true
  endif
  call FlushStoredInteger(udg_Cache,"mH_Values",I2S(GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))) + "Links")
  call StoreInteger(udg_Cache,"mH_Values",I2S(GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))) + "Links",mH_Links)
  call RemoveLocation(mH_LinkPos)
  set mH_LinkPos = null
  return stop
endfunction

function Trig_MH_Extend_Condition takes nothing returns boolean
  return GetUnitState(GetFilterUnit(),ConvertUnitState(0)) > 0
endfunction

function Trig_MH_Extend_Actions takes integer mH_Level,unit mH_Unit1,location mH_Unit1Pos,real mH_Angle returns boolean
  local boolean stop = false
  local integer mH_Links = GetStoredInteger(udg_Cache,"mH_Values",I2S(GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))) + "Links")
  local location mH_LinkPos
  local group tempGroup
  local unit mH_Unit2
  local timer mH_ExtendTimer = CreateTimer()
  if mH_Links < 5 + 6 * mH_Level then
    set mH_Links = mH_Links + 1
    set udg_MH_Link[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))+4+mH_Links] = CreateUnitAtLocSaveLast(GetOwningPlayer(mH_Unit1),'u005',PolarProjectionBJ(mH_Unit1Pos,I2R(40 * mH_Links),mH_Angle),mH_Angle)
    set mH_LinkPos = GetUnitLoc(udg_MH_Link[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))+4+mH_Links])
    set tempGroup = GetUnitsInRangeOfLocMatching(115.00,mH_LinkPos,Condition(function Trig_MH_Extend_Condition))
    if mH_Links > 3 then
      set mH_Unit2 = GroupPickRandomUnit(tempGroup)
      if not IsUnitAlly(mH_Unit2,GetOwningPlayer(mH_Unit1)) then
        call UnitDamageTargetBJ(mH_Unit1,mH_Unit2,100.00 * I2R(mH_Level),ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL)
      endif
    endif
    if mH_Unit2 != null then
      loop
        call TimerStart(mH_ExtendTimer,0.1,false,null)
        if TimerGetElapsed(mH_ExtendTimer) >= 0.04 then
          call PauseTimer(mH_ExtendTimer)
          call ResumeTimer(mH_ExtendTimer)
          exitwhen Trig_MH_Retract_Actions(mH_Links,mH_Unit1,mH_Unit2)
        endif
      endloop
      set stop = true
    endif
    call FlushStoredInteger(udg_Cache,"mH_Values",I2S(GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))) + "Links")
    call StoreInteger(udg_Cache,"mH_Values",I2S(GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))) + "Links",mH_Links)
    call RemoveLocation(mH_LinkPos)
    call DestroyGroup(tempGroup)
    set mH_LinkPos = null
    set udg_Temp_Group = null
  else
    loop
      call TimerStart(mH_ExtendTimer,0.1,false,null)
      if TimerGetElapsed(mH_ExtendTimer) >= 0.04 then
        call PauseTimer(mH_ExtendTimer)
        call ResumeTimer(mH_ExtendTimer)
        exitwhen Trig_MH_Retract_Actions(mH_Links,mH_Unit1,mH_Unit2)
      endif
    endloop
    set stop = true
  endif
  call DestroyTimer(mH_ExtendTimer)
  set mH_ExtendTimer = null
  return stop
endfunction

function Trig_MH_Cast_Actions takes nothing returns nothing
  local integer mH_Level = 0
  local unit mH_Unit1
  local location mH_Unit1Pos
  local location mH_SpellPos
  local real mH_Angle = 0
  local timer mH_CastTimer
  if GetSpellAbilityId() == 'A00F' then
    set mH_Level = GetUnitAbilityLevelSwapped('A00F',GetTriggerUnit())
    set mH_Unit1 = GetTriggerUnit()
    set mH_Unit1Pos = GetUnitLoc(mH_Unit1)
    set mH_SpellPos = GetSpellTargetLoc()
    set mH_Angle = 180/3.14159 * Atan2(GetLocationY(mH_SpellPos) - GetLocationY(mH_Unit1Pos), GetLocationX(mH_SpellPos) - GetLocationX(mH_Unit1Pos))
    set mH_CastTimer = CreateTimer()
    loop
      call TimerStart(mH_CastTimer,0.1,false,null)
      if TimerGetElapsed(mH_CastTimer) >= 0.04 then
        call PauseTimer(mH_CastTimer)
        call ResumeTimer(mH_CastTimer)
        exitwhen Trig_MH_Extend_Actions(mH_Level,mH_Unit1,mH_Unit1Pos,mH_Angle)
      endif
    endloop
    call RemoveLocation(mH_Unit1Pos)
    call RemoveLocation(mH_SpellPos)
    call DestroyTimer(mH_CastTimer)
    set mH_Unit1 = null
    set mH_Unit1Pos = null
    set mH_SpellPos = null
    set mH_CastTimer = null
  endif
endfunction

function InitTrig_MH_Cast takes nothing returns nothing
  set gg_trg_MH_Cast = CreateTrigger()
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(0),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(1),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(2),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(3),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(4),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(5),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(6),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(7),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(8),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(9),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(10),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(11),EVENT_PLAYER_UNIT_SPELL_CAST,null)
  call TriggerAddAction(gg_trg_MH_Cast,function Trig_MH_Cast_Actions)
endfunction

Now, that is what you need to make it work:

- the ability to throw the hook.

You have to replace "A00F" in function "Trig_MH_Cast_Actions" with it's id.
It must not have more than four levels!
Else my left global is beeing messed up. ^^

- a unit, which can learn the ability

- a dummy unit

You have to replace "u005" in function "Trig_MH_Extend_Actions" with it's id.
This one has to be identical to u005 ("Chain Link") in the map you refered to.

- a global variable

It's type has to be "unit array" and it's name "MH_Link".

...

So, now it "should" work... If not, do not hesitate to tell me and I will look over it again.
 
Level 1
Joined
Jun 25, 2006
Messages
3
Ok thank you very much. But if I paste it into the editor and change the ID´s I get an error.. Do I have to maintain the structure of the code or can I also just paste it and its there in three long lines? Because one error was "End of line expected" (I dont know how it is exactly because I have the german editor)

Greetz Mordred
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
ugh...

call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(0),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(1),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(2),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(3),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(4),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(5),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(6),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(7),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(8),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(9),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(10),ConvertPlayerUnitEvent(273),null)
call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(11),ConvertPlayerUnitEvent(273),null)

should be

JASS:
local integer index = 0
loop
    call TriggerRegisterPlayerUnitEvent(gg_trg_MH_Cast,Player(index),ConvertPlayerUnitEvent(273),null)
    set index = index + 1
endloop

also, why are u using ConvertPlayerUnitEvent? use the PlayerUnitEvent globals, as they run faster, since they have already executed the function.
 
Level 5
Joined
May 22, 2006
Messages
150
@PurplePoot

As long as I know exactly, how often my task has to be executed, writing it as often is better (because faster) then using a loop.
Remember: "loop" is a reserved word, that causes nothing else then executing a list of operations similar to a function.
So with an "exitwhen", you got two additional "calls" per event check.
Also, you got four more bites for your local variable and another operation to do for increasing the value.

~~ But you are right about the player events. As they are constants, the functions to determine their values are executed on start of the map and not furthermore.
I change that.

... But there is something else, I worry about.
Take a look at the if-structures, I used to avoid "TriggerSleepAction" and you will know, what I mean, I suppose.

@Mordred:

German version? So may it be, that you are yourself a "german version"? May it mean, that you understand was ich hier schreibe?
That whould make things easier, I think.

Okay, first of all:
Sorry, I forgot something to tell you.
To make it work, you also need a game cache with reference from a global variable called "Cache".

Now to your compilation errors...
Yes, it is right. In difference to Java (for example), JASS needs the lines as indicators for where a task ends.
So you have to use exactly the same paragraphs as I used.
If more errors occur, it lightens my life if you write exactly, what the editor told you.
Do not worry about versions - the compiler is the same for English as for German as probably for any other game language.
 
Status
Not open for further replies.
Top