Name | Type | is_array | initial_value |
library distancetool initializer init // uses libassert
globals
private constant integer Path_Add_New_Point_Id = 'A000'
private constant integer Path_Clear_Id = 'A002'
private constant integer Path_Cycle_Color_Id = 'A003'
private constant integer New_Pathomancer_Id = 'A004'
private constant integer Path_Point_Remove_Id = 'A005'
private constant integer Pathomancer_Id = 'n000'
private constant integer Path_Point_Id = 'e000'
private constant boolean Reveal_Map = false
private constant player Dev = Player(0)
endglobals
globals
private leaderboard path_display
endglobals
private function path_display_init takes nothing returns nothing
set path_display = CreateLeaderboard()
call LeaderboardSetStyle(path_display, /*show_title:*/ true, /*show_item_labels:*/ true, /*show_item_values:*/ true, /*show_item_icons:*/ false)
call PlayerSetLeaderboard(Dev, path_display)
endfunction
private function path_display_begin_draw takes nothing returns nothing
local integer n = LeaderboardGetItemCount(path_display)
loop
exitwhen n == 0
call LeaderboardRemoveItem(path_display, 0)
set n = n - 1
endloop
endfunction
private function path_display_add_path takes string label, integer path_dist, integer item_index returns nothing
call LeaderboardAddItem(path_display, label, path_dist, Dev)
endfunction
private function path_display_end_draw takes nothing returns nothing
local integer num_items = LeaderboardGetItemCount(path_display)
if num_items == 0 then
call LeaderboardDisplay(path_display, false)
else
call LeaderboardSetLabelColor(path_display, /*R:*/ 0xFF, /*G:*/ 0xFF, /*B:*/ 0xFF, /*A:*/ 0xFF)
call LeaderboardSetValueColor(path_display, /*R:*/ 0xFF, /*G:*/ 0xFF, /*B:*/ 0xFF, /*A:*/ 0xFF)
call LeaderboardSetSizeByItemCount(path_display, LeaderboardGetItemCount(path_display))
//call LeaderboardSortItemsByValue(path_display, /*ascending:*/ false)
call LeaderboardSetLabel(path_display, "Path Distances")
call LeaderboardDisplay(path_display, true)
endif
endfunction
globals
private string array path_point_link_model
private integer num_path_point_links
private integer next_path_point_link_id = 0
private real path_point_link_initial_x
private real path_point_link_initial_y
endglobals
private function path_point_link_init takes nothing returns nothing
local rect w
set path_point_link_model[1] = "DRAM"
set path_point_link_model[2] = "DRAL"
set path_point_link_model[3] = "AFOD"
set path_point_link_model[4] = "CHIM"
set path_point_link_model[5] = "SPLK"
set path_point_link_model[6] = "LEAS"
set path_point_link_model[7] = "FORK"
set path_point_link_model[8] = "MBUR"
set path_point_link_model[9] = "MFPB"
set path_point_link_model[10] = "HWPB"
set num_path_point_links = 10
set w = GetWorldBounds()
set path_point_link_initial_x = GetRectMinX(w)
set path_point_link_initial_y = GetRectMaxY(w)
call RemoveRect(w)
set w = null
endfunction
private function get_next_path_point_link_id takes nothing returns integer
set next_path_point_link_id = next_path_point_link_id + 1
if next_path_point_link_id > num_path_point_links then
set next_path_point_link_id = 1
endif
return next_path_point_link_id
endfunction
private struct Path_Point
thistype prev
thistype next
unit u
lightning li
endstruct
private function path_point_remove takes Path_Point pp returns nothing
if pp.li == null then
// pp is the first point in the path
call DestroyLightning(pp.next.li)
set pp.next.li = null
else
call DestroyLightning(pp.li)
set pp.li = null
endif
set pp.prev.next = pp.next
set pp.next.prev = pp.prev
set pp.prev = 0
set pp.next = 0
call RemoveUnit(pp.u)
set pp.u = null
call pp.destroy()
endfunction
private struct Pathomancer
unit u
Path_Point path // sentinel node of a doubly-linked lits of Path_Point(s)
integer path_point_link_model_id
endstruct
globals
Pathomancer array pathomancers
integer num_pathomancers = 0
endglobals
private function pathomancer_new takes real x, real y, real facing_rad returns Pathomancer
local Pathomancer p
local Path_Point pp
set p = Pathomancer.create()
set p.u = CreateUnit(Dev, Pathomancer_Id, x, y, bj_RADTODEG*facing_rad)
call SetUnitUserData(p.u, p)
set pp = Path_Point.create()
set pp.prev = pp
set pp.next = pp
set p.path = pp
set p.path_point_link_model_id = get_next_path_point_link_id()
set pathomancers[num_pathomancers] = p
set num_pathomancers = num_pathomancers + 1
call SetUnitState(p.u, UNIT_STATE_MANA, num_pathomancers)
return p
endfunction
private function pathomancer_add_new_point takes Pathomancer p returns nothing
local Path_Point pp = Path_Point.create()
set pp.u = CreateUnit(Dev, Path_Point_Id, GetUnitX(p.u), GetUnitY(p.u), 270.0)
call SetUnitUserData(pp.u, pp)
if p.path.prev == p.path then
set pp.li = null // don't add a lightning for the first point in the path
else
set pp.li = AddLightning(path_point_link_model[p.path_point_link_model_id], false, path_point_link_initial_x, path_point_link_initial_y, path_point_link_initial_x, path_point_link_initial_y)
endif
set pp.prev = p.path.prev
set pp.next = p.path
set pp.prev.next = pp
set pp.next.prev = pp
endfunction
private function pathomancer_clear_path takes Pathomancer p returns nothing
local Path_Point pp
local Path_Point pp_next
set pp = p.path.next
loop
exitwhen pp == p.path
set pp_next = pp.next
call path_point_remove(pp)
set pp = pp_next
endloop
endfunction
private function pathomancer_cycle_path_color takes Pathomancer p returns nothing
local Path_Point pp
set p.path_point_link_model_id = p.path_point_link_model_id + 1
if p.path_point_link_model_id > num_path_point_links then
set p.path_point_link_model_id = 1
endif
set pp = p.path.next.next
loop
exitwhen pp == p.path
call DestroyLightning(pp.li)
set pp.li = AddLightning(path_point_link_model[p.path_point_link_model_id], false, path_point_link_initial_x, path_point_link_initial_y, path_point_link_initial_x, path_point_link_initial_y)
set pp = pp.next
endloop
endfunction
private function pathomancer_spawn_new_pathomancer takes Pathomancer p returns nothing
local real x = GetUnitX(p.u)
local real y = GetUnitY(p.u)
local real facing_rad = bj_DEGTORAD*GetUnitFacing(p.u)
local real dist = 384.0
set x = x + dist*Cos(facing_rad)
set y = y + dist*Sin(facing_rad)
if facing_rad < 0.0 then
set facing_rad = facing_rad + 2.0*bj_PI
endif
call pathomancer_new(x, y, facing_rad + bj_PI)
endfunction
private function pathomancer_update_path_point_links takes Pathomancer p returns real
local Path_Point pp
local Path_Point prev_pp
local real x0
local real y0
local real x1
local real y1
local real dx
local real dy
local real total_path_dist = 0.0
local real segment_dist
set prev_pp = p.path.next
set pp = p.path.next.next
loop
exitwhen pp == p.path
set x0 = GetUnitX(prev_pp.u)
set y0 = GetUnitY(prev_pp.u)
set x1 = GetUnitX(pp.u)
set y1 = GetUnitY(pp.u)
call MoveLightning(pp.li, false, x0, y0, x1, y1)
set dx = x1 - x0
set dy = y1 - y0
set segment_dist = SquareRoot(dx*dx + dy*dy)
set total_path_dist = total_path_dist + segment_dist
set prev_pp = pp
set pp = pp.next
endloop
return total_path_dist
endfunction
private function update_path_point_links takes nothing returns nothing
local real path_dist
local integer i
call path_display_begin_draw()
set i = 0
loop
exitwhen i >= num_pathomancers
set path_dist = pathomancer_update_path_point_links(pathomancers[i])
if path_dist != 0.0 then
call path_display_add_path("Path " + I2S(i + 1), R2I(path_dist), i)
endif
set i = i + 1
endloop
call path_display_end_draw()
endfunction
private function on_button_press takes nothing returns nothing
local integer btn = GetSpellAbilityId()
local Pathomancer p
local Path_Point pp
if btn == Path_Add_New_Point_Id then
set p = Pathomancer(GetUnitUserData(GetTriggerUnit()))
call pathomancer_add_new_point(p)
elseif btn == Path_Clear_Id then
set p = Pathomancer(GetUnitUserData(GetTriggerUnit()))
call pathomancer_clear_path(p)
elseif btn == Path_Cycle_Color_Id then
set p = Pathomancer(GetUnitUserData(GetTriggerUnit()))
call pathomancer_cycle_path_color(p)
elseif btn == Path_Point_Remove_Id then
set pp = Path_Point(GetUnitUserData(GetTriggerUnit()))
call path_point_remove(pp)
elseif btn == New_Pathomancer_Id then
set p = Pathomancer(GetUnitUserData(GetTriggerUnit()))
call pathomancer_spawn_new_pathomancer(p)
endif
endfunction
private function buttons_init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function on_button_press)
endfunction
private function init takes nothing returns nothing
call path_display_init()
call path_point_link_init()
call buttons_init()
call pathomancer_new(0.0, 0.0, 270.0*bj_DEGTORAD)
call TimerStart(CreateTimer(), 0.1, true, function update_path_point_links)
if Reveal_Map then
call FogEnable(false)
call FogMaskEnable(false)
endif
endfunction
endlibrary
//! import "main.j"