- Joined
- Oct 12, 2011
- Messages
- 3,449
This is quite similar to this system, they have similar purpose. And it's indeed not very advanced compared to that system (or perhaps not yet), but this one is a lot easier to use. Also it supports any shape of platform, just depends on the model you use.
This is all I can achieve for tonight, still gotta add bunch of complementary systems to make everything looks alright, like custom actor, advanced multi-level pathing, etc.
Handsome code:
Issues:
- Doesn't work well with flying unit (yet)
- Still looking
To do:
- Allow to modify platform object's size
- Allow to rotate platform
- Remove unneeded scripts
- Enable/disable platform feature
- Add additional functioons (get unit platform level, check is unit on platform, etc)
- Add platform events (enters, falls from, etc.)
- Add per rect platform generation feature
- Complete complementary systems
Complementary systems:
- A 3D pathing system
- A custom actor system (to simulate falling physics, etc.)
- A custom arrow key movement and camera system (which is adapted to this platform system)
Note:
I use the witcher's camera and movement system for the demonstration. You can use arrow key to move around. Also try double-tapping the arrow key as well
Feedback pls
EDIT:
Lil update, added wandering units.
This is all I can achieve for tonight, still gotta add bunch of complementary systems to make everything looks alright, like custom actor, advanced multi-level pathing, etc.
Handsome code:
JASS:
library PlatformSystem uses Table, UnitZ, TimerUtils
// dest:
// - must have free rotation
// - must have no variation
// - must have no pathing map
// - must have no other dest around
// ground:
// - completely flat
globals
private constant real PRECISION = 16.0
private constant real STEP_OFFSET = 75.0
private constant real INTERVAL = 0.01
private constant real OPEN_X = 0.0
private constant real OPEN_Y = 0.0
endglobals
globals
private constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
struct PlatformObj
readonly integer objId
readonly integer destId
readonly integer tWidth
readonly integer tHeight
readonly real width
readonly real height
readonly real sz
readonly real rot
readonly Table zMap
private static unit dummy
private static real locZ
private method remap takes nothing returns nothing
local destructable d = CreateDestructableZ(.destId, OPEN_X, OPEN_Y, 0, .rot, .sz, 0)
local integer xOffset
local integer yOffset
local real x
local real y = 0
local real z //*
local real sx = OPEN_X-.width/2
local real sy = OPEN_Y-.height/2
local real tx = sx+.width
local real ty = sy+.height
debug local string ms
debug call BJDebugMsg(" ")
loop
exitwhen y > height
set x = 0
set yOffset = R2I(y/PRECISION)
debug set ms = ""
loop
exitwhen x > width
set xOffset = R2I(x/PRECISION)
set z = GetTerrainZ(sx+x, sy+y)-locZ
set .zMap.real[tWidth*yOffset+xOffset] = z
debug set ms = ms + R2SW(z, 5, 1) + " "
set x = x + PRECISION
endloop
debug call BJDebugMsg(ms)
set y = y + PRECISION
endloop
call RemoveDestructable(d)
set d = null
endmethod
static method create takes integer objId, integer destId, real angle, real size, real width, real height returns thistype
local thistype this = allocate()
set .objId = objId
set .destId = destId
set .sz = size
set .rot = angle
set .zMap = Table.create()
set .width = width
set .height = height
set .tWidth = R2I(width/PRECISION)
set .tHeight = R2I(height/PRECISION)
call this.remap()
return this
endmethod
private static method onInit takes nothing returns nothing
set locZ = GetTerrainZ(OPEN_X, OPEN_Y)
endmethod
endstruct
struct Platform
private unit obj
private real mx
private real my
private real x
private real y
private real z
private real z2
private rect area
private integer dex
private PlatformObj plat
private static timer tick = CreateTimer()
private static integer count = -1
private static Table rectDex
private static Table unitState
private static rect array rects
private static group tempGroup = CreateGroup()
private static group tempGroup2 = CreateGroup()
private static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this
local integer xOffset
local integer yOffset
local integer hand
local integer i
local unit fog
local real x
local real y
local real z
local real tz
set i = 0
loop
exitwhen i > count
set this = rectDex.integer[GetHandleId(rects[i])]
call GroupEnumUnitsInRect(tempGroup, .area, null)
loop
set fog = FirstOfGroup(tempGroup)
exitwhen fog == null
call GroupRemoveUnit(tempGroup, fog)
set hand = GetHandleId(fog)
if not unitState.boolean[hand] then
call GroupAddUnit(tempGroup2, fog)
set x = GetUnitX(fog)-.mx
set y = GetUnitY(fog)-.my
set z = GetUnitZ(fog)
set xOffset = R2I(x/PRECISION)
set yOffset = R2I(y/PRECISION)
set tz = .plat.zMap.real[.plat.tWidth*yOffset+xOffset]
if tz > 0 then
set unitState.boolean[hand] = true
if z > .z+tz-STEP_OFFSET then
call SetUnitZ(fog, .z+tz+GetUnitDefaultFlyHeight(fog))//+(z-(.z+tz)))
endif
endif
endif
endloop
set i = i + 1
endloop
loop
set fog = FirstOfGroup(tempGroup2)
exitwhen fog == null
call GroupRemoveUnit(tempGroup2, fog)
set hand = GetHandleId(fog)
if not unitState.boolean[hand] then
call SetUnitFlyHeight(fog, GetUnitDefaultFlyHeight(fog), 0)
else
set unitState.boolean[hand] = false
endif
endloop
set t = null
endmethod
static method create takes PlatformObj obj, real x, real y, real z returns thistype
local thistype this = allocate()
local thistype dex
local integer i
local integer j
set .plat = obj
set .x = x
set .y = y
set .z = z
set .z2 = GetTerrainZ(.x, .y)
set .mx = .x-.plat.width/2
set .my = .y-.plat.height/2
set .area = Rect(x-obj.width/2, y-obj.height/2, x+obj.width/2, y+obj.height/2)
set .obj = CreateUnit(PASSIVE, obj.objId, x, y, .plat.rot)
static if not LIBRARY_AutoFly then
if UnitAddAbility(.obj, 'Amrf') and UnitRemoveAbility(.obj, 'Amrf') then
endif
endif
call SetUnitZ(.obj, z)
call SetUnitScale(.obj, .plat.sz, 1, 1)
if UnitAddAbility(.obj, 'Aloc') and UnitRemoveAbility(.obj, 'Aloc') then
endif
call ShowUnit(.obj, false)
call ShowUnit(.obj, true)
set i = 0
loop
exitwhen i > count
set dex = rectDex.integer[GetHandleId(rects[i])]
if .z > dex.z then
exitwhen true
endif
set i = i + 1
endloop
set count = count + 1
set j = count
loop
exitwhen j == i
set rects[j] = rects[j-1]
set j = j - 1
endloop
set .dex = i
set rects[i] = .area
set rectDex.integer[GetHandleId(.area)] = this
if count == 0 then
call TimerStart(tick, INTERVAL, true, function thistype.onPeriodic)
endif
return this
endmethod
private static method onInit takes nothing returns nothing
set rectDex = Table.create()
set unitState = Table.create()
endmethod
endstruct
endlibrary
- Doesn't work well with flying unit (yet)
- Still looking
To do:
- Allow to modify platform object's size
- Allow to rotate platform
- Remove unneeded scripts
- Enable/disable platform feature
- Add additional functioons (get unit platform level, check is unit on platform, etc)
- Add platform events (enters, falls from, etc.)
- Add per rect platform generation feature
- Complete complementary systems
Complementary systems:
- A 3D pathing system
- A custom actor system (to simulate falling physics, etc.)
- A custom arrow key movement and camera system (which is adapted to this platform system)
Note:
I use the witcher's camera and movement system for the demonstration. You can use arrow key to move around. Also try double-tapping the arrow key as well
Feedback pls
EDIT:
Lil update, added wandering units.
Attachments
Last edited: