• 🏆 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!

Mount system v1.2

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
About system

Allows units to sit on other units simulating a ride on horseback.

Instructions for use inside.
Functions

MSAddUnit(unit id,unit dummy id,animation id) - register unit in system
MSAddMount(mount id, sit height) - register mount in system
MountUnit(unit, target) - mount unit
UnMountUnit(unit) - unmount unit
JASS:
/*

    MOUNT SYSTEM v1.2 BY OXYGEND
   Instruction:
    --- Setting ---
    MSAddUnit(unit id,unit dummy id) - register unit in system
    MSAddMount(mount id, sit height) - register mount in system
    --- Control ---
    MountUnit(unit, target) - mount unit
    UnMountUnit(unit) - unmount unit
    This functions return true with success and false with fail.
    
                                                                                                             P.S Write my nickname somewhere in credit if you will use this system:)
*/

library MountSys initializer InitSystem

globals
 private constant integer  Maxunit = 100
 
 private constant real        TIMER_PEREODIC = 0.025 // optimal
 
 private constant boolean DEBUG_FLAG = false
endglobals

 globals
 // General
 private timer                 UpTimer                      = CreateTimer()
 private unit array         MountedUnit     [Maxunit]
 private unit array         UnitMounted     [Maxunit]
 private unit array         InvisUnit            [Maxunit]
 private boolean array  OnMOUNT         [Maxunit]
 private integer              MaxUnit                       = 0
 // For registration
 integer                           NOW_MOUNTED         = 0
 integer                           REGISTRED_UNITS       = 0
 integer                           MOUNT_COUNT          = 0
 integer array                 GENERAL_ID      [Maxunit]
 integer array                 CLONE_ID          [Maxunit]
 integer array                 MOUNT_ID        [Maxunit]
 integer array                 MISSED_SLOT    [Maxunit]
 real array                       MOUNT_HIGHT [Maxunit]
 
endglobals

 function MSAddUnit takes integer uid,integer cid returns nothing
   set REGISTRED_UNITS = REGISTRED_UNITS + 1
   set GENERAL_ID[REGISTRED_UNITS] = uid
   set CLONE_ID[REGISTRED_UNITS] = cid
 endfunction
 
 function MSAddMount takes integer mid,real height returns nothing
   set MOUNT_COUNT = MOUNT_COUNT + 1
   set MOUNT_ID[MOUNT_COUNT] = mid
   set MOUNT_HIGHT[MOUNT_COUNT] = height
 endfunction
   
 private function GetMountId takes integer m returns integer
   local integer i=1
   
    loop
    exitwhen(i>MOUNT_COUNT)
    
      if m == MOUNT_ID[i] then
        return i
      endif
      
     set i = i + 1
    endloop
   return 0
 endfunction
  
 private function GetMountedUnitId takes unit u returns integer
   local integer i = 1
   
    loop
    exitwhen(i>MaxUnit)
    
      if u == InvisUnit[i] then
        return i
      endif
      
      set i = i + 1
    endloop
    
   return 0
 endfunction
 
 private function GetMissSlot takes nothing returns integer
  local integer i = 1
  
   loop
    exitwhen(i>MaxUnit)
    
     if MISSED_SLOT[i]>0 then
      return MISSED_SLOT[i]
     endif
     
    set i = i + 1
   endloop
    return 0
 endfunction
  
 function OnMount takes unit u returns boolean
   return OnMOUNT[GetMountedUnitId(u)]
 endfunction

  function MountUnit takes unit u,unit t returns boolean
   local integer id=GetPlayerId(GetOwningPlayer(u))
   local integer i = 0
   local integer j = 0
   local integer ms
   
  loop
  exitwhen(i>REGISTRED_UNITS) 
    if GetUnitTypeId(u) == GENERAL_ID[i] and GetUnitTypeId(t) == MOUNT_ID[GetMountId(GetUnitTypeId(t))] then
    
    loop
     exitwhen(j > MaxUnit) 
     
       if t == UnitMounted[j] then
        static if DEBUG_FLAG then
         call BJDebugMsg("Mounted: fail(no place to mount)!")
        endif
         return false // fail
       endif
       
     set j = j + 1 
    endloop
    
      set ms = GetMissSlot()
      if ms != 0 then
    
        set NOW_MOUNTED = NOW_MOUNTED + 1
        set InvisUnit[ms] = u
        call ShowUnit(u,false)
        call SetUnitOwner(t,Player(id),false)
        set MountedUnit[ms] = CreateUnit(Player(id),CLONE_ID[i],GetUnitX(t),GetUnitY(t),GetUnitFacing(t))
        set UnitMounted[ms] = t
        call UnitAddAbility(MountedUnit[ms],'Aave')
        call UnitRemoveAbility(MountedUnit[ms],'Aave')
        call UnitAddAbility(MountedUnit[ms],'Aloc')
        call UnitRemoveAbility(MountedUnit[ms],'Aloc')
        set OnMOUNT[ms] = true
        set MISSED_SLOT[ms] = 0
        
      else
      
        set NOW_MOUNTED = NOW_MOUNTED + 1
        set MaxUnit = MaxUnit + 1
        set InvisUnit[MaxUnit] = u
        call ShowUnit(u,false)
        call SetUnitOwner(t,Player(id),false)
        set MountedUnit[MaxUnit] = CreateUnit(Player(id),CLONE_ID[i],GetUnitX(t),GetUnitY(t),GetUnitFacing(t))
        set UnitMounted[MaxUnit] = t
        call UnitAddAbility(MountedUnit[MaxUnit],'Aave')
        call UnitRemoveAbility(MountedUnit[MaxUnit],'Aave')
        call UnitAddAbility(MountedUnit[MaxUnit],'Aloc')
        call UnitRemoveAbility(MountedUnit[MaxUnit],'Aloc')
        set OnMOUNT[MaxUnit] = true
        set MISSED_SLOT[MaxUnit] = 0
      
      endif
      
       static if DEBUG_FLAG then
        call BJDebugMsg("Mounted: success!")
       endif
      return true // success
     endif
     
    set i = i + 1
   endloop
   
    static if DEBUG_FLAG then
     call BJDebugMsg("Mounted: fail(unregistred unit)!")
    endif
   return false // fail
  endfunction
 
 function UnMountUnit takes unit u returns boolean
   local integer i=0
   
   loop
    exitwhen(i>MaxUnit) 
     if (u == MountedUnit[i]) or (u == InvisUnit[i]) or (u == UnitMounted[i]) then
     
      set OnMOUNT[i] = false
      set NOW_MOUNTED = NOW_MOUNTED - 1
      call SetUnitFlyHeight(MountedUnit[i],0.0,300.0)
      call SetUnitX(InvisUnit[i],GetUnitX(MountedUnit[i]))
      call SetUnitY(InvisUnit[i],GetUnitY(MountedUnit[i]))
      call SetUnitFacing(InvisUnit[i],GetUnitFacing(MountedUnit[i]))
      call SetUnitOwner(UnitMounted[i],Player(15),false)
      call RemoveUnit(MountedUnit[i])
      call ShowUnit(InvisUnit[i],true)
      set MountedUnit[i] = null
      set UnitMounted[i] = null
      set InvisUnit[i]        = null
      set MISSED_SLOT[i] = i
       static if DEBUG_FLAG then
        call BJDebugMsg("Unmounted: success!")
       endif
      return true // success
      
     endif
     set i = i + 1
    endloop
    
    static if DEBUG_FLAG then
     call BJDebugMsg("Unmounted: fail!")
    endif
   return false // fail
  endfunction
 
 private function UnitPlusMaunt takes nothing returns nothing
    local integer i=1
    
  if NOW_MOUNTED > 0 then
    loop
     exitwhen(i>MaxUnit)
       if OnMOUNT[i] then
       
        call SetUnitFacing(MountedUnit[i],GetUnitFacing(UnitMounted[i]))
        call SetUnitX(MountedUnit[i],GetUnitX(UnitMounted[i]))
        call SetUnitY(MountedUnit[i],GetUnitY(UnitMounted[i]))
        call SetUnitFlyHeight(MountedUnit[i],MOUNT_HIGHT[GetMountId(GetUnitTypeId(UnitMounted[i]))],0.0)
        
       endif
      set i = i + 1
    endloop
   endif
    
  endfunction
 
 private function InitSystem takes nothing returns nothing
   call TimerStart(UpTimer,TIMER_PEREODIC,true,function UnitPlusMaunt)
 endfunction
 
endlibrary

Keywords:
mount,system,OxygenD,mount system,horse,ride,horseback,simulating,sit,unit,units,jass,vjass.
Contents

Mount system v1.2 (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected.

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.
 
Level 17
Joined
Jul 17, 2011
Messages
1,864
Yea absolutely, this is a good mount system which can be used to increase the speed of a hero and make it look like he is riding something. You dont need the hero to play any animations because in most rpgs a mounted hero can only ride.

Hmm.... I can use this :D
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Yeah, to add to what Maker said:

These o(N) searches are unnecessary. You can always do lookups in hashtables.

The timer should only be started when there are mounted units around, it doesn't make sense to keep it running perpetually.

If you improve your indexing, let's say with a better-implementation of the stack, then you can avoid the need for the "OnMOUNT" boolean.

Well, as a whole, the system is good, but as a whole the code is bad. I feel like these changes should be made first, just for the sake of setting a good example of what makes an approve-worthy resource.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
- pls fix your indenting...
- why many globals are not privete?...
- you really dont need the 'Maxunit' integer, just reduce the MOUNT_COUNT,
REGISTRED_UNITS and NOW_MOUNTED if you unmount/unregister the unit...
- adding 'Aloc' ability to a non-dummy unit is not recommended coz you can only
select your unit/hero by draging not by clicking...
 
Level 5
Joined
May 13, 2012
Messages
66
Finally my damn Ghost Rider can actually jump onto his bike! Btw, this is very useful as mount Archer basically remove then replace the unit. Warcraft considers Heroes which mount are considered to have died (very funny if you do this in a Melee map!)
 
Top