Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
<< CANNON COMMANDER >>
By Sourc[e]x
[+] About
"Cannon Commander" is a turn-based WarCraft III scenario developed by Sourc[e]x (Illidan(evil)x) for
The Hive Workshop`s Speed Mapping Contest #1 (www.hiveworkshop.com).
Cannon Commander has been designed with two players in mind, but is also playable by only one player.
As it`s a turn-based game, it is playable for two players on a single computer (Versus Mode) as well.
[+] Modes
* Multiplayer : Activated immediately if multiple players are found.
* Versus Mode : Here two players can compete using a single computer.
* Practice Mode : Designed for a single player. Used for target practicing. Unlimited time and ammunition.
[+] Hotkeys
* General:
- W == Next Cameraset. (3D Mode)
- X == Previus Cameraset. (3D Mode)
- Q == Increase Power.
- Z == Decrease Power.
- E == Switch Weapontype.
- D == Fine Tuning On/Off.
- F == Fire Cannon.
- UP == Increase cannon elevation angle.
- DOWN == Decrease cannon elevation angle.
- LEFT == Rotate cannon left. (3D Mode)
- RIGHT == Rotate cannon right. (3D Mode)
* Multiplayer:
- ESC == Open request dialog.
* Singleplayer:
- ESC == Return to start menu.
* Practice Mode:
- R == Randomize wind conditions.
- V == Randomize terrain.
//TESH.scrollpos=0
//TESH.alwaysfold=0
-==CREDITS==-
Punisher_x - Metal tile
Chris. - Everwood tree
Born2Modificate - Cloud model/texture
Anitarf - Vector System
Vexorian - Bound Sentinel
Ubisoft (Rayman) - Map music
Ray Larabie - Baveuse font
Sourc[e]x - All other resources
- Programming
- Terraining
PitzerMike, SFilip, PipeDream and Vexorian - JassNewGenPack
============================================================
-==Full Resource Credits List==-
2D.blp - Sourc[e]x
3D.blp - Sourc[e]x
Arrow.mdx - Sourc[e]x
Ashen_DirtGrass.blp - Punisher_x
Baveuse.ttf - Ray Larabie
Button2D.mdx - Sourc[e]x
Button3D.mdx - Sourc[e]x
ButtonBackground.mdx - Sourc[e]x
ButtonPractice.mdx - Sourc[e]x
ButtonTrackable.mdx - Sourc[e]x
ButtonVersus.mdx - Sourc[e]x
CannonBase.mdx - Sourc[e]x
CannonFireEmitter.mdx - Sourc[e]x
CannonTurret.mdx - Sourc[e]x
CannonTurretHut.mdx - Sourc[e]x
EffectExDummy.mdx - Sourc[e]x
EmptyBar.tga - Sourc[e]x
EverwoodTree.mdx - Chris.
Flag.mdx - Sourc[e]x
FlagEnd.tga - Sourc[e]x
FlagPole.mdx - Sourc[e]x
GroundFireEmitter.mdx - Sourc[e]x
Health.tga - Sourc[e]x
HealthBarFull.tga - Sourc[e]x
HumanCursor.blp - Sourc[e]x
HumanUI-TimeIndicator.blp - Sourc[e]x
HumanUITile-InventoryCover.blp - Sourc[e]x
HumanUITile01.blp - Sourc[e]x
HumanUITile02.blp - Sourc[e]x
HumanUITile03.blp - Sourc[e]x
HumanUITile04.blp - Sourc[e]x
LandOfMusic4.mp3 - Ubisoft
Leaf.mdx - Sourc[e]x
Outland_Abyss.blp - Sourc[e]x
Player1.blp - Sourc[e]x
Player1Flag.tga - Sourc[e]x
Player2.blp - Sourc[e]x
Player2Flag.tga - Sourc[e]x
Pointer.blp - Sourc[e]x
Pointer.mdx - Sourc[e]x
Power.tga - Sourc[e]x
PowerBarFull.tga - Sourc[e]x
Practice.blp - Sourc[e]x
PracticeFilter.blp - Sourc[e]x
PracticeTarget.mdx - Sourc[e]x
Smoke.mdx - Sourc[e]x
Versus.blp - Sourc[e]x
WindBarFull.tga - Sourc[e]x
cloud.mdx - Born2Modificate
hhuman-options-menu-border.blp - Sourc[e]x
war3mapMap.blp - Sourc[e]x
war3mapPreview.tga - Sourc[e]x
wolke1.blp - Born2Modificate
VectorLib.j - Anitarf
BoundSentinel.j - Vexorian
//TESH.scrollpos=0
//TESH.alwaysfold=0
Changelog
1.00
- Initial release (contest version)
1.01
- Fixed a minor script glitch.
- Skies now moves in the direction of the wind.
- The 'food resource' now serves as a second projectile display.
- Preloading of units has been added.
- Two more weapon types has been added.
- 2D terrain is now "2D".
- Camera abilities is now visually disabled in 2D mode.
- Terrain can now be deformed by projectile impacts.
- Trees can now be destroyed.
- Wind strength has been adjusted.
- More comments added.
1.01b
- Fixed a minor bug where you could destroy the flag poles.
1.01c
- 1.24b+ patch fixing
//TESH.scrollpos=0
//TESH.alwaysfold=0
library SourceAPI initializer init
//! *************************************************************************************
//! The Source Framework (2.2) has been stripped down and optimized for Cannon Commander.
//!
//! *************************************************************************************
globals
//! Timed Life Buff Ids
constant integer TIMER_GENERIC = 'BTLF'
//! Generic true boolexpr
boolexpr TrueExpr
//! Map Bounds
rect WORLD_BOUNDS
real MAP_MAX_X
real MAP_MIN_X
real MAP_MAX_Y
real MAP_MIN_Y
//! Other Globals
timer TIMER = null
group GROUP = null
location LOCATION = null
endglobals
private function True takes nothing returns boolean
return true
endfunction
private function init takes nothing returns nothing
set WORLD_BOUNDS = GetWorldBounds ( )
set MAP_MAX_X = GetRectMaxX ( WORLD_BOUNDS )
set MAP_MIN_X = GetRectMinX ( WORLD_BOUNDS )
set MAP_MAX_Y = GetRectMaxY ( WORLD_BOUNDS )
set MAP_MIN_Y = GetRectMinY ( WORLD_BOUNDS )
set TrueExpr = Filter ( function True )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library AttachAPI requires SourceAPI
globals
constant integer MAX_ARRAY_INDEXES = 10000
endglobals
//! textmacro Attach takes TYPE, NAME, PREFIX
globals
private $TYPE$ array $NAME$ [ MAX_ARRAY_INDEXES ]
endglobals
$PREFIX$ function GetHandle$NAME$ takes handle h returns $TYPE$
return $NAME$ [ GetHandleId ( h ) - 0x100000 ]
endfunction
$PREFIX$ function SetHandle$NAME$ takes handle h, $TYPE$ value returns nothing
set $NAME$ [ GetHandleId ( h ) - 0x100000 ] = value
endfunction
//! endtextmacro
//! runtextmacro Attach ( "integer", "Struct", "" )
//! runtextmacro Attach ( "destructable", "Destructable", "" )
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library MathAPI
function AngleBetween takes real xA, real yA, real xB, real yB returns real
return bj_RADTODEG * Atan2 ( yB - yA, xB - xA )
endfunction
function DistanceBetween takes real xA, real yA, real xB, real yB returns real
return SquareRoot ( ( xB - xA ) * ( xB - xA ) + ( yB - yA ) * ( yB - yA ) )
endfunction
function AngleBetweenWidgets takes widget a, widget b returns real
return AngleBetween ( GetWidgetX ( a ), GetWidgetY ( a ), GetWidgetX ( b ), GetWidgetY ( b ) )
endfunction
function DistanceBetweenWidgets takes widget a, widget b returns real
return DistanceBetween ( GetWidgetX ( a ), GetWidgetY ( a ), GetWidgetX ( b ), GetWidgetY ( b ) )
endfunction
function PercentOfValue takes real Value, real Percent returns real
return Value * Percent
endfunction
function GetValuePercent takes real MaxValue, real Value returns real
return Value / MaxValue
endfunction
function ProjectX takes real x, real distance, real angle returns real
return x + distance * Cos ( angle * bj_DEGTORAD )
endfunction
function ProjectY takes real y, real distance, real angle returns real
return y + distance * Sin ( angle * bj_DEGTORAD )
endfunction
function IsBetweenInt takes integer tocheck, integer i1, integer i2 returns boolean
return ( ( tocheck < i1 ) and ( i2 < tocheck ) ) or ( ( tocheck > i1 ) and ( tocheck < i2 ) )
endfunction
function IsBetweenReal takes real tocheck, real r1, real r2 returns boolean
return ( ( tocheck < r1 ) and ( r2 < tocheck ) ) or ( ( tocheck > r1 ) and ( tocheck < r2 ) )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library DebugAPI
function MSG takes string Debug returns nothing
call DisplayTextToPlayer ( GetLocalPlayer ( ), 0, 0, Debug )
endfunction
function INT takes integer Debug returns nothing
call DisplayTextToPlayer ( GetLocalPlayer ( ), 0, 0, I2S ( Debug ) )
endfunction
function REAL takes real Debug returns nothing
call DisplayTextToPlayer ( GetLocalPlayer ( ), 0, 0, R2S ( Debug ) )
endfunction
function BOOL takes boolean Debug returns nothing
if Debug then
call DisplayTextToPlayer ( GetLocalPlayer ( ), 0, 0, "TRUE" )
else
call DisplayTextToPlayer ( GetLocalPlayer ( ), 0, 0, "FALSE" )
endif
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
library RecycleAPI requires AttachAPI, UnitAPI, SourceAPI
//! runtextmacro Attach ( "integer", "Data", "private" )
private struct Timer
timer t
static method Allocate takes nothing returns timer
local Timer t = Timer.allocate()
if t.t==null then
set t.t=CreateTimer()
endif
call SetHandleData(t.t,t)
return t.t
endmethod
method onDestroy takes nothing returns nothing
call PauseTimer(.t)
endmethod
endstruct
function NewTimer takes nothing returns timer
return Timer.Allocate()
endfunction
function ReleaseTimer takes timer t returns nothing
call Timer.destroy(GetHandleData(t))
endfunction
private struct Group
group g
static method Allocate takes nothing returns group
local Group g = Group.allocate()
if g.g==null then
set g.g=CreateGroup()
endif
call SetHandleData(g.g,g)
return g.g
endmethod
method onDestroy takes nothing returns nothing
call GroupClear(.g)
endmethod
endstruct
function NewGroup takes nothing returns group
return Group.Allocate()
endfunction
function ReleaseGroup takes group g returns nothing
call Group.destroy(GetHandleData(g))
endfunction
endlibrary
//TESH.scrollpos=121
//TESH.alwaysfold=0
library FadeAPI requires AttachAPI, RecycleAPI
globals
private constant real CYCLE = 0.035
private group HasVertexData = CreateGroup()
private group HasPosData = CreateGroup()
private real array Start
private real array End
endglobals
private struct data
unit u
real array current [4]
real array start [4]
real array end [4]
real array speed [4]
boolean array increase [4]
timer t
method onDestroy takes nothing returns nothing
call ReleaseTimer(.t)
endmethod
endstruct
//! runtextmacro Attach ("integer", "VertexData", "private")
//! runtextmacro Attach ("integer", "PosData", "private")
private function VertexExecution takes nothing returns nothing
local data v = GetHandleStruct(GetExpiredTimer())
local integer i = 0
loop
if v.increase[i] then
set v.current[i] = v.current[i] + v.speed[i]
if v.current[i] >= v.end[i] then
set v.speed[i] = 0
set v.current[i] = v.end[i]
endif
else
set v.current[i] = v.current[i] + v.speed[i]
if v.current[i] <= v.end[i] then
set v.speed[i] = 0
set v.current[i] = v.end[i]
endif
endif
set i = i + 1
exitwhen i > 3
endloop
call SetUnitVertexColor(v.u,R2I(v.current[0]),R2I(v.current[1]),R2I(v.current[2]),R2I(v.current[3]))
if ( v.speed[0]==0 and v.speed[1]==0 and v.speed[2]==0 and v.speed[3]==0 ) or GetUnitState ( v.u, UNIT_STATE_LIFE ) <= 0.405 then
call v.destroy()
call GroupRemoveUnit(HasVertexData, v.u)
endif
endfunction
private function PosExecution takes nothing returns nothing
local data v = GetHandleStruct(GetExpiredTimer())
local integer i = 0
loop
if v.increase[i] then
set v.current[i] = v.current[i] + v.speed[i]
if v.current[i] >= v.end[i] then
set v.speed[i] = 0
set v.current[i] = v.end[i]
endif
else
set v.current[i] = v.current[i] + v.speed[i]
if v.current[i] <= v.end[i] then
set v.speed[i] = 0
set v.current[i] = v.end[i]
endif
endif
set i = i + 1
exitwhen i > 2
endloop
call SetUnitX(v.u, v.current[0])
call SetUnitY(v.u, v.current[1])
call SetUnitFlyHeight(v.u, v.current[2], 0)
if ( v.speed[0]==0 and v.speed[1]==0 and v.speed[2]==0 ) or GetUnitState ( v.u, UNIT_STATE_LIFE ) <= 0.405 then
call v.destroy()
call GroupRemoveUnit(HasPosData, v.u)
endif
endfunction
function SetVertexStartColor takes integer red, integer green, integer blue, integer alpha returns nothing
set Start[0] = red
set Start[1] = green
set Start[2] = blue
set Start[3] = alpha
endfunction
function SetVertexEndColor takes integer red, integer green, integer blue, integer alpha returns nothing
set End[0]=red
set End[1]=green
set End[2]=blue
set End[3]=alpha
endfunction
function FadeUnitVertexColor takes unit u, real time returns nothing
local data v
local integer i = 0
if IsUnitInGroup(u, HasVertexData) then
set v = GetHandleVertexData(u)
else
set v = data.create()
set v.u = u
call GroupAddUnit(HasVertexData, u)
call SetHandleVertexData(u, v)
set v.t=NewTimer()
call SetHandleStruct(v.t,v)
endif
loop
set v.start[i] = Start[i]
set v.end[i] = End[i]
set v.current[i] = Start[i]
if time > 0 then
set v.speed[i] = ((End[i] - Start[i]) * CYCLE) / time
else
set v.speed[i] = ((End[i] - Start[i]) * CYCLE)
endif
if v.speed[i] > 0 then
set v.increase[i] = true
else
set v.increase[i] = false
endif
set i = i + 1
exitwhen i > 3
endloop
call TimerStart(v.t,CYCLE,true,function VertexExecution)
endfunction
function FadeUnitPosition takes unit u, real newX, real newY, real newZ, real time returns nothing
local data v
local integer i = 0
if IsUnitInGroup(u, HasPosData) then
set v = GetHandlePosData(u)
else
set v = data.create()
set v.u = u
call GroupAddUnit(HasPosData, u)
call SetHandlePosData(u, v)
set v.t=NewTimer()
call SetHandleStruct(v.t,v)
endif
set v.start[0] = GetUnitX(u)
set v.end[0] = newX
set v.start[1] = GetUnitY(u)
set v.end[1] = newY
set v.start[2] = GetUnitFlyHeight(u)
set v.end[2] = newZ
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
loop
set v.current[i] = v.start[i]
if time > 0 then
set v.speed[i] = ((v.end[i] - v.start[i]) * CYCLE) / time
else
set v.speed[i] = ((v.end[i] - v.start[i]) * CYCLE)
endif
if v.speed[i] > 0 then
set v.increase[i] = true
else
set v.increase[i] = false
endif
set i = i + 1
exitwhen i > 2
endloop
call TimerStart(v.t,CYCLE,true,function PosExecution)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UnitAPI requires SourceAPI
function RemoveUnitEx takes unit whichUnit returns nothing
call ShowUnit(whichUnit, false)
call KillUnit(whichUnit)
endfunction
function SetUnitZ takes unit whichUnit, real newZ returns nothing
call UnitAddAbility(whichUnit, 'Amrf')
call UnitRemoveAbility(whichUnit, 'Amrf')
call SetUnitFlyHeight(whichUnit, newZ, 0)
endfunction
function GetUnitZ takes unit whichUnit returns real
return GetUnitFlyHeight(whichUnit)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library PlayerAPI initializer init
globals
constant string COLOR_RED = "|cFFFF0303"
constant string COLOR_BLUE = "|cFF0042FF"
private string array COLOR_ARRAY
endglobals
function PlayerHexColor takes player whichPlayer returns string
local integer id = 0
loop
exitwhen GetPlayerColor(whichPlayer) == ConvertPlayerColor(id)
set id = id + 1
endloop
return COLOR_ARRAY[id]
endfunction
private function init takes nothing returns nothing
set COLOR_ARRAY[0] = COLOR_RED
set COLOR_ARRAY[1] = COLOR_BLUE
endfunction
endlibrary
//TESH.scrollpos=76
//TESH.alwaysfold=0
library PointAPI requires SourceAPI, UnitAPI
globals
private location Loc=Location(0,0)
private unit Unit=null
endglobals
struct point
real x=0
real y=0
real z=0
private static location loc=Location(0,0)
static method create takes real x, real y, real z returns point
local point p = point.allocate()
set p.x = x
set p.y = y
set p.z = z
return p
endmethod
method clone takes nothing returns point
return point.create(.x,.y,.z)
endmethod
method move takes real x, real y, real z returns nothing
set .x = x
set .y = y
set .z = z
endmethod
method moveTo takes point p returns nothing
set .x = p.x
set .y = p.y
set .z = p.z
endmethod
method moveToUnit takes unit u returns nothing
set .x = GetUnitX(u)
set .y = GetUnitY(u)
set .z = GetUnitFlyHeight(u)
endmethod
method moveToLoc takes location l returns nothing
set .x = GetLocationX(l)
set .y = GetLocationY(l)
set .z = GetLocationZ(l)
endmethod
method moveToWidget takes widget w returns nothing
set .x = GetWidgetX(w)
set .y = GetWidgetY(w)
set .z = .0
endmethod
method moveToRect takes rect r returns nothing
set .x = GetRectCenterX(r)
set .y = GetRectCenterY(r)
set .z = .0
endmethod
method add takes real x, real y, real z returns nothing
set .x = .x + x
set .y = .y + y
set .z = .z + z
endmethod
method addPoint takes point p returns nothing
set .x = .x + p.x
set .y = .y + p.y
set .z = .z + p.z
endmethod
method removePoint takes point p returns nothing
set .x = .x - p.x
set .y = .y - p.y
set .z = .z - p.z
endmethod
method distance takes point p returns real
return SquareRoot(((p.x-.x)*(p.x-.x))+((p.y-.y)*(p.y-.y))+((p.z-.z)*(p.z-.z)))
endmethod
method terrainZ takes nothing returns real
call MoveLocation(.loc, .x, .y)
return GetLocationZ(.loc)
endmethod
method totalZ takes nothing returns real
return .z+.terrainZ()
endmethod
method closest takes nothing returns nothing
call ShowUnit(Unit, true)
call SetUnitPosition(Unit, .x, .y)
set .x = GetUnitX(Unit)
set .y = GetUnitY(Unit)
call ShowUnit(Unit, false)
endmethod
method phi takes point p returns real
return Atan2(SquareRoot((p.x-.x)*(p.x-.x)+(p.y-.y)*(p.y-.y)),(p.z-.z))
endmethod
method theta takes point p returns real
return Atan2((p.y-.y),(p.x-.x))
endmethod
method project takes real distance, real theta, real phi returns nothing
set .x=.x+distance*Sin(phi)*Cos(theta)
set .y=.y+distance*Sin(phi)*Sin(theta)
set .z=.z+distance*Cos(phi)
endmethod
method projectTowards takes real distance, point p returns nothing
call .project(distance, .theta(p), .phi(p))
endmethod
method polarProject takes real distance, real angle returns nothing
set .x=.x+distance*Cos(angle)
set .y=.y+distance*Sin(angle)
endmethod
method projectX takes real distance, real angle returns nothing
set .x=.x+distance*Cos(angle)
endmethod
method projectY takes real distance, real angle returns nothing
set .y=.y+distance*Sin(angle)
endmethod
method moveUnit takes unit whichUnit returns nothing
call SetUnitX(whichUnit, .x)
call SetUnitY(whichUnit, .y)
call SetUnitZ(whichUnit, .z)
endmethod
method outOfBounds takes nothing returns boolean
return .x > MAP_MAX_X or .x < MAP_MIN_X or .y > MAP_MAX_Y or .y < MAP_MIN_Y
endmethod
endstruct
function GetPointZ takes real x, real y returns real
call MoveLocation(Loc, x, y)
return GetLocationZ(Loc)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CameraAPI initializer init
globals
private boolean array Controller
private real array ControllerField [8][12]
private timer ControlTimer = CreateTimer()
endglobals
private function CameraControllerCallback takes nothing returns nothing
local integer i = 0
local integer field = 0
loop
if Controller[i] then
loop
if GetLocalPlayer() == Player(i) then
call SetCameraField(ConvertCameraField(field), ControllerField[field][i], ControllerField[7][i])
endif
set field = field + 1
exitwhen field > 6
endloop
endif
set field = 0
set i = i + 1
exitwhen i > 11
endloop
endfunction
function SetCameraControllerField takes integer playerId, camerafield field, real value returns nothing
local integer i = 0
loop
exitwhen ConvertCameraField(i) == field
set i = i + 1
endloop
set ControllerField[i][playerId] = value
endfunction
function SetCameraControllerSmoothing takes integer playerId, real smoothing returns nothing
set ControllerField[7][playerId] = smoothing
endfunction
function ApplyCameraController takes integer playerId, boolean enable returns nothing
set Controller[playerId] = enable
endfunction
function ApplyCameraControllerAll takes boolean enable returns nothing
local integer i = 0
loop
set Controller[i] = enable
set i = i + 1
exitwhen i > 11
endloop
endfunction
function EnableCameraController takes boolean enable returns nothing
if enable then
call TimerStart(ControlTimer, 0.05, true, function CameraControllerCallback)
else
call PauseTimer(ControlTimer)
endif
endfunction
private function init takes nothing returns nothing
local integer i = 0
loop
set Controller[i] = false
set ControllerField[0][i] = bj_CAMERA_DEFAULT_DISTANCE
set ControllerField[1][i] = bj_CAMERA_DEFAULT_FARZ
set ControllerField[2][i] = bj_CAMERA_DEFAULT_AOA
set ControllerField[3][i] = bj_CAMERA_DEFAULT_FOV
set ControllerField[4][i] = bj_CAMERA_DEFAULT_ROLL
set ControllerField[5][i] = bj_CAMERA_DEFAULT_ROTATION
set ControllerField[6][i] = 0
set i = i + 1
exitwhen i > 11
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library MiscAPI requires SourceAPI, RecycleAPI
function Wait takes real duration returns nothing
local timer t
local real timeRemaining
if duration > 0 then
set t = NewTimer()
call TimerStart(t, duration, false, null)
loop
set timeRemaining = TimerGetRemaining(t)
exitwhen timeRemaining <= 0
if timeRemaining > 2.0 then
call TriggerSleepAction(0.1 * timeRemaining)
else
call TriggerSleepAction(0)
endif
endloop
call ReleaseTimer(t)
set t = null
endif
endfunction
//function MapString takes integer index returns string
// if index < 10 then
// return ("TRIGSTR_00"+I2S(index))
// elseif index < 100 then
// return ("TRIGSTR_0"+I2S(index))
// endif
// return ("TRIGSTR_"+I2S(index))
//endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope BoundSentinel initializer init //! Credits to Vexorian
globals
private constant real SAFE_FRAME = 32.0
endglobals
private function dis takes nothing returns nothing
local unit u = GetTriggerUnit ( )
local real x = GetUnitX ( u )
local real y = GetUnitY ( u )
if x > MAP_MAX_X then
set x = MAP_MAX_X - SAFE_FRAME
elseif x < MAP_MIN_X then
set x = MAP_MIN_X + SAFE_FRAME
endif
if y > MAP_MAX_Y then
set y = MAP_MAX_Y - SAFE_FRAME
elseif y < MAP_MIN_Y then
set y = MAP_MIN_Y + SAFE_FRAME
endif
call SetUnitX ( u, x )
call SetUnitY ( u, y )
set u = null
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
local region r = CreateRegion ( )
call RegionAddRect ( r, WORLD_BOUNDS )
call TriggerRegisterLeaveRegion ( t, r, null )
call TriggerAddAction ( t, function dis )
set t = null
set r = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Initialization initializer init
//! Main map initializer
//!===========================================================================
private function init takes nothing returns nothing
//!////////////////////////////////////////////
//! Initialize player variables
//!
call InitPlayers.execute ( )
//!////////////////////////////////////////////
//! Run terrain generator
//!
call InitTerrainGenerator.execute ( )
//!////////////////////////////////////////////
//! Create cannons
//!
call CreateCannons.execute ( )
//!////////////////////////////////////////////
//! Init Power
//!
call InitPower.execute ( )
//!////////////////////////////////////////////
//! Apply wind settings
//!
call RandomizeWind.execute ( )
//!////////////////////////////////////////////
//! Apply wind display models
//!
//call InitWindEffectModels.execute ( )
//!////////////////////////////////////////////
//! Play map music
//!
call PlayMapMusic.execute ( )
//!////////////////////////////////////////////
//! Create control panels
//!
call CreateDummyPanels.execute ( )
//!////////////////////////////////////////////
//! Initialize and create camera setups
//!
call InitCameraSettings.execute ( )
//!////////////////////////////////////////////
//! Create multiboard
//!
call MultiboardSetup.execute ( )
//!////////////////////////////////////////////
//! Initialize round timer
//!
call InitRoundTimer.execute ( )
//!////////////////////////////////////////////
//! Runs the round manager
//!
call RunRoundManager.execute ( )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library MapDefinition initializer init requires SourceAPI
globals
constant real MIN_X = 1024.00
constant real MAX_X = 3072.00
constant real MIN_Y = -4096.00
constant real MAX_Y = -512.00
endglobals
private function init takes nothing returns nothing
//! Lock time of day
call SetTimeOfDayScale ( 0 )
call SetFloatGameState ( GAME_STATE_TIME_OF_DAY, 12.00 )
//! Remove fog, fog mask, boundary shaddow and terrain fog
call FogEnable ( false )
call FogMaskEnable ( false )
call EnableWorldFogBoundary ( false )
call SetTerrainFogEx ( 0, 20000, 20000, 0, 0, 0, 0 )
//! Apply sky model
call SetSkyModel ( "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl" )
//! Stop default map music
call SetMusicVolume ( 0 )
call StopMusic ( false )
call EndThematicMusic ( )
//! Disable drag-selection
call EnableDragSelect ( false, false )
call EnableSelect ( true, false )
//! Disable minimap buttons
call EnableMinimapFilterButtons ( false, false )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
globals
constant string MAP_MUSIC = "Music\\LandOfMusic4.mp3" //! Map Music
constant real MUSIC_START_TIMEOUT = 0.20 //! Gametime before music starts playing
endglobals
function StartMusic takes nothing returns nothing
//! Rayman is awesome :D
call ReleaseTimer ( GetExpiredTimer ( ) )
call PlayMusic ( MAP_MUSIC )
call SetMusicVolume ( 127 )
endfunction
function PlayMapMusic takes nothing returns nothing
call TimerStart ( NewTimer ( ), MUSIC_START_TIMEOUT, false, function StartMusic )
endfunction
//TESH.scrollpos=166
//TESH.alwaysfold=0
globals
boolean IS_SINGLE_PLAYER = true //! Singleplayer until proven otherwise
boolean PRACTICE_MODE = false //! Returns true if Practice Mode is enabled
boolean TWO_DIMENSIONAL = true //! Returns true if 2D Mode is enabled
integer ROUND_NUMBER = 0 //! Current round number
integer CURRENT_PLAYER = 0 //! The player currently playing
boolean array IS_PLAYING //! Returns true if the array player is actually playing
integer SINGLE_PLAYER_ID = 0 //! When single-player, this points to the playerid of the playing player
player array PLAYER //! Players
integer array ROUNDS_WON //! Rounds won by each player
timer T = CreateTimer ( ) //! First round startup delay timer
timer T2 = CreateTimer ( ) //! New round delay timer
endglobals
function StartTurn takes integer playerId, boolean resetStats returns nothing
//! Set player variable to enable cannon rotation
set CURRENT_PLAYER = playerId
if resetStats then
//! Reset cannons angles and animations
call ResetCannons.execute ( )
if SMOKE != null then
//! Safety
call RemoveUnitEx ( SMOKE )
set SMOKE = null
endif
//! Resets cannons health
call ResetHealth.execute ( )
endif
//! Start timer
if PRACTICE_MODE then
//! Practice mode; disable timer
call MultiboardSetItemValue ( BOARD_TIMER, "- : --" )
else
call StartRoundTimer.execute ( )
endif
//! Update the player's aiming point
call UpdateAimPoint.execute ( playerId )
//! Enable abilities
call EnableAbilities ( playerId, true )
if not TWO_DIMENSIONAL then
//! If 3D mode, enable the camera controller abilities
call EnableCameraCustomize ( true )
endif
//! Reset amount of projectiles
call ResetProjectileCount.execute ( )
//! Randomize wind settings
call RandomizeWind ( )
//! Update multiboard ammo display
call UpdateAmmoDisplay.execute ( )
//! Update 'Rounds Won' state
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_LUMBER, ROUNDS_WON [ 0 ] )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_LUMBER, ROUNDS_WON [ 1 ] )
if IS_SINGLE_PLAYER then
call SetPlayerState ( PLAYER [ playerId ], PLAYER_STATE_RESOURCE_LUMBER, ROUNDS_WON [ playerId ] )
//if not PRACTICE_MODE then
// //! If versus mode, return camera to default between each round
// call SetCamera ( SINGLE_PLAYER_ID, 0 )
//endif
endif
//! Fade filter
if PRACTICE_MODE then
call CinematicFadeBJ ( bj_CINEFADETYPE_FADEOUTIN, 5, "Filter\\PracticeFilter.blp", 100, 100, 100, 0 )
call UnitAddAbility ( PANELS [ 0 ], 'A007' )
call UnitAddAbility ( PANELS [ 0 ], 'A008' )
call UnitAddAbility ( PANELS [ 1 ], 'A007' )
call UnitAddAbility ( PANELS [ 1 ], 'A008' )
else
call CinematicFadeBJ ( bj_CINEFADETYPE_FADEOUTIN, 5, "Filter\\Player"+I2S(playerId+1)+".blp", 100, 100, 100, 0 )
call UnitRemoveAbility ( PANELS [ 0 ], 'A007' )
call UnitRemoveAbility ( PANELS [ 0 ], 'A008' )
call UnitRemoveAbility ( PANELS [ 1 ], 'A007' )
call UnitRemoveAbility ( PANELS [ 1 ], 'A008' )
endif
endfunction
function EndTurn takes nothing returns nothing
//! Disable abilities
call EnableAbilities ( 0, false )
call EnableAbilities ( 1, false )
call EnableCameraCustomize ( false )
//! Remove aiming pointer
call RemovePointer.execute ( )
if HIT_POINTS [ 0 ] <= 0 or HIT_POINTS [ 1 ] <= 0 then
//! A player is dead. End this round
call NewRoundDelay.execute ( 5 )
if HIT_POINTS [ 0 ] <= 0 then
set ROUNDS_WON [ 1 ] = ROUNDS_WON [ 1 ] + 1
else
set ROUNDS_WON [ 0 ] = ROUNDS_WON [ 0 ] + 1
endif
else
//! No players are dead yet. Change turn
if CURRENT_PLAYER == 0 then
call StartTurn ( 1, false )
else
call StartTurn ( 0, false )
endif
endif
endfunction
function NewRound takes nothing returns nothing
//! Get random starting player
local integer i = GetRandomInt ( 0, 1 )
//! If Practice Mode, use the playing player
if PRACTICE_MODE then
set i = SINGLE_PLAYER_ID
endif
//! New round number
set ROUND_NUMBER = ROUND_NUMBER + 1
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_GOLD, ROUND_NUMBER )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_GOLD, ROUND_NUMBER )
//! Randomize terrain
call terrain.RemoveAll ( )
call GenerateTerrain.execute ( )
//! Start new turn
call StartTurn ( i, true )
set ENABLE_OPEN_MENU = true
endfunction
function NewRoundDelay takes real delay returns nothing
//! Starts a new round after a delay
call TimerStart ( T2, delay, false, function NewRound )
endfunction
function RunRoundManager takes nothing returns nothing
if not IS_SINGLE_PLAYER then
//! Multiplayer found. Run new round right away.
call TimerStart ( T, 0.5, false, function NewRound )
call MultiplayerDialogInitializer.execute ( )
else
//! Apply menu and stuff
call InitMenu.execute ( )
endif
endfunction
function GetPlayerIdEx takes player p returns integer
//! Will return the id of a player
if IS_SINGLE_PLAYER then
//! Singleplayer detected, return current player
return CURRENT_PLAYER
endif
//! Multiplayer, return player id
return GetPlayerId ( p )
endfunction
function InitPlayers takes nothing returns nothing
//! **********************************************************
//!
//! SHOULD BE EXECUTED BEFORE ANYTHING ELSE
//!
//! ***********************************************************
set IS_PLAYING [ 0 ] = false
set IS_PLAYING [ 1 ] = false
//! Find multiplayer game
if GetPlayerController ( Player ( 0 ) ) == MAP_CONTROL_USER and GetPlayerSlotState ( Player ( 0 ) ) == PLAYER_SLOT_STATE_PLAYING then
//! Player 0 is playing
set IS_PLAYING [ 0 ] = true
set SINGLE_PLAYER_ID = 0
endif
if GetPlayerController ( Player ( 1 ) ) == MAP_CONTROL_USER and GetPlayerSlotState ( Player ( 1 ) ) == PLAYER_SLOT_STATE_PLAYING then
//! Player 1 is playing
set IS_PLAYING [ 1 ] = true
set SINGLE_PLAYER_ID = 1
endif
if IS_PLAYING [ 0 ] and IS_PLAYING [ 1 ] then
//! Both players are playing, this is no longer a singleplayer game
set PLAYER [ 0 ] = Player ( 0 )
set PLAYER [ 1 ] = Player ( 1 )
set IS_SINGLE_PLAYER = false
else
if IS_PLAYING [ 0 ] then
//! Singleplayer game. Player 0 is playing
set PLAYER [ 0 ] = Player ( 0 )
set PLAYER [ 1 ] = Player ( 0 )
else
//! Singleplayer game. Player 1 is playing
set PLAYER [ 0 ] = Player ( 1 )
set PLAYER [ 1 ] = Player ( 1 )
endif
endif
//! Initialize rounds won
set ROUNDS_WON [ 0 ] = 0
set ROUNDS_WON [ 1 ] = 0
endfunction
//TESH.scrollpos=113
//TESH.alwaysfold=0
globals
constant string TRACKABLE_MODEL = "Models\\Effects\\ButtonTrackable.mdl" //! Dummy trackable model
boolean USING_MENU = false //! Is true when the menu is in use
boolean ENABLE_OPEN_MENU = false //! Is true when the menu is openable
MenuButton BUTTON_VERSUS //! Menu button: Versus
MenuButton BUTTON_PRACTICE //! Menu button: Practice
MenuButton BUTTON_PLATFORM //! Menu button: Platform type (2D/3D)
trigger TRACK = CreateTrigger ( ) //! Trackable tracked trigger
trigger HIT = CreateTrigger ( ) //! Trackable clicked trigger
timer MENU_TIMER = CreateTimer ( ) //! New round delay timer
endglobals
function TrackButton takes nothing returns boolean
local MenuButton m
if not USING_MENU then
return false
endif
call StopSound ( gg_snd_TrackButton, false, false )
call StartSound ( gg_snd_TrackButton )
set m = GetHandleStruct ( GetTriggeringTrackable ( ) )
call AddUnitAnimationProperties ( BUTTON_PRACTICE.u, "alternate", false )
call AddUnitAnimationProperties ( BUTTON_VERSUS.u, "alternate", false )
call AddUnitAnimationProperties ( BUTTON_PLATFORM.u, "alternate", false )
call AddUnitAnimationProperties ( m.u, "alternate", true )
return false
endfunction
function ClickButton takes nothing returns boolean
local MenuButton m
if not USING_MENU then
return false
endif
set m = GetHandleStruct ( GetTriggeringTrackable ( ) )
if m == BUTTON_PLATFORM then
set TWO_DIMENSIONAL = not TWO_DIMENSIONAL
call RemoveUnitEx ( m.txt )
call SetVertexStartColor ( 255, 255, 255, 0 )
call SetVertexEndColor ( 255, 255, 255, 255 )
if TWO_DIMENSIONAL then
set m.txt = CreateUnit ( Player ( 14 ), 'h00D', m.x, m.y-32, 270 )
call SetUnitFlyHeight ( m.txt, m.z, 0 )
call FadeUnitVertexColor ( m.txt, 0.5 )
else
set m.txt = CreateUnit ( Player ( 14 ), 'h00E', m.x, m.y-32, 270 )
call SetUnitFlyHeight ( m.txt, m.z, 0 )
call FadeUnitVertexColor ( m.txt, 0.5 )
endif
call StopSound ( gg_snd_TrackButton, false, false )
call StartSound ( gg_snd_TrackButton )
return false
elseif m == BUTTON_PRACTICE then
set PRACTICE_MODE = true
else
set PRACTICE_MODE = false
endif
call AddUnitAnimationProperties ( BUTTON_PRACTICE.u, "alternate", false )
call AddUnitAnimationProperties ( BUTTON_VERSUS.u, "alternate", false )
call AddUnitAnimationProperties ( BUTTON_PLATFORM.u, "alternate", false )
call StartSound ( gg_snd_ClickButton )
call CinematicFadeBJ ( bj_CINEFADETYPE_FADEIN, 0.25, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 100, 100, 100, 0 )
set USING_MENU = false
call BUTTON_VERSUS.hide ( 2 )
call BUTTON_PRACTICE.hide ( 2 )
call BUTTON_PLATFORM.hide ( 2 )
call TimerStart ( MENU_TIMER , 3, false, function NewRound )
return false
endfunction
struct MenuButton
trackable t
unit u
unit txt
real x
real y
real z
static method create takes real z, integer textdummy returns MenuButton
local MenuButton m = MenuButton.allocate ( )
local real x = GetRectCenterX ( gg_rct_MenuSpawn )
local real y = GetRectCenterY ( gg_rct_MenuSpawn )
local destructable d = CreateDestructableZ ( 'OTip', x, y, z - 720, 0, 1, 0 )
set m.u = CreateUnit ( Player ( 14 ), 'h009', x, y, 270 )
call SetUnitFlyHeight ( m.u, z, 0 )
set m.txt = CreateUnit ( Player ( 14 ), textdummy, x, y-32, 270 )
call SetUnitFlyHeight ( m.txt, z, 0 )
set m.t = CreateTrackable ( TRACKABLE_MODEL, x, y, 180 )
call SetHandleStruct ( m.t, m )
call TriggerRegisterTrackableTrackEvent ( TRACK, m.t )
call TriggerRegisterTrackableHitEvent ( HIT, m.t )
call RemoveDestructable ( d )
set d = null
set m.x = x
set m.y = y
set m.z = z
return m
endmethod
method hide takes real fadetime returns nothing
call SetVertexStartColor ( 255, 255, 255, 255 )
call SetVertexEndColor ( 255, 255, 255, 0 )
call FadeUnitVertexColor ( .u, fadetime )
call FadeUnitVertexColor ( .txt, fadetime )
endmethod
method show takes real fadetime returns nothing
call SetVertexStartColor ( 255, 255, 255, 0 )
call SetVertexEndColor ( 255, 255, 255, 255 )
call FadeUnitVertexColor ( .u, fadetime )
call FadeUnitVertexColor ( .txt, fadetime )
endmethod
endstruct
function EnableInteractivity takes nothing returns nothing
set USING_MENU = true
call ReleaseTimer ( GetExpiredTimer ( ) )
endfunction
function ApplyMenu takes nothing returns nothing
call EnableCameraCustomize ( false )
//! Apply camera
call SetCamera ( 0, 0 )
call SetCamera ( 1, 0 )
//! Show menu
call BUTTON_VERSUS.show ( 1 )
call BUTTON_PRACTICE.show ( 1 )
call BUTTON_PLATFORM.show ( 1 )
set ENABLE_OPEN_MENU = false
call TimerStart ( NewTimer ( ), 1.1, false, function EnableInteractivity )
endfunction
function InitMenu takes nothing returns nothing
call TriggerAddCondition ( TRACK, Condition ( function TrackButton ) )
call TriggerAddCondition ( HIT, Condition ( function ClickButton ) )
//! Create menu buttons
set BUTTON_PLATFORM = MenuButton.create ( 2600, 'h00D' )
set BUTTON_VERSUS = MenuButton.create ( 2000, 'h00A' )
set BUTTON_PRACTICE = MenuButton.create ( 1400, 'h00B' )
call ApplyMenu ( )
call ReturnToMenuInitializer.execute ( )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function ReturnMenu takes nothing returns boolean
if (not USING_MENU) and (not CHASE_CAM) and (ENABLE_OPEN_MENU) then
//! Disable abilities
call EnableAbilities ( 0, false )
call EnableAbilities ( 1, false )
//! Remove aiming pointer
call RemovePointer.execute ( )
//! This round was canceled
set ROUND_NUMBER = ROUND_NUMBER - 1
//! Pause the round timer
call PauseRoundTimer.execute ( )
//! Applies the actual menu
call ApplyMenu ( )
endif
return false
endfunction
function ReturnToMenuInitializer takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerEvent( t, Player(0), EVENT_PLAYER_END_CINEMATIC )
call TriggerRegisterPlayerEvent( t, Player(1), EVENT_PLAYER_END_CINEMATIC )
call TriggerAddCondition( t, Condition ( function ReturnMenu ) )
endfunction
//TESH.scrollpos=95
//TESH.alwaysfold=0
globals
boolean DIALOG_IN_USE = false
dialog OPTION_DIALOG = null
dialog CONFIRM_DIALOG
button array BUTTON
constant integer VOTE_OPTION_PLATFORM = 0
constant integer VOTE_OPTION_TERRAIN = 1
constant integer VOTE_OPTION_RESTART = 2
integer CURRENT_VOTE_OPTION = 0
player DIALOG_PLAYER = null
trigger DIALOG_TRIG = CreateTrigger ( )
endglobals
function ConfirmClicked takes nothing returns boolean
if GetClickedButton ( ) == BUTTON [ 4 ] then
//! Accepted
call DisplayTextToPlayer ( DIALOG_PLAYER, 1, 0, "|cff33ff33Request Accepted|r")
if CURRENT_VOTE_OPTION == VOTE_OPTION_TERRAIN then
call terrain.RemoveAll ( )
call GenerateTerrain.execute ( )
set DIALOG_IN_USE = false
return false
elseif CURRENT_VOTE_OPTION == VOTE_OPTION_PLATFORM then
set TWO_DIMENSIONAL = not TWO_DIMENSIONAL
endif
//! Disable abilities
call EnableAbilities ( 0, false )
call EnableAbilities ( 1, false )
//! Remove aim pointer
call RemovePointer.execute ( )
//! Pause the round timer
call PauseRoundTimer.execute ( )
set ROUND_NUMBER = ROUND_NUMBER - 1
if TWO_DIMENSIONAL then
call SetCamera ( 0, 0 )
call SetCamera ( 1, 0 )
endif
call NewRound ( )
else
//! Rejected
call DisplayTextToPlayer ( DIALOG_PLAYER, 1, 0, "|cffff3333Request Rejected|r")
endif
set DIALOG_IN_USE = false
return false
endfunction
function OptionClicked takes nothing returns boolean
local button b = GetClickedButton ( )
if b == BUTTON [ 0 ] then
set CURRENT_VOTE_OPTION = VOTE_OPTION_PLATFORM
if TWO_DIMENSIONAL then
call DialogSetMessage ( CONFIRM_DIALOG, PlayerHexColor ( DIALOG_PLAYER ) + GetPlayerName ( DIALOG_PLAYER ) + "|r wants to change platform: |cffff33333D|r." )
else
call DialogSetMessage ( CONFIRM_DIALOG, PlayerHexColor ( DIALOG_PLAYER ) + GetPlayerName ( DIALOG_PLAYER ) + "|r wants to change platform: |cffff33332D|r." )
endif
elseif b == BUTTON [ 1 ] then
set CURRENT_VOTE_OPTION = VOTE_OPTION_TERRAIN
call DialogSetMessage ( CONFIRM_DIALOG, PlayerHexColor ( DIALOG_PLAYER ) + GetPlayerName ( DIALOG_PLAYER) + "|r wants to generate a new terrain." )
elseif b == BUTTON [ 2 ] then
set CURRENT_VOTE_OPTION = VOTE_OPTION_RESTART
call DialogSetMessage ( CONFIRM_DIALOG, PlayerHexColor ( DIALOG_PLAYER ) + GetPlayerName ( DIALOG_PLAYER) + "|r wants to restart this round." )
else
set DIALOG_IN_USE = false
set b = null
return false
endif
if DIALOG_PLAYER == Player ( 0 ) then
call DialogDisplay ( Player ( 1 ), CONFIRM_DIALOG, true )
else
call DialogDisplay ( Player ( 0 ), CONFIRM_DIALOG, true )
endif
set b = null
return false
endfunction
function ApplyDialog takes player whichPlayer returns nothing
set DIALOG_IN_USE = true
set DIALOG_PLAYER = whichPlayer
if OPTION_DIALOG == null then
set OPTION_DIALOG = DialogCreate ( )
endif
call DialogClear ( OPTION_DIALOG )
call DialogSetMessage ( OPTION_DIALOG, "Requests" )
if TWO_DIMENSIONAL then
set BUTTON [ 0 ] = DialogAddButton ( OPTION_DIALOG, "New platform: |cffff33333D|r", 0 )
else
set BUTTON [ 0 ] = DialogAddButton ( OPTION_DIALOG, "New platform: |cffff33332D|r", 0 )
endif
set BUTTON [ 1 ] = DialogAddButton ( OPTION_DIALOG, "|cffffffffRe-Generate Terrain|r", 0 )
set BUTTON [ 2 ] = DialogAddButton ( OPTION_DIALOG, "|cffffffffRestart Round|r", 0 )
set BUTTON [ 3 ] = DialogAddButton ( OPTION_DIALOG, "|cff33ff33Cancel|r", 0 )
call DialogDisplay (whichPlayer, OPTION_DIALOG, true )
endfunction
function EnterDialog takes nothing returns boolean
if (not CHASE_CAM) and (not DIALOG_IN_USE) then
call ApplyDialog ( GetTriggerPlayer ( ) )
endif
return false
endfunction
function MultiplayerDialogInitializer takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerEvent( DIALOG_TRIG, Player(0), EVENT_PLAYER_END_CINEMATIC )
call TriggerRegisterPlayerEvent( DIALOG_TRIG, Player(1), EVENT_PLAYER_END_CINEMATIC )
call TriggerAddCondition( DIALOG_TRIG, Condition ( function EnterDialog ) )
call TriggerRegisterDialogEvent ( t, OPTION_DIALOG )
call TriggerAddCondition ( t, Condition ( function OptionClicked ) )
set CONFIRM_DIALOG = DialogCreate ( )
set BUTTON [ 4 ] = DialogAddButton ( CONFIRM_DIALOG, "|cff33ff33Accept|r", 0 )
set BUTTON [ 5 ] = DialogAddButton ( CONFIRM_DIALOG, "|cffff3333Reject|r", 0 )
set t = CreateTrigger ( )
call TriggerRegisterDialogEvent ( t, CONFIRM_DIALOG )
call TriggerAddCondition ( t, Condition ( function ConfirmClicked ) )
endfunction
//TESH.scrollpos=224
//TESH.alwaysfold=0
//! ========================================================================================================
globals
constant real MAX_TERRAIN_Z = 256.00 //! Maximum height build per iteration
constant real MIN_TERRAIN_Z = 128.00 //! Minimum height build per iteration
constant real MAX_TERRAIN_RADIUS = 1024.00 //! Maximum radius per iteration
constant real MIN_TERRAIN_RADIUS = 256.00 //! Minimum radius per iteration
constant integer TERRAIN_ITERATOR = 45 //! Number of iterations
constant integer MAX_DECORATIONS = 30 //! Maximum amount of decorations
constant integer DIVIDER_2D = 2 //! Iterator division in 2D mode
constant string SPLAT_TEXTURE = "DHMB" //! Projectile collision ubersplat image
constant real CRATER_RADIUS = 256.00 //! Radius of projectile craters
constant real CRATER_DEPTH = 128.00 //! Depth of projectile craters
endglobals
//! ========================================================================================================
//! Doodad decorations
struct decoration
integer Type = 0
real min
real max
static decoration array ALL
static integer MAX = 0
static real maxx
static real minx
static real maxy
static real miny
static method define takes integer NewType, real minscale, real maxscale returns nothing
local decoration d = decoration.create ( )
set d.Type = NewType
set d.min = minscale
set d.max = maxscale
set d.ALL [ d.MAX ] = d
set d.MAX = d.MAX + 1
endmethod
static method apply takes nothing returns nothing
local integer index = MAX_DECORATIONS
local integer i
local real x
local real y
set decoration.maxx = GetRectMaxX ( gg_rct_MapDef )
set decoration.minx = GetRectMinX ( gg_rct_MapDef )
set decoration.maxy = GetRectMaxY ( gg_rct_MapDef )
set decoration.miny = GetRectMinY ( gg_rct_MapDef )
if TWO_DIMENSIONAL then //! +++ 2D mod +++
set decoration.maxy = GetRectCenterY ( gg_rct_MapDef )
set decoration.miny = GetRectCenterY ( gg_rct_MapDef )
set index = index / DIVIDER_2D
endif
loop
set i = GetRandomInt ( 0, decoration.MAX - 1 )
set x = GetRandomReal ( decoration.minx, decoration.maxx )
set y = GetRandomReal ( decoration.miny, decoration.maxy )
call CreateDestructableZ ( decoration.ALL [ i ].Type, x, y, GetPointZ ( x, y ) - 100, GetRandomReal ( 0, 360 ), GetRandomReal ( decoration.ALL[ i ].min, decoration.ALL[ i ].max ), 0 )
set index = index - 1
exitwhen index < 0
endloop
endmethod
static method RemoveDecorations takes nothing returns nothing
call RemoveDestructable ( GetEnumDestructable ( ) )
endmethod
endstruct
//! ========================================================================================================
//! Terrain tiles
struct tile
integer Type = 0
static tile array TILES
static integer MAX = 0
static method define takes integer NewType returns nothing
local tile t = tile.create ( )
set t.Type = NewType
set t.TILES [ t.MAX ] = t
set t.MAX = t.MAX + 1
endmethod
static method apply takes real x, real y returns nothing
local integer i = GetRandomInt ( 0, tile.MAX - 1 )
call SetTerrainType ( x, y, tile.TILES [ i ].Type, -1, GetRandomInt ( 2, 5 ), 0 )
endmethod
endstruct
//! ========================================================================================================
//! Crater ubersplats
struct splat
ubersplat u
method onDestroy takes nothing returns nothing
call DestroyUbersplat ( .u )
endmethod
static method new takes real x, real y returns nothing
local splat s = splat.create ( )
set s.u = CreateUbersplat ( x, y, SPLAT_TEXTURE, 255, 255, 255, 255, true, false )
call SetUbersplatRenderAlways ( s.u, true )
call SetUbersplatRender ( s.u, true )
call ShowUbersplat ( s.u, true )
set SPLATS [ SPLAT_MAX ] = s
set SPLAT_MAX = SPLAT_MAX + 1
endmethod
static method RemoveAll takes nothing returns nothing
loop
set SPLAT_MAX = SPLAT_MAX - 1
exitwhen SPLAT_MAX < 0
call SPLATS [ SPLAT_MAX ].destroy ( )
endloop
set SPLAT_MAX = 0
endmethod
endstruct
globals
integer SPLAT_MAX = 0
splat array SPLATS
endglobals
//! ========================================================================================================
//! Crater
struct crater
terraindeformation deform
static rect r = Rect ( 0, 0, 0, 0 )
static method RemoveDest takes nothing returns nothing
call RemoveDestructable ( GetHandleDestructable ( GetExpiredTimer ( ) ) )
call ReleaseTimer ( GetExpiredTimer ( ) )
endmethod
static method Destructable takes nothing returns nothing
if GetDestructableTypeId ( GetEnumDestructable ( ) ) == 'B002' then
set TIMER = NewTimer ( )
call SetHandleDestructable ( TIMER, GetEnumDestructable ( ) )
call TimerStart ( TIMER, 5, false, function crater.RemoveDest )
call KillDestructable ( GetEnumDestructable ( ) )
endif
endmethod
static method create takes real x, real y returns crater
local crater c = crater.allocate ( )
if not IsPointInRegion ( CRATER_REG, x, y ) and GetPointZ ( x, y ) > -256.00 then
set c.deform = TerrainDeformCrater ( x, y, CRATER_RADIUS, CRATER_DEPTH, 0, true )
call SetRect ( c.r, x-CRATER_RADIUS, y-CRATER_RADIUS, x+CRATER_RADIUS, y+CRATER_RADIUS )
call EnumDestructablesInRect ( c.r, TrueExpr, function crater.Destructable )
endif
set CRATER_ALL [ CRATER_N ] = c
set CRATER_N = CRATER_N + 1
return c
endmethod
method onDestroy takes nothing returns nothing
call TerrainDeformStop ( .deform, 0 )
endmethod
static method RemoveAll takes nothing returns nothing
loop
set CRATER_N = CRATER_N - 1
exitwhen CRATER_N < 0
call CRATER_ALL [ CRATER_N ].destroy ( )
endloop
set CRATER_N = 0
endmethod
static method onInit takes nothing returns nothing
set CRATER_REG = CreateRegion ( )
call RegionAddRect ( CRATER_REG, gg_rct_Player1Small )
call RegionAddRect ( CRATER_REG, gg_rct_Player2Small )
endmethod
endstruct
globals
region CRATER_REG
crater array CRATER_ALL
integer CRATER_N = 0
endglobals
//! ========================================================================================================
//! Terrain bumps
struct terrain
real x
real y
terraindeformation deform
real height
real radius
method setPos takes nothing returns nothing
set .x = GetRandomReal ( MIN_X, MAX_X )
set .y = GetRandomReal ( MIN_Y, MAX_Y )
if TWO_DIMENSIONAL then //! +++ 2D mod +++
set .y = GetRectCenterY ( gg_rct_MapDef )
endif
call tile.apply ( .x, .y )
endmethod
method setHeight takes nothing returns nothing
set .height = GetRandomReal ( MIN_TERRAIN_Z, MAX_TERRAIN_Z )
endmethod
method setRadius takes nothing returns nothing
set .radius = GetRandomReal ( MIN_TERRAIN_RADIUS, MAX_TERRAIN_RADIUS )
endmethod
method start takes nothing returns nothing
set .deform = TerrainDeformCrater ( .x, .y, .radius, -this.height, 0, true )
endmethod
static method create takes nothing returns terrain
local terrain t = terrain.allocate ( )
call t.setPos ( )
call t.setHeight ( )
call t.setRadius ( )
call t.start ( )
set TERRAIN_ALL [ TERRAIN_N ] = t
set TERRAIN_N = TERRAIN_N + 1
return t
endmethod
method onDestroy takes nothing returns nothing
call TerrainDeformStop ( .deform, 0 )
endmethod
static method RemoveAll takes nothing returns nothing
loop
set TERRAIN_N = TERRAIN_N - 1
exitwhen TERRAIN_N < 0
call TERRAIN_ALL [ TERRAIN_N ].destroy ( )
endloop
set TERRAIN_N = 0
set decoration.MAX = 0
call splat.RemoveAll ( )
call crater.RemoveAll ( )
call EnumDestructablesInRect ( gg_rct_MapDefAdd, TrueExpr, function decoration.RemoveDecorations )
endmethod
endstruct
globals
terrain array TERRAIN_ALL
integer TERRAIN_N = 0
endglobals
//! ========================================================================================================
//! Main terrain functions
function DestroyTerrain takes nothing returns nothing
//! "Destroys" the terrain in order to generate new one
loop
set TERRAIN_N = TERRAIN_N - 1
exitwhen TERRAIN_N < 0
call TERRAIN_ALL [ TERRAIN_N ].destroy ( )
endloop
endfunction
function Decorations takes nothing returns nothing
//! Generate decorations
call ReleaseTimer ( GetExpiredTimer ( ) )
call decoration.apply ( )
endfunction
function GenerateTerrain takes nothing returns nothing
//! Generates a new map terrain
local integer i = TERRAIN_ITERATOR
if TWO_DIMENSIONAL then //! +++ 2D mod +++
set i = i / DIVIDER_2D
endif
loop
call terrain.create ( )
set i = i - 1
exitwhen i < 0
endloop
//! Need to wait for the terrain to generate before adding decorations
call TimerStart ( NewTimer ( ), 0.05, false, function Decorations)
endfunction
function InitTerrainGenerator takes nothing returns nothing
//! Initializer function - Defines the terrain
//! Define tiles
call tile.define ( 'Arck' ) //! Ashenvale Rocks
//call tile.define ( 'Agrs' ) //! Ashenvale Grass
call tile.define ( 'Vcbp' ) //! Village Cobble Path
call tile.define ( 'Vrck' ) //! Village Rocks
//! Define decorations (destructables)
call decoration.define ( 'B002', 2.00, 4.00 ) //! Generic tree
//call decoration.define ( 'B005', 0.50, 2.00 ) //! Rock
//call decoration.define ( 'B003', 0.50, 0.80 ) //! Grass
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope TerrainRandomizeAbility initializer init
globals
private constant integer ABILITY_ID = 'A008'
endglobals
private function ModTerrain takes nothing returns boolean
if GetSpellAbilityId ( ) == ABILITY_ID then
call terrain.RemoveAll ( )
call GenerateTerrain ( )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function ModTerrain ) )
endfunction
endscope
//TESH.scrollpos=107
//TESH.alwaysfold=0
globals
constant integer TURRET_BASE_ID = 'B000'
constant integer TURRET_HUT_ID = 'h000'
constant integer TURRET_BARREL_ID = 'h001'
constant integer TURRET_TARGET_ID = 'B006'
constant integer TURRET_FLAG_POLE_ID = 'B001'
constant integer TURRET_FLAG_ID = 'h002'
constant integer TURRET_SMOKE_ID = 'h005'
constant real CANNON_SIZE = 315.00 //! Collision size for projectiles
constant real START_Z_ANGLE = 15.00 //! Starting Z angle
constant real FLAG_OFFSET = 512.00 //! Wind/player flag placement distance
constant real FLAG_ANGLE_OFFSET = 115.00 //! Wind/player flag placement angle
unit array TURRET_HUT //! The Base cannon unit
unit array TURRET_BARREL //! The turret unit
unit array TURRET_FLAG //! Flag model unit
unit SMOKE = null //! Smoke dummy
real array ANGLE //! Current X/Y angle of the turrets
real array Z_ANGLE //! Current Z angle of the turrets
real array POWER //! Current power of the turrets
point array POINT_START //! Projectile start point
point array POINT_AIM //! Projectile aiming point
destructable array TURRET_BASE
destructable array TURRET_TARGET
destructable POINTER = null
boolean array SHOW_POINTER
constant integer POINTER_ID_RED = 'B004' //! Red pointer destructable
constant integer POINTER_ID_BLU = 'B003' //! Blue pointer destructable
constant real POINTER_DISTANCE = 1000 //! Pointer origin offset distance
endglobals
function UpdateAimPoint takes integer playerId returns nothing
local real x
local real y
local real z
if SHOW_POINTER [ playerId ] then
call POINT_AIM [ playerId ].moveTo ( POINT_START [ playerId ] )
call POINT_AIM [ playerId ].project ( POINTER_DISTANCE, ( ANGLE [ playerId ] - 180 ) * bj_DEGTORAD, ( Z_ANGLE [ playerId ] - 90 ) * bj_DEGTORAD )
set x = POINT_AIM [ playerId ].x
set y = POINT_AIM [ playerId ].y
set z = POINT_AIM [ playerId ].z
call RemoveDestructable ( POINTER )
if playerId == 0 then
set POINTER = CreateDestructableZ ( POINTER_ID_RED, x, y, z, 0, 5, 0 )
else
set POINTER = CreateDestructableZ ( POINTER_ID_BLU, x, y, z, 0, 5, 0 )
endif
endif
endfunction
function UpdateZAngle takes integer playerId returns nothing
//! Updates the cannon's elevation angle
call SetUnitAnimationByIndex ( TURRET_BARREL [ playerId ] , ModuloInteger ( R2I ( Z_ANGLE [ playerId ] ) / 2, 180 ) )
call UpdateAimPoint ( playerId )
endfunction
function UpdateXYAngle takes integer playerId returns nothing
//! Updates the cannon's facing angle
call SetUnitFacing ( TURRET_HUT [ playerId ], ANGLE [ playerId ] )
call SetUnitFacing ( TURRET_BARREL [ playerId ], ANGLE [ playerId ] )
call UpdateAimPoint ( playerId )
endfunction
function ResetCannons takes nothing returns nothing
//! Returns both cannons back to initial state
call SetUnitVertexColor ( TURRET_HUT [ 0 ], 255, 255, 255, 255 )
call SetUnitVertexColor ( TURRET_BARREL [ 0 ], 255, 255, 255, 255 )
call SetUnitVertexColor ( TURRET_HUT [ 1 ], 255, 255, 255, 255 )
call SetUnitVertexColor ( TURRET_BARREL [ 1 ], 255, 255, 255, 255 )
call ShowDestructable ( TURRET_TARGET [ 0 ], false )
call ShowDestructable ( TURRET_BASE [ 0 ], true )
call ShowDestructable ( TURRET_TARGET [ 1 ], false )
call ShowDestructable ( TURRET_BASE [ 1 ], true )
if SMOKE != null then
call RemoveUnitEx ( SMOKE )
set SMOKE = null
endif
set ANGLE [ 0 ] = 180
set ANGLE [ 1 ] = 0
set Z_ANGLE [ 0 ] = START_Z_ANGLE
set Z_ANGLE [ 1 ] = START_Z_ANGLE
call UpdateXYAngle ( 0 )
call UpdateXYAngle ( 1 )
call UpdateZAngle ( 0 )
call UpdateZAngle ( 1 )
if PRACTICE_MODE then
if CURRENT_PLAYER == 0 then
call ShowDestructable ( TURRET_TARGET [ 0 ], true )
call ShowDestructable ( TURRET_BASE [ 1 ], false )
call SetUnitVertexColor ( TURRET_HUT [ 1 ], 255, 255, 255, 0 )
call SetUnitVertexColor ( TURRET_BARREL [ 1 ], 255, 255, 255, 0 )
else
call ShowDestructable ( TURRET_TARGET [ 1 ], true )
call ShowDestructable ( TURRET_BASE [ 0 ], false )
call SetUnitVertexColor ( TURRET_HUT [ 0 ], 255, 255, 255, 0 )
call SetUnitVertexColor ( TURRET_BARREL [ 0 ], 255, 255, 255, 0 )
endif
endif
endfunction
function RemovePointer takes nothing returns nothing
//! Does what it says
call RemoveDestructable ( POINTER )
endfunction
function DestroyTurret takes integer playerId returns nothing
//! This one as well
call SetUnitVertexColor ( TURRET_HUT [ playerId ], 20, 20, 20, 255 )
call SetUnitVertexColor ( TURRET_BARREL [ playerId ], 20, 20, 20, 255 )
set SMOKE = CreateUnit ( Player ( 14 ), TURRET_SMOKE_ID, GetUnitX ( TURRET_HUT [ playerId ] ), GetUnitY ( TURRET_HUT [ playerId ] ), 0 )
endfunction
function CreateCannons takes nothing returns nothing
//! Main cannon initializer
local real x1 = GetRectCenterX ( gg_rct_Player1 )
local real y1 = GetRectCenterY ( gg_rct_Player1 )
local real x2 = GetRectCenterX ( gg_rct_Player2 )
local real y2 = GetRectCenterY ( gg_rct_Player2 )
set TURRET_BASE [ 0 ] = CreateDestructable ( TURRET_BASE_ID, x1, y1, 270, 1.00, 0 )
set TURRET_BASE [ 1 ] = CreateDestructable ( TURRET_BASE_ID, x2, y2, 270, 1.00, 0 )
set TURRET_TARGET [ 1 ] = CreateDestructable ( TURRET_TARGET_ID, x1, y1, 270, 1.00, 0 )
set TURRET_TARGET [ 0 ] = CreateDestructable ( TURRET_TARGET_ID, x2, y2, 270, 1.00, 0 )
call ShowDestructable ( TURRET_TARGET [ 1 ], false )
call ShowDestructable ( TURRET_TARGET [ 0 ], false )
set SHOW_POINTER [ 0 ] = true
set SHOW_POINTER [ 1 ] = true
set ANGLE [ 0 ] = AngleBetween ( x1, y1, x2, y2 )
set ANGLE [ 1 ] = AngleBetween ( x2, y2, x1, y1 )
set Z_ANGLE [ 0 ] = START_Z_ANGLE
set Z_ANGLE [ 1 ] = START_Z_ANGLE
set TURRET_HUT [ 0 ] = CreateUnit ( Player( 0 ), TURRET_HUT_ID, x1, y1, ANGLE [ 0 ] )
set TURRET_HUT [ 1 ] = CreateUnit ( Player( 1 ), TURRET_HUT_ID, x2, y2, ANGLE [ 1 ] )
set TURRET_BARREL [ 0 ] = CreateUnit ( Player( 0 ), TURRET_BARREL_ID, x1, y1, ANGLE [ 0 ] )
set TURRET_BARREL [ 1 ] = CreateUnit ( Player( 1 ), TURRET_BARREL_ID, x2, y2, ANGLE [ 1 ] )
call SetUnitAnimationByIndex ( TURRET_BARREL [ 0 ] , R2I ( Z_ANGLE [ 0 ] ) / 2 )
call SetUnitAnimationByIndex ( TURRET_BARREL [ 1 ] , R2I ( Z_ANGLE [ 1 ] ) / 2 )
call CreateDestructable ( TURRET_FLAG_POLE_ID, ProjectX ( x1, FLAG_OFFSET, ANGLE [ 0 ] + FLAG_ANGLE_OFFSET ), ProjectY ( y1, FLAG_OFFSET, ANGLE [ 0 ] + FLAG_ANGLE_OFFSET ), 270, 1.00, 0 )
call CreateDestructable ( TURRET_FLAG_POLE_ID, ProjectX ( x2, FLAG_OFFSET, ANGLE [ 1 ] + FLAG_ANGLE_OFFSET ), ProjectY ( y2, FLAG_OFFSET, ANGLE [ 1 ] + FLAG_ANGLE_OFFSET ), 270, 1.00, 0 )
set TURRET_FLAG [ 0 ] = CreateUnit ( Player ( 0 ), TURRET_FLAG_ID, ProjectX ( x1, FLAG_OFFSET, ANGLE [ 0 ] + FLAG_ANGLE_OFFSET ), ProjectY ( y1, FLAG_OFFSET, ANGLE [ 0 ] + FLAG_ANGLE_OFFSET ), 270 )
set TURRET_FLAG [ 1 ] = CreateUnit ( Player ( 1 ), TURRET_FLAG_ID, ProjectX ( x2, FLAG_OFFSET, ANGLE [ 1 ] + FLAG_ANGLE_OFFSET ), ProjectY ( y2, FLAG_OFFSET, ANGLE [ 1 ] + FLAG_ANGLE_OFFSET ), 270 )
set POINT_START [ 0 ] = point.create ( x1, y1, 155 )
set POINT_START [ 1 ] = point.create ( x2, y2, 155 )
set POINT_AIM [ 0 ] = point.create ( x1, y1, 155 )
set POINT_AIM [ 1 ] = point.create ( x2, y2, 155 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Health requires MathAPI
globals
constant real MAX_HP = 100.00 //! Maximum hit points
real array HIT_POINTS //! Current hit points
endglobals
function DamageCannon takes integer playerId, real amount returns nothing
//! Cannon damage function
set HIT_POINTS [ playerId ] = HIT_POINTS [ playerId ] - amount
if HIT_POINTS [ playerId ] < 0 then
set HIT_POINTS [ playerId ] = 0
endif
call UpdateHealthBar.execute ( playerId )
if HIT_POINTS [ playerId ] <= 0 then
//! Cannon destroyed
call DestroyTurret.execute ( playerId )
//! End round
call EndTurn.execute ( )
endif
endfunction
function ResetHealth takes nothing returns nothing
set HIT_POINTS [ 0 ] = MAX_HP
set HIT_POINTS [ 1 ] = MAX_HP
call UpdateHealthBar.execute ( 0 )
call UpdateHealthBar.execute ( 1 )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Strength requires MathAPI
globals
constant real MAX_POWER = 120.00
constant real MIN_POWER = 20.00
private constant real DEFAULT = 55.00
endglobals
function AddPower takes integer playerId, real amount returns nothing
set POWER [ playerId ] = POWER [ playerId ] + amount
if POWER [ playerId ] < MIN_POWER then
set POWER [ playerId ] = MIN_POWER
elseif POWER [ playerId ] > MAX_POWER then
set POWER [ playerId ] = MAX_POWER
endif
call UpdatePowerBar.execute ( playerId )
endfunction
function InitPower takes nothing returns nothing
set POWER [ 0 ] = DEFAULT
set POWER [ 1 ] = DEFAULT
endfunction
endlibrary
//TESH.scrollpos=447
//TESH.alwaysfold=0
globals
constant real BOARD_MAX_WIDTH = 0.700
constant string BOARD_NAME = " "
constant real BOARD_BAR_WIDTH = 0.01
constant integer BOARD_BAR_COUNT = 20
constant string BOARD_HEALTH = "Multiboard\\Icons\\Health.tga"
constant string BOARD_POWER = "Multiboard\\Icons\\Power.tga"
constant string BOARD_HEALTH_BAR = "Multiboard\\Icons\\HealthBarFull.tga"
constant string BOARD_POWER_BAR = "Multiboard\\Icons\\PowerBarFull.tga"
constant string BOARD_WIND_BAR = "Multiboard\\Icons\\WindBarFull.tga"
constant string BOARD_EMPTY_BAR = "Multiboard\\Icons\\EmptyBar.tga"
constant string BOARD_FLAG_RED = "Multiboard\\Icons\\Player1Flag.tga"
constant string BOARD_FLAG_BLUE = "Multiboard\\Icons\\Player2Flag.tga"
constant string BOARD_FLAG_END = "Multiboard\\Icons\\FlagEnd.tga"
constant string BOARD_AMMO_ICON = "ReplaceableTextures\\CommandButtons\\BTNGolemStormBolt.blp"
constant integer ARRAY_SIZE = BOARD_BAR_COUNT + 1
multiboard BOARD
multiboarditem array HEALTH_BAR [ ARRAY_SIZE ] [ 2 ]
multiboarditem array POWER_BAR [ ARRAY_SIZE ] [ 2 ]
multiboarditem array WIND_BAR [ ARRAY_SIZE ]
multiboarditem CAMERA_NAME
multiboarditem BOARD_TIMER
multiboarditem BOARD_AMMO
endglobals
function MultiboardExecute takes nothing returns nothing
local integer i
local integer add
local real TotalWidth = 0 //! Counting the total width of the created multiboard
local real kkk
local multiboarditem itm //! For non-manipulate items
local real rest
call ReleaseTimer ( GetExpiredTimer ( ) )
set BOARD = CreateMultiboard ( )
call MultiboardSetTitleText ( BOARD, BOARD_NAME )
call MultiboardSetColumnCount ( BOARD, ( BOARD_BAR_COUNT * 3 ) + 10 )
call MultiboardSetRowCount ( BOARD, 4 )
call MultiboardSetItemsStyle ( BOARD, true, false )
//!************************************************************
//! Player 2 (1)'s bars
//!
set add = 0
set i = 0
loop
set HEALTH_BAR [ i ] [ 1 ] = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemStyle ( HEALTH_BAR [ i ] [ 1 ], false, true )
call MultiboardSetItemWidth ( HEALTH_BAR [ i ] [ 1 ], BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( HEALTH_BAR [ i ] [ 1 ], BOARD_HEALTH_BAR )
set POWER_BAR [ i ] [ 1 ] = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemStyle ( POWER_BAR [ i ] [ 1 ], false, true )
call MultiboardSetItemWidth ( POWER_BAR [ i ] [ 1 ], BOARD_BAR_WIDTH )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i + 1
exitwhen i >= BOARD_BAR_COUNT
endloop
//! Empty Space
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i + 1
//! Player 2 Bar Icons
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_HEALTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_POWER )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set i = i + 1
//! Empty Space
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i + 1
//! Player 2 Flag
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_FLAG_BLUE )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_FLAG_END )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
//!************************************************************
//! Player 1 (0)'s bars
//!
set add = MultiboardGetColumnCount ( BOARD ) - BOARD_BAR_COUNT
set i = 0
loop
set HEALTH_BAR [ i ] [ 0 ] = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemStyle ( HEALTH_BAR [ i ] [ 0 ], false, true )
call MultiboardSetItemWidth ( HEALTH_BAR [ i ] [ 0 ], BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( HEALTH_BAR [ i ] [ 0 ], BOARD_HEALTH_BAR )
set POWER_BAR [ i ] [ 0 ] = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemStyle ( POWER_BAR [ i ] [ 0 ], false, true )
call MultiboardSetItemWidth ( POWER_BAR [ i ] [ 0 ], BOARD_BAR_WIDTH )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i + 1
exitwhen i >= BOARD_BAR_COUNT
endloop
set add = add - 1
set i = 0
//! Empty Space
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i - 1
//! Player 1 Bar Icons
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_HEALTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_POWER )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set i = i - 1
//! Empty Space
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i - 1
//! Player 1 Flag
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_FLAG_RED )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemIcon ( itm, BOARD_FLAG_END )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set kkk = TotalWidth
//!************************************************************
//! Wind bar
//!
set add = ( MultiboardGetColumnCount ( BOARD ) / 2 ) - ( BOARD_BAR_COUNT / 2 )
set i = 0
loop
set WIND_BAR [ i ] = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemStyle ( WIND_BAR [ i ], false, true )
call MultiboardSetItemWidth ( WIND_BAR [ i ], BOARD_BAR_WIDTH )
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, ( ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 ) / BOARD_BAR_COUNT )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, ( ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 ) / BOARD_BAR_COUNT )
call MultiboardReleaseItem ( itm )
set kkk = kkk + ( ( ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 ) / BOARD_BAR_COUNT )
set TotalWidth = TotalWidth + BOARD_BAR_WIDTH
set i = i + 1
exitwhen i >= BOARD_BAR_COUNT
endloop
set kkk = kkk - ( ( ( ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 ) / BOARD_BAR_COUNT ) * 2 )
//! Camera name
set itm = MultiboardGetItem ( BOARD, 0, add )
call MultiboardSetItemStyle ( itm, true, false )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemValue ( itm, "<" )
call MultiboardReleaseItem ( itm )
set kkk = kkk + BOARD_BAR_WIDTH
set itm = MultiboardGetItem ( BOARD, 0, add + i - 1 )
call MultiboardSetItemStyle ( itm, true, false )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardSetItemValue ( itm, ">" )
call MultiboardReleaseItem ( itm )
set kkk = kkk + BOARD_BAR_WIDTH
set CAMERA_NAME = MultiboardGetItem ( BOARD, 0, add + ( BOARD_BAR_COUNT / 2 ) + 5 )
call MultiboardSetItemStyle ( CAMERA_NAME, true, false )
call MultiboardSetItemWidth ( CAMERA_NAME, ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 )
set kkk = kkk + ( ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 )
//! Board Ammo
set itm = MultiboardGetItem ( BOARD, 2, ( MultiboardGetColumnCount ( BOARD ) / 2 ) - 1 )
call MultiboardSetItemStyle ( itm, false, true )
call MultiboardSetItemIcon ( itm, BOARD_AMMO_ICON )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, ( MultiboardGetColumnCount ( BOARD ) / 2 ) )
call MultiboardSetItemStyle ( itm, true, false )
call MultiboardSetItemValue ( itm, "x" )
call MultiboardReleaseItem ( itm )
set BOARD_AMMO = MultiboardGetItem ( BOARD, 2, ( MultiboardGetColumnCount ( BOARD ) / 2 ) + 1 )
call MultiboardSetItemStyle ( BOARD_AMMO, true, false )
//! Board Timer
set itm = MultiboardGetItem ( BOARD, 3, add )
call MultiboardSetItemWidth ( itm, BOARD_BAR_WIDTH )
call MultiboardReleaseItem ( itm )
set BOARD_TIMER = MultiboardGetItem ( BOARD, 3, add + ( BOARD_BAR_COUNT / 2 ) + 6 )
call MultiboardSetItemStyle ( BOARD_TIMER, true, false )
call MultiboardSetItemWidth ( BOARD_TIMER, ( BOARD_BAR_WIDTH * BOARD_BAR_COUNT ) / 2 )
call MultiboardSetItemValueColor ( BOARD_TIMER, 255, 255, 0, 255 )
call MultiboardSetItemValue ( BOARD_TIMER, "- : --" )
set rest = ( BOARD_MAX_WIDTH - TotalWidth ) / 2
//! Empty Space
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, ( BOARD_MAX_WIDTH - kkk ) / 2 )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
set add = add - 1
set i = 0
//! Empty Space
set itm = MultiboardGetItem ( BOARD, 0, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 1, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 2, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
set itm = MultiboardGetItem ( BOARD, 3, i+add )
call MultiboardSetItemWidth ( itm, rest )
call MultiboardReleaseItem ( itm )
call MultiboardDisplay ( BOARD, true )
call MultiboardMinimize ( BOARD, false )
call UpdatePowerBar.execute ( 0 )
call UpdatePowerBar.execute ( 1 )
call UpdateWindBar.execute ( )
call UpdateCameraName.execute ( )
set itm = null
endfunction
function UpdateHealthBar takes integer playerId returns nothing
local integer i = 0
local real p = GetValuePercent ( MAX_HP, HIT_POINTS [ playerId ] )
local integer t = R2I ( PercentOfValue ( BOARD_BAR_COUNT, p ) )
loop
exitwhen i >= t or i >= BOARD_BAR_COUNT
call MultiboardSetItemIcon ( HEALTH_BAR [ i ] [ playerId ], BOARD_HEALTH_BAR )
set i = i + 1
endloop
loop
exitwhen i >= BOARD_BAR_COUNT
call MultiboardSetItemIcon ( HEALTH_BAR [ i ] [ playerId ], BOARD_EMPTY_BAR )
set i = i + 1
endloop
endfunction
function UpdatePowerBar takes integer playerId returns nothing
local integer i = 0
local real p = GetValuePercent ( MAX_POWER, POWER [ playerId ] )
local integer t = R2I ( PercentOfValue ( BOARD_BAR_COUNT, p ) )
loop
exitwhen i >= t or i >= BOARD_BAR_COUNT
call MultiboardSetItemIcon ( POWER_BAR [ i ] [ playerId ], BOARD_POWER_BAR )
set i = i + 1
endloop
loop
exitwhen i >= BOARD_BAR_COUNT
call MultiboardSetItemIcon ( POWER_BAR [ i ] [ playerId ], BOARD_EMPTY_BAR )
set i = i + 1
endloop
endfunction
function UpdateWindBar takes nothing returns nothing
local integer i = 0
local real p = GetValuePercent ( MAX_WIND, WIND_CURRENT_STRENGTH )
local integer t = R2I ( PercentOfValue ( BOARD_BAR_COUNT, p ) )
loop
exitwhen i >= t or i >= BOARD_BAR_COUNT
call MultiboardSetItemIcon ( WIND_BAR [ i ], BOARD_WIND_BAR )
set i = i + 1
endloop
loop
exitwhen i >= BOARD_BAR_COUNT
call MultiboardSetItemIcon ( WIND_BAR [ i ], BOARD_EMPTY_BAR )
set i = i + 1
endloop
endfunction
function UpdateCameraName takes nothing returns nothing
local string s1 = GetCameraName ( 0 )
local string s2 = GetCameraName ( 1 )
if GetLocalPlayer ( ) == Player ( 1 ) then
set s1 = s2
endif
call MultiboardSetItemValue ( CAMERA_NAME, s1 )
endfunction
function UpdateTimerClock takes nothing returns nothing
local string s = I2S ( MINUTES ) + " : "
if SECONDS > 9 then
set s = s + I2S ( SECONDS )
call MultiboardSetItemValueColor ( BOARD_TIMER, 255, 255, 0, 255 )
else
set s = s + "0" + I2S ( SECONDS )
if MINUTES <= 0 then
call MultiboardSetItemValueColor ( BOARD_TIMER, 255, 50, 50, 255 )
call StartSound ( gg_snd_Tick )
endif
endif
call MultiboardSetItemValue ( BOARD_TIMER, s )
endfunction
function UpdateAmmoDisplay takes nothing returns nothing
if PRACTICE_MODE then
call MultiboardSetItemValue ( BOARD_AMMO, "-" )
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_FOOD_USED, 0 )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_FOOD_USED, 0 )
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_FOOD_CAP, 0 )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_FOOD_CAP, 0 )
else
call MultiboardSetItemValue ( BOARD_AMMO, I2S ( PROJECTILES [ CURRENT_PLAYER ] ) )
if IS_SINGLE_PLAYER then
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_FOOD_USED, PROJECTILES [ CURRENT_PLAYER ] )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_FOOD_USED, PROJECTILES [ CURRENT_PLAYER ] )
else
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_FOOD_USED, PROJECTILES [ 0 ] )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_FOOD_USED, PROJECTILES [ 1 ] )
endif
call SetPlayerState ( Player ( 0 ), PLAYER_STATE_RESOURCE_FOOD_CAP, PROJECTILES_MAX )
call SetPlayerState ( Player ( 1 ), PLAYER_STATE_RESOURCE_FOOD_CAP, PROJECTILES_MAX )
endif
endfunction
function MultiboardMaximize takes nothing returns nothing
call MultiboardMinimize ( BOARD, false )
endfunction
function MultiboardSetup takes nothing returns nothing
call TimerStart ( NewTimer ( ), 0.1, false, function MultiboardExecute )
call TimerStart ( CreateTimer ( ), 0.1, true, function MultiboardMaximize )
endfunction
//TESH.scrollpos=6
//TESH.alwaysfold=0
globals
constant integer ROUND_TIME_MINUTES = 1
constant integer ROUND_TIME_SECONDS = 1
integer SECONDS
integer MINUTES
timer DUMMY_TIMER
endglobals
function TimerUpdate takes nothing returns nothing
set SECONDS = SECONDS - 1
if SECONDS < 0 then
if MINUTES == 0 then
set MINUTES = 0
set SECONDS = 0
call PauseTimer ( DUMMY_TIMER )
//! End round
call EndTurn.execute ( )
return
else
set MINUTES = MINUTES - 1
set SECONDS = SECONDS + 60
endif
endif
call UpdateTimerClock.execute ( )
endfunction
function ResetTimer takes nothing returns nothing
set MINUTES = ROUND_TIME_MINUTES
set SECONDS = ROUND_TIME_SECONDS
endfunction
function PauseRoundTimer takes nothing returns nothing
//! Pauses the round timer
call PauseTimer ( DUMMY_TIMER )
endfunction
function ResumeRoundTimer takes nothing returns nothing
//! Resumes the round timer
call TimerStart ( DUMMY_TIMER, 1.00, true, function TimerUpdate )
endfunction
function StartRoundTimer takes nothing returns nothing
//! Resets and starts the round timer
call ResetTimer ( )
call TimerStart ( DUMMY_TIMER, 1.00, true, function TimerUpdate )
endfunction
function InitRoundTimer takes nothing returns nothing
set DUMMY_TIMER = CreateTimer ( )
endfunction
//TESH.scrollpos=151
//TESH.alwaysfold=0
library Camera requires CameraAPI
globals
integer array CURRENT_CAMERA //! Current camera id
cameraset array CAMERAS //! All available camera objects
private integer MAX = 0 //! Max amount of camera objects
private unit middle //! Dummy unit
endglobals
struct cameraset
real distance = bj_CAMERA_DEFAULT_DISTANCE
real height = 0
real angle = bj_CAMERA_DEFAULT_AOA
real farz = bj_CAMERA_DEFAULT_FARZ
real fov = bj_CAMERA_DEFAULT_FOV
real rotation = bj_CAMERA_DEFAULT_ROTATION
real roll = bj_CAMERA_DEFAULT_ROLL
unit attach = null
string name
static method create takes string name returns cameraset
//! Defines a new cameraset to be used by the players
local cameraset c = cameraset.allocate ( )
set c.name = name
set CAMERAS [ MAX ] = c
set MAX = MAX + 1
return c
endmethod
method apply takes integer playerId returns nothing
//! Applies the cameraset to a player
local real minX = GetRectMinX ( gg_rct_WorldBounds )
local real minY = GetRectMinY ( gg_rct_WorldBounds )
local real maxX = GetRectMaxX ( gg_rct_WorldBounds )
local real maxY = GetRectMaxY ( gg_rct_WorldBounds )
call SetCameraControllerField ( playerId, CAMERA_FIELD_TARGET_DISTANCE, .distance )
call SetCameraControllerField ( playerId, CAMERA_FIELD_ZOFFSET, .height )
call SetCameraControllerField ( playerId, CAMERA_FIELD_ANGLE_OF_ATTACK, .angle )
call SetCameraControllerField ( playerId, CAMERA_FIELD_FARZ, .farz )
call SetCameraControllerField ( playerId, CAMERA_FIELD_FIELD_OF_VIEW, .fov )
call SetCameraControllerField ( playerId, CAMERA_FIELD_ROTATION, .rotation )
call SetCameraControllerField ( playerId, CAMERA_FIELD_ROLL, .roll )
if .attach != null then
set minX = GetUnitX ( .attach )
set minY = GetUnitY ( .attach )
set maxX = GetUnitX ( .attach )
set maxY = GetUnitY ( .attach )
endif
if GetLocalPlayer ( ) == Player ( playerId ) then
call SetCameraBounds ( minX, minY, minX, maxY, maxX, maxY, maxX, minY )
endif
endmethod
method SetCamera takes integer playerId returns nothing
call .apply ( playerId )
set CURRENT_CAMERA [ playerId ] = this
endmethod
endstruct
function SetCamera takes integer playerId, integer cameraId returns nothing
//! Applies a sertain camerasetting as the Gameplay Camera
call CAMERAS [ cameraId ].apply ( playerId )
set CURRENT_CAMERA [ playerId ] = cameraId
call UpdateCameraName.execute ( )
endfunction
function GetCameraName takes integer playerId returns string
return CAMERAS [ CURRENT_CAMERA [ playerId ] ].name
endfunction
function SetNextCamera takes integer playerId returns nothing
//! Camera cycle - Apply next settings
local integer cam
set cam = CURRENT_CAMERA [ playerId ]
set cam = cam + 1
if cam > MAX - 1 then
set cam = 0
endif
call SetCamera ( playerId, cam )
endfunction
function SetPreviousCamera takes integer playerId returns nothing
//! Camera cycle - Apply previous settings
local integer cam
set cam = CURRENT_CAMERA [ playerId ]
set cam = cam - 1
if cam < 0 then
set cam = MAX - 1
endif
call SetCamera ( playerId, cam )
endfunction
function ReturnCamera takes integer playerId returns nothing
//! Returns camera to the latest setting
call SetCamera ( playerId, CURRENT_CAMERA [ playerId ] )
endfunction
function ReleaseCamera takes integer playerId returns nothing
//! Releases the cameras locked position
local real minX = GetRectMinX ( gg_rct_WorldBounds )
local real minY = GetRectMinY ( gg_rct_WorldBounds )
local real maxX = GetRectMaxX ( gg_rct_WorldBounds )
local real maxY = GetRectMaxY ( gg_rct_WorldBounds )
if GetLocalPlayer ( ) == Player ( playerId ) then
call SetCameraBounds ( minX, minY, minX, maxY, maxX, maxY, maxX, minY )
endif
endfunction
function InitCameraSettings takes nothing returns nothing
//! Initializer function
local cameraset c
call EnableCameraController ( true )
call SetCameraControllerSmoothing ( 0, 0.25 )
call SetCameraControllerSmoothing ( 1, 0.25 )
set middle = CreateUnit ( Player ( 14 ), 'hdum', GetRectCenterX ( gg_rct_MapDef ), GetRectCenterY ( gg_rct_MapDef ), 0 )
//!======================================================================
//! Generic sideview camera
set c = cameraset.create ( "Sideview" )
set c.distance = 8000
set c.rotation = 90
set c.angle = 0
set c.height = 1500
set c.farz = 10000
set c.attach = middle
//!======================================================================
//! Generic top-down camera
set c = cameraset.create ( "Overview" )
set c.distance = 8000
set c.rotation = 90
set c.angle = 300
set c.height = 500
set c.farz = 10000
set c.attach = middle
//!======================================================================
//! Player 1 overview camera
set c = cameraset.create ( "Player 1 overview" )
set c.distance = 8000
set c.rotation = 135
set c.angle = 300
set c.height = 0
set c.farz = 10000
set c.attach = middle
//!======================================================================
//! Player 1 turret camera
set c = cameraset.create ( "Player 1 cannon" )
set c.distance = 6000
set c.rotation = 180
set c.angle = 0
set c.height = 500
set c.farz = 10000
set c.attach = middle
//!======================================================================
//! Wind direction camera
set c = cameraset.create ( "Wind direction" )
set c.distance = 8000
set c.rotation = 90
set c.angle = 270
set c.height = 0
set c.farz = 9000
set c.attach = middle
//!======================================================================
//! Player 2 overview camera
set c = cameraset.create ( "Player 2 overview" )
set c.distance = 8000
set c.rotation = 45
set c.angle = 300
set c.height = 0
set c.farz = 10000
set c.attach = middle
//!======================================================================
//! Player 2 turret camera
set c = cameraset.create ( "Player 2 cannon" )
set c.distance = 6000
set c.rotation = 0
set c.angle = 0
set c.height = 500
set c.farz = 10000
set c.attach = middle
//!======================================================================
call SetCamera ( 0, 0 )
call SetCamera ( 1, 0 )
call ApplyCameraController ( 0, true )
call ApplyCameraController ( 1, true )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope CameraBrowse initializer init
globals
constant integer NEXT_CAM_ABILITY_ID = 'A003'
constant integer PREV_CAM_ABILITY_ID = 'A005'
private timer DELAY_TIMER = CreateTimer ( )
endglobals
private function Delay takes nothing returns nothing
set ENABLE_OPEN_MENU = true
endfunction
private function BrowseCamera takes nothing returns boolean
local integer i = GetPlayerId ( GetOwningPlayer ( GetTriggerUnit ( ) ) )
local integer id = GetSpellAbilityId ( )
if TWO_DIMENSIONAL then
return false
elseif id == NEXT_CAM_ABILITY_ID then
call SetNextCamera ( i )
set ENABLE_OPEN_MENU = false
call TimerStart ( DELAY_TIMER, 2, false, function Delay )
elseif id == PREV_CAM_ABILITY_ID then
call SetPreviousCamera ( i )
call IssueImmediateOrderById ( GetTriggerUnit(), 852178 )
set ENABLE_OPEN_MENU = false
call TimerStart ( DELAY_TIMER, 2, false, function Delay )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function BrowseCamera ) )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library VectorLib //! Credits to Infrane
globals
private location loc = Location(0.0,0.0)
endglobals
struct vector
real x
real y
real z
static method create takes real x, real y, real z returns vector
local vector v = vector.allocate()
set v.x=x
set v.y=y
set v.z=z
return v
endmethod
method getLength takes nothing returns real
return SquareRoot(.x*.x + .y*.y + .z*.z)
endmethod
static method sum takes vector augend, vector addend returns vector
local vector v = vector.allocate()
set v.x = augend.x+addend.x
set v.y = augend.y+addend.y
set v.z = augend.z+addend.z
return v
endmethod
method add takes vector addend returns nothing
set this.x=this.x+addend.x
set this.y=this.y+addend.y
set this.z=this.z+addend.z
endmethod
static method difference takes vector minuend, vector subtrahend returns vector
local vector v = vector.allocate()
set v.x = minuend.x-subtrahend.x
set v.y = minuend.y-subtrahend.y
set v.z = minuend.z-subtrahend.z
return v
endmethod
method subtract takes vector subtrahend returns nothing
set this.x=this.x-subtrahend.x
set this.y=this.y-subtrahend.y
set this.z=this.z-subtrahend.z
endmethod
method scale takes real factor returns nothing
set this.x=this.x*factor
set this.y=this.y*factor
set this.z=this.z*factor
endmethod
method setLength takes real length returns nothing
local real l = SquareRoot(.x*.x + .y*.y + .z*.z)
if l == 0.0 then
debug call BJDebugMsg("Attempted to set the length of a vector with no length!")
return
endif
set l = length/l
set this.x = this.x*l
set this.y = this.y*l
set this.z = this.z*l
endmethod
static method dotProduct takes vector a, vector b returns real
return (a.x*b.x+a.y*b.y+a.z*b.z)
endmethod
static method crossProduct takes vector a, vector b returns vector
local vector v = vector.allocate()
set v.x = a.y*b.z - a.z*b.y
set v.y = a.z*b.x - a.x*b.z
set v.z = a.x*b.y - a.y*b.x
return v
endmethod
static method projectionVector takes vector projected, vector direction returns vector
local vector v = vector.allocate()
local real l = direction.x*direction.x+direction.y*direction.y+direction.z*direction.z
if l == 0.0 then
call v.destroy()
debug call BJDebugMsg("Attempted to project onto a vector with no length!")
return null
endif
set l = (projected.x*direction.x+projected.y*direction.y+projected.z*direction.z) / l
set v.x = direction.x*l
set v.y = direction.y*l
set v.z = direction.z*l
return v
endmethod
method projectVector takes vector direction returns nothing
local real l = direction.x*direction.x+direction.y*direction.y+direction.z*direction.z
if l == 0.0 then
debug call BJDebugMsg("Attempted to project onto a vector with no length!")
return
endif
set l = (this.x*direction.x+this.y*direction.y+this.z*direction.z) / l
set this.x = direction.x*l
set this.y = direction.y*l
set this.z = direction.z*l
endmethod
static method projectionPlane takes vector projected, vector normal returns vector
local vector v = vector.allocate()
local real l = normal.x*normal.x+normal.y*normal.y+normal.z*normal.z
if l == 0.0 then
call v.destroy()
debug call BJDebugMsg("Attempted to project onto an undefined plane!")
return null
endif
set l = (projected.x*normal.x+projected.y*normal.y+projected.z*normal.z) / l
set v.x = projected.x - normal.x*l
set v.y = projected.y - normal.y*l
set v.z = projected.z - normal.z*l
return v
endmethod
method projectPlane takes vector normal returns nothing
local real l = normal.x*normal.x+normal.y*normal.y+normal.z*normal.z
if l == 0.0 then
debug call BJDebugMsg("Attempted to project onto an undefined plane!")
return
endif
set l = (this.x*normal.x+this.y*normal.y+this.z*normal.z) / l
set this.x = this.x - normal.x*l
set this.y = this.y - normal.y*l
set this.z = this.z - normal.z*l
endmethod
static method getAngle takes vector a, vector b returns real
local real l = SquareRoot(a.x*a.x + a.y*a.y + a.z*a.z)*SquareRoot(b.x*b.x + b.y*b.y + b.z*b.z)
if l == 0 then
debug call BJDebugMsg("Attempted to get angle between vectors with no length!")
return 0.0
endif
return Acos((a.x*b.x+a.y*b.y+a.z*b.z)/l) //angle is returned in radians
endmethod
method rotate takes vector axis, real angle returns nothing //angle is taken in radians
local real xx
local real xy
local real xz
local real yx
local real yy
local real yz
local real zx
local real zy
local real zz
local real al = axis.x*axis.x+axis.y*axis.y+axis.z*axis.z //axis length^2
local real f
local real c = Cos(angle)
local real s = Sin(angle)
if al == 0.0 then
debug call BJDebugMsg("Attempted to project onto a vector with no length!")
return
endif
set f = (this.x*axis.x+this.y*axis.y+this.z*axis.z) / al
set zx = axis.x*f
set zy = axis.y*f
set zz = axis.z*f //axis component of rotated vector
set xx = this.x-zx
set xy = this.y-zy
set xz = this.z-zz //component of vector perpendicular to axis
set al = SquareRoot(al)
set yx = (axis.y*xz - axis.z*xy)/al
set yy = (axis.z*xx - axis.x*xz)/al //y same length as x by using cross product and dividing with axis length
set yz = (axis.x*xy - axis.y*xx)/al //x,y - coordinate system in which we rotate
set this.x=xx*c+yx*s+zx
set this.y=xy*c+yy*s+zy
set this.z=xz*c+yz*s+zz
endmethod
static method createTerrainPoint takes real x, real y returns vector
local vector v = vector.allocate()
call MoveLocation(loc,x,y)
set v.x=x
set v.y=y
set v.z=GetLocationZ(loc)
return v
endmethod
method getTerrainPoint takes real x, real y returns nothing
call MoveLocation(loc,x,y)
set this.x=x
set this.y=y
set this.z=GetLocationZ(loc)
endmethod
static method createTerrainNormal takes real x, real y, real sampleRadius returns vector
local vector v = vector.allocate()
local real z1
local real z2
local real z3
local real z4
call MoveLocation(loc, x-sampleRadius, y)
set z1=GetLocationZ(loc)
call MoveLocation(loc, x+sampleRadius, y)
set z2=GetLocationZ(loc)
call MoveLocation(loc, x, y-sampleRadius)
set z3=GetLocationZ(loc)
call MoveLocation(loc, x, y+sampleRadius)
set z4=GetLocationZ(loc)
set sampleRadius=2*sampleRadius
set v.x = (z1-z2)*sampleRadius
set v.y = (z3-z4)*sampleRadius
set v.z = sampleRadius*sampleRadius
return v
endmethod
method getTerrainNormal takes real x, real y, real sampleRadius returns nothing
local real z1
local real z2
local real z3
local real z4
call MoveLocation(loc, x-sampleRadius, y)
set z1=GetLocationZ(loc)
call MoveLocation(loc, x+sampleRadius, y)
set z2=GetLocationZ(loc)
call MoveLocation(loc, x, y-sampleRadius)
set z3=GetLocationZ(loc)
call MoveLocation(loc, x, y+sampleRadius)
set z4=GetLocationZ(loc)
set sampleRadius=2*sampleRadius
set this.x = (z1-z2)*sampleRadius
set this.y = (z3-z4)*sampleRadius
set this.z = sampleRadius*sampleRadius
endmethod
method getTerrainNormal2D takes real x, real y, real sampleRadius returns nothing
local real z1
local real z2
local real z3
local real z4
call MoveLocation(loc, x-sampleRadius, y)
set z1=GetLocationZ(loc)
call MoveLocation(loc, x+sampleRadius, y)
set z2=GetLocationZ(loc)
call MoveLocation(loc, x, y)
set z3=GetLocationZ(loc)
call MoveLocation(loc, x, y)
set z4=GetLocationZ(loc)
set sampleRadius=2*sampleRadius
set this.x = (z1-z2)*sampleRadius
set this.y = (z3-z4)*sampleRadius
set this.z = sampleRadius*sampleRadius
endmethod
method isInCylinder takes vector cylinderOrigin, vector cylinderHeight, real cylinderRadius returns boolean
local real l
local real x = this.x-cylinderOrigin.x
local real y = this.y-cylinderOrigin.y
local real z = this.z-cylinderOrigin.z
if x*cylinderHeight.x+y*cylinderHeight.y+z*cylinderHeight.z < 0.0 then //point below cylinder
return false
endif
set x = x-cylinderHeight.x
set y = y-cylinderHeight.y
set z = z-cylinderHeight.z
if x*cylinderHeight.x+y*cylinderHeight.y+z*cylinderHeight.z > 0.0 then //point above cylinder
return false
endif
set l = cylinderHeight.x*cylinderHeight.x+cylinderHeight.y*cylinderHeight.y+cylinderHeight.z*cylinderHeight.z
if l == 0.0 then
debug call BJDebugMsg("Cylinder with no height!")
return false
endif
set l = (x*cylinderHeight.x+y*cylinderHeight.y+z*cylinderHeight.z) / l
set x = x - cylinderHeight.x*l
set y = y - cylinderHeight.y*l
set z = z - cylinderHeight.z*l
if x*x+y*y+z*z > cylinderRadius*cylinderRadius then //point outside cylinder
return false
endif
return true
endmethod
method isInCone takes vector coneOrigin, vector coneHeight, real coneRadius returns boolean
local real l
local real x = this.x-coneOrigin.x
local real y = this.y-coneOrigin.y
local real z = this.z-coneOrigin.z
if x*coneHeight.x+y*coneHeight.y+z*coneHeight.z < 0.0 then //point below cone
return false
endif
set l = coneHeight.x*coneHeight.x+coneHeight.y*coneHeight.y+coneHeight.z*coneHeight.z
if l == 0.0 then
debug call BJDebugMsg("cone with no height!")
return false
endif
set l = (x*coneHeight.x+y*coneHeight.y+z*coneHeight.z) / l
set x = x - coneHeight.x*l
set y = y - coneHeight.y*l
set z = z - coneHeight.z*l
if SquareRoot(x*x+y*y+z*z) > coneRadius*(1.0-l) then //point outside cone
return false
endif
return true
endmethod
method isInSphere takes vector sphereOrigin, real sphereRadius returns boolean
if sphereRadius*sphereRadius < ((this.x-sphereOrigin.x)*(this.x-sphereOrigin.x)+(this.y-sphereOrigin.y)*(this.y-sphereOrigin.y)+(this.z-sphereOrigin.z)*(this.z-sphereOrigin.z)) then
return false
endif
return true
endmethod
endstruct
endlibrary
//TESH.scrollpos=239
//TESH.alwaysfold=0
library Projectile requires UnitAPI, VectorLib, RecycleAPI
globals
private constant real PROJECTILE_DAMAGE = 50.00 //! Default projectile damage
private constant real SYSTEM_UPDATE_RATE = 0.015 //! Projectile update cycle time
private constant real GRAVITY_FORCE = -200 //! Gravity
constant integer DUMMY_UNIT_ID = 'h006' //! Projectile dummy unit
constant integer DUMMY_EXP_UNIT_ID = 'e000' //! Projectile hit dummy
projectile PROJECTILE = 0 //! Current active projectile
private vector GRAVITY //! Gravity velocity
private vector WIND //! Wind velocity
private vector HELPER //! Helper vector
private sound array SND //! Grenade ground hit sounds
endglobals
struct projectile
boolean enable = false
boolean bounce = false
boolean resist = false
boolean timed = false
boolean dualdmg= false
boolean divdmg = false
vector pos
vector vel
unit dum
static timer t = CreateTimer ( )
static integer time = 0
static method Countdown takes nothing returns nothing
local projectile p = PROJECTILE
local texttag t
set p.time = p.time - 1
if p.time > 0 then
set t = CreateTextTag ( )
call SetTextTagPos ( t, p.pos.x, p.pos.y, p.pos.z )
call SetTextTagColor ( t, 255, 0, 0, 255 )
call SetTextTagText ( t, I2S ( p.time ), 0.03 )
call SetTextTagPermanent ( t, false )
call SetTextTagLifespan ( t, 1 )
call SetTextTagFadepoint ( t, 0.05 )
call SetTextTagVisibility ( t, true )
set t = null
else
call DamagePoint.execute ( )
set p.enable = false
call ShowUnit ( p.dum, false )
call PauseTimer ( p.t )
endif
endmethod
static method create takes real x, real y, real z returns projectile
local projectile p = projectile.allocate ( )
set p.pos = vector.create ( x, y, z )
set p.vel = vector.create ( 0, 0, 0 )
set p.dum = CreateUnit ( Player ( 14 ), DUMMY_UNIT_ID, x, y, 0 )
call UnitAddAbility ( p.dum, 'Amrf' )
call UnitRemoveAbility ( p.dum, 'Amrf' )
call SetUnitFlyHeight ( p.dum, z, 0 )
call PauseUnit ( p.dum, true )
call ShowUnit ( p.dum, false )
return p
endmethod
method onDestroy takes nothing returns nothing
call RemoveUnit ( .dum )
call .pos.destroy ( )
call .vel.destroy ( )
set .enable = false
endmethod
static method GetWindX takes nothing returns real
return ( ( WIND_CURRENT_STRENGTH * Cos ( WIND_CURRENT_ANGLE * bj_DEGTORAD ) ) * SYSTEM_UPDATE_RATE ) / 10
endmethod
static method GetWindY takes nothing returns real
return ( ( WIND_CURRENT_STRENGTH * Sin ( WIND_CURRENT_ANGLE * bj_DEGTORAD ) ) * SYSTEM_UPDATE_RATE ) / 10
endmethod
method move takes real x, real y, real z returns nothing
set .pos.x = x
set .pos.y = y
set .pos.z = z
call ShowUnit ( .dum, true )
call SetUnitX ( .dum, x )
call SetUnitY ( .dum, y )
call SetUnitFlyHeight ( .dum, z, 0 )
endmethod
static method onLoop takes nothing returns nothing
local real maxx = GetRectMaxX ( gg_rct_ProjectileBounds )
local real minx = GetRectMinX ( gg_rct_ProjectileBounds )
local real maxy = GetRectMaxY ( gg_rct_ProjectileBounds )
local real miny = GetRectMinY ( gg_rct_ProjectileBounds )
local projectile p = PROJECTILE
local vector v
if p != 0 and p.enable then
set WIND.x = p.GetWindX ( )
set WIND.y = p.GetWindY ( )
//! Apply Wind
call p.vel.add ( WIND )
if p.resist then
set p.vel.x = p.vel.x - ( WIND.x * 0.5 )
set p.vel.y = p.vel.y - ( WIND.y * 0.5 )
endif
//! Apply Gravity
call p.vel.add ( GRAVITY )
//! Apply Force
call p.pos.add ( p.vel )
//! Position Z helper
call HELPER.getTerrainPoint ( p.pos.x, p.pos.y )
call SetUnitX ( p.dum, p.pos.x)
call SetUnitY ( p.dum, p.pos.y)
call SetUnitFlyHeight ( p.dum, p.pos.z - HELPER.z, 0 )
if GetPointZ ( p.pos.x, p.pos.y ) >= p.pos.z or (p.pos.x > maxx) or (p.pos.x < minx) or (p.pos.y > maxy) or (p.pos.y < miny) then
//! Projectile ended
if p.bounce and ( GetTerrainType ( p.pos.x, p.pos.y ) != 1666147121 ) then //! 1666147121 == Abyss
//! Bounce projectile
//! Get terrain normal vector
if TWO_DIMENSIONAL then
call HELPER.getTerrainNormal2D ( HELPER.x, HELPER.y, 4.0 )
else
call HELPER.getTerrainNormal ( HELPER.x, HELPER.y, 4.0 )
endif
if not ( vector.dotProduct ( p.vel, HELPER ) > 0 ) then
//! Get the component of speed vector that is perpendicular to the terrain
set v = vector.projectionVector ( p.vel, HELPER )
//! Invert the projectile's speed component that's perpendicular to terrain
call v.scale ( -1.5 )
call p.vel.add ( v )
call v.destroy ( )
if p.vel.z > 5.0 then
call StartSound ( SND [ GetRandomInt ( 0, 2 ) ] )
endif
endif
else
call DamagePoint.execute ( )
set p.enable = false
call ShowUnit ( p.dum, false )
call PauseTimer ( p.t )
endif
endif
endif
endmethod
static method onInit takes nothing returns nothing
//! Initializer
local real x = GetRectCenterX ( gg_rct_MapDef )
local real y = GetRectCenterY ( gg_rct_MapDef )
call TimerStart ( CreateTimer ( ), SYSTEM_UPDATE_RATE, true, function projectile.onLoop )
set GRAVITY = vector.create ( 0.0, 0.0, ( GRAVITY_FORCE * SYSTEM_UPDATE_RATE ) / 2 )
set WIND = vector.create ( 0.0, 0.0, 0.0 )
set HELPER = vector.create ( 0.0, 0.0, 0.0 )
set PROJECTILE = projectile.create ( x, y, 0 )
set SND [ 0 ] = gg_snd_ProjectileHit1
set SND [ 1 ] = gg_snd_ProjectileHit2
set SND [ 2 ] = gg_snd_ProjectileHit3
endmethod
endstruct
function ResetGameplay takes nothing returns nothing
call ReleaseTimer ( GetExpiredTimer ( ) )
call EndChaseCam.execute ( )
call ReturnCamera ( 0 )
call ReturnCamera ( 1 )
endfunction
function DamagePoint takes nothing returns nothing
local projectile p = PROJECTILE
local real r
local real d
local real x = p.pos.x
local real y = p.pos.y
local real z = GetUnitFlyHeight ( p.dum ) //p.pos.z - HELPER.z
local unit u
local real dmg = PROJECTILE_DAMAGE
if TWO_DIMENSIONAL then
//! 2D Mode deals only half the damage
set dmg = dmg / 2
endif
if p.pos.z > -500 then
//! Projectile explosion
if p.pos.z < GetPointZ ( x, y ) + 200 and GetTerrainType ( x, y ) != 1666147121 then //! 1666147121 == Abyss
call splat.new ( x, y )
call crater.create ( x, y )
endif
set u = CreateUnit ( Player ( 14 ), DUMMY_EXP_UNIT_ID, x, y, GetRandomReal ( 0, 360 ) )
call StopSound ( gg_snd_ProjectileHit, false, false )
call StartSound ( gg_snd_ProjectileHit )
call UnitAddAbility ( u, 'Amrf' )
call UnitRemoveAbility ( u, 'Amrf' )
call SetUnitX ( u, x )
call SetUnitY ( u, y )
call SetUnitFlyHeight ( u, z , 0 )
call KillUnit ( u )
set u = null
if not PRACTICE_MODE then
if DistanceBetweenWidgets ( p.dum, TURRET_HUT [ 0 ] ) < CANNON_SIZE and p.pos.z < 200 then
//! Damage player 1 cannon
set d = DistanceBetweenWidgets ( p.dum, TURRET_HUT [ 0 ] )
set r = GetValuePercent ( CANNON_SIZE, d )
call DamageCannon ( 0, dmg - PercentOfValue ( dmg, r ) )
if p.dualdmg then
call DamageCannon ( 0, dmg - PercentOfValue ( dmg, r ) )
elseif p.divdmg then
call DamageCannon ( 0, -( ( dmg - PercentOfValue ( dmg, r ) ) / 2 ) )
endif
call MultiboardDisplay ( BOARD, true )
elseif DistanceBetweenWidgets ( p.dum, TURRET_HUT [ 1 ] ) < CANNON_SIZE and p.pos.z < 200 then
//! Damage player 2 cannon
set d = DistanceBetweenWidgets ( p.dum, TURRET_HUT [ 1 ] )
set r = GetValuePercent ( CANNON_SIZE, d )
call DamageCannon ( 1, dmg - PercentOfValue ( dmg, r ) )
if p.dualdmg then
call DamageCannon ( 1, dmg - PercentOfValue ( dmg, r ) )
elseif p.divdmg then
call DamageCannon ( 1, -( ( dmg - PercentOfValue ( dmg, r ) ) / 2 ) )
endif
call MultiboardDisplay ( BOARD, true )
endif
endif
endif
call TimerStart ( NewTimer(), 2.0, false, function ResetGameplay )
endfunction
function SimulateFireEmitter takes real x, real y, real z, real angle, real zangle returns nothing
local unit u = CreateUnit ( Player ( 14 ), 'e001', x, y, angle )
call UnitAddAbility ( u, 'Amrf' )
call UnitRemoveAbility ( u, 'Amrf' )
call SetUnitX ( u, x )
call SetUnitY ( u, y )
call SetUnitFlyHeight ( u, z , 0 )
call SetUnitAnimationByIndex ( u, ModuloInteger ( R2I ( zangle ), 360 ) / 2 )
call KillUnit ( u )
set u = null
endfunction
function Launch takes integer playerId returns nothing
local projectile p = PROJECTILE
local point to = POINT_START [ playerId ].clone ( )
local point from = POINT_START [ playerId ].clone ( )
call to.project ( POWER [ playerId ], (ANGLE [ playerId ] - 180) * bj_DEGTORAD, (Z_ANGLE [ playerId ] - 90) * bj_DEGTORAD )
call from.project ( 256, (ANGLE [ playerId ] - 180) * bj_DEGTORAD, (Z_ANGLE [ playerId ] - 90) * bj_DEGTORAD )
call p.move ( from.x, from.y, from.z )
set p.vel.x = to.x - POINT_START [ playerId ].x
set p.vel.y = to.y - POINT_START [ playerId ].y
set p.vel.z = to.z - POINT_START [ playerId ].z
call SimulateFireEmitter ( from.x, from.y, from.z, ANGLE [ playerId ], Z_ANGLE [ playerId ] - 90 )
call StopSound ( gg_snd_Attack, false, false )
call StartSound ( gg_snd_Attack )
if p.timed then
set p.time = 3
call TimerStart ( p.t, 0.66, true, function projectile.Countdown )
endif
set p.enable = true
call to.destroy ( )
call from.destroy ( )
endfunction
endlibrary
//TESH.scrollpos=17
//TESH.alwaysfold=0
library WindEffects requires FadeAPI
globals
private constant integer WIND_EFFECT_DUMMY_ID = 'h003' //! Wind effect dummy unit type
private constant real WIND_EFFECT_SPAWN_RATE = 0.20 //! Interval of wind effect spawns
private constant real WIND_EFFECT_DISPLAY = 5.00 //! Display time in seconds
constant real MAX_WIND = 700.00 //! Warcraft units per second
constant real MIN_WIND = 100.00 //! Warcraft units per second
real WIND_CURRENT_ANGLE = 45.00 //! Current wind direction (will be randomized)
real WIND_CURRENT_STRENGTH = 100.00 //! Current wind strength (will be randomized)
unit WIND_ARROW = null //! Arrow model displaying wind direction
endglobals
function SetWind takes real strength, real angle returns nothing
set WIND_CURRENT_ANGLE = angle
set WIND_CURRENT_STRENGTH = strength
call SetUnitFacing ( TURRET_FLAG [ 0 ], angle - 90 )
call SetUnitFacing ( TURRET_FLAG [ 1 ], angle - 90 )
call SetUnitTimeScale ( TURRET_FLAG [ 0 ], strength / 200 )
call SetUnitTimeScale ( TURRET_FLAG [ 1 ], strength / 200 )
if WIND_ARROW == null then
set WIND_ARROW = CreateUnit ( Player ( 14 ), 'h007', GetRectCenterX ( gg_rct_MapDef ), GetRectCenterY ( gg_rct_MapDef ), 0 )
call PauseUnit ( WIND_ARROW, true )
endif
call SetUnitFacing ( WIND_ARROW, angle )
call UpdateWindBar.execute ( )
endfunction
function RandomizeWind takes nothing returns nothing
if TWO_DIMENSIONAL then
if GetRandomInt ( 0, 1 ) == 0 then
call SetWind ( GetRandomReal ( MIN_WIND, MAX_WIND ), 180 )
else
call SetWind ( GetRandomReal ( MIN_WIND, MAX_WIND ), 360 )
endif
else
call SetWind ( GetRandomReal ( MIN_WIND, MAX_WIND ), GetRandomReal ( 0, 360 ) )
endif
call AffectExistingSkies ( )
endfunction
private function CreateWindEffect takes nothing returns nothing
local real x = GetRandomReal ( GetRectMinX ( gg_rct_MapDef ), GetRectMaxX ( gg_rct_MapDef ) )
local real y = GetRandomReal ( GetRectMinY ( gg_rct_MapDef ), GetRectMaxY ( gg_rct_MapDef ) )
local unit u = CreateUnit ( Player ( 14 ), WIND_EFFECT_DUMMY_ID, x, y, WIND_CURRENT_ANGLE )
call SetUnitTimeScale ( u, 3.00 - ( ( 1.00 - GetValuePercent ( MAX_WIND, WIND_CURRENT_STRENGTH ) ) * 3 ) )
call SetUnitFlyHeight ( u, GetPointZ ( x, y ) + 700, 0 )
call TriggerSleepAction ( WIND_EFFECT_DISPLAY )
call RemoveUnitEx ( u )
set u = null
endfunction
function InitWindEffectModels takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerAddAction ( t, function CreateWindEffect )
call TriggerRegisterTimerEvent ( t, WIND_EFFECT_SPAWN_RATE, true )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Skies initializer init requires FadeAPI
globals
private constant integer SKY_DUMMY_ID = 'h004' //! Wind effect dummy unit type
private constant real SKY_SPAWN_RATE = 10.00 //! Interval of wind effect spawns
private constant real SKY_DISPLAY = 60.00 //! Display time in seconds
private constant integer SKY_ALPHA = 127 //! Skies vertex alpha value
endglobals
function AffectExistingSkies takes nothing returns nothing
//! Makes all existing skies move in the direction of the current wind
local group g = NewGroup ( )
local unit u
call GroupEnumUnitsOfPlayer ( g, Player ( 13 ), TrueExpr )
loop
set u = FirstOfGroup ( g )
exitwhen u == null
call GroupRemoveUnit ( g, u )
call FadeUnitPosition ( u, ProjectX ( GetUnitX ( u ), 7000, WIND_CURRENT_ANGLE ), ProjectY ( GetUnitY ( u ), 7000, WIND_CURRENT_ANGLE ), GetUnitFlyHeight ( u ), SKY_DISPLAY )
endloop
call ReleaseGroup ( g )
//! No need to null a static global group
//! The unit variable was nulled in the loop
endfunction
private function CreateSky takes nothing returns nothing
//! ******************************************************************************
//! Skies are hovering over the map and can be seen in a few camera settings.
//! Since version 1.01, these skies are moving the exact direction of the wind
//! ******************************************************************************
//! Randomize locals to get a more random sky pattern
local real r = GetRandomReal ( -2000, 2000 )
local real x = ProjectX ( GetRectCenterX ( gg_rct_MapDef ), 3500, WIND_CURRENT_ANGLE + 180 )
local real y = ProjectY ( GetRectCenterY ( gg_rct_MapDef ), 3500, WIND_CURRENT_ANGLE + 180 )
local real x2 = ProjectX ( x, r, WIND_CURRENT_ANGLE + 90 )
local real y2 = ProjectY ( y, r, WIND_CURRENT_ANGLE + 90 )
local unit u = CreateUnit ( Player ( 13 ), SKY_DUMMY_ID, x2, y2, WIND_CURRENT_ANGLE )
local real scale = GetRandomReal ( 10, 20 )
local real display = SKY_DISPLAY + GetRandomReal ( -15, 15 )
set x = ProjectX ( x2, 7000, WIND_CURRENT_ANGLE )
set y = ProjectY ( y2, 7000, WIND_CURRENT_ANGLE )
//! Start move this sky and fade vertex colors
call PauseUnit ( u, true )
call SetUnitFlyHeight ( u, GetUnitFlyHeight ( u ) + GetRandomReal ( -128, 256 ), 0 )
call SetUnitScale ( u, scale, scale, scale )
call FadeUnitPosition ( u, x, y, GetUnitFlyHeight ( u ), display)
call SetUnitVertexColor ( u, 255, 255, 255, 0)
call SetVertexStartColor ( 255, 255, 255, 0 )
call SetVertexEndColor ( 255, 255, 255, SKY_ALPHA )
call FadeUnitVertexColor ( u, 3 )
//! Wait for the sky to reach the other side of the map
call Wait ( display - 3 )
//! Start fade the sky again
call SetVertexStartColor ( 255, 255, 255, SKY_ALPHA )
call SetVertexEndColor ( 255, 255, 255, 0 )
call FadeUnitVertexColor ( u, 3 )
//! Wait for the fading to end
call Wait ( 3.5 )
//! The sky has reached the end and is completely transparent -- Remove it
call RemoveUnitEx ( u )
set u = null
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerAddAction ( t, function CreateSky )
call TriggerRegisterTimerEvent ( t, SKY_SPAWN_RATE, true )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope WindRandomizeAbility initializer init
globals
private constant integer ABILITY_ID = 'A007'
endglobals
private function ModWind takes nothing returns boolean
if GetSpellAbilityId ( ) == ABILITY_ID then
call RandomizeWind ( )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function ModWind ) )
endfunction
endscope
//TESH.scrollpos=22
//TESH.alwaysfold=0
library Controller initializer init requires UnitAPI
globals
boolean array CONTROL_ACTIVE
unit array ENABLE_ABILITY_DUM
unit array ENABLE_CAMERA_DUM
endglobals
function ActivatePlayerController takes integer playerId, boolean active returns nothing
//! Activates / deactivates arrow key controllers
set CONTROL_ACTIVE [ playerId ] = active
endfunction
function EnableAbilities takes integer playerId, boolean enable returns nothing
//! Enables / disables dummy abilities
local real x = GetRectCenterX ( gg_rct_MapDef )
local real y = GetRectCenterY ( gg_rct_MapDef )
if enable then
//! Abilities has been enabled, recreate dummy unit if missing
if ENABLE_ABILITY_DUM [ playerId ] == null then
set ENABLE_ABILITY_DUM [ playerId ] = CreateUnit ( PLAYER [ playerId ], 'turn', x, y, 0 )
endif
//! Update weapon abilities
call SwitchToWeapon.execute ( playerId )
else
//! Abilities has been disabled, remove and clear dummy
if ENABLE_ABILITY_DUM [ playerId ] != null then
call RemoveUnitEx ( ENABLE_ABILITY_DUM [ playerId ] )
set ENABLE_ABILITY_DUM [ playerId ] = null
endif
endif
//! Enable/disable player controller
call ActivatePlayerController ( playerId, enable )
endfunction
function EnableCameraCustomize takes boolean enable returns nothing
//! Enables / disables camera browsing abilities
local real x = GetRectCenterX ( gg_rct_MapDef )
local real y = GetRectCenterY ( gg_rct_MapDef )
if enable then
if ENABLE_CAMERA_DUM [ 0 ] == null then
set ENABLE_CAMERA_DUM [ 0 ] = CreateUnit ( Player ( 0 ), 'h00C', x, y, 0 )
set ENABLE_CAMERA_DUM [ 1 ] = CreateUnit ( Player ( 1 ), 'h00C', x, y, 0 )
endif
else
if ENABLE_CAMERA_DUM [ 0 ] != null then
call RemoveUnitEx ( ENABLE_CAMERA_DUM [ 0 ] )
call RemoveUnitEx ( ENABLE_CAMERA_DUM [ 1 ] )
set ENABLE_CAMERA_DUM [ 0 ] = null
endif
endif
endfunction
private function init takes nothing returns nothing
//! Initializer function
set CONTROL_ACTIVE [ 0 ] = false
set CONTROL_ACTIVE [ 1 ] = false
set ENABLE_CAMERA_DUM [ 0 ] = null
set ENABLE_ABILITY_DUM [ 0 ] = null
set ENABLE_ABILITY_DUM [ 1 ] = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library DummyPanel
globals
private constant real UPDATE_CYCLE = 0.05
private constant integer DUMMY_ID = 'h008'
unit array PANELS
endglobals
private function Selection takes nothing returns nothing
//! Constantly selects the dummy units
if GetLocalPlayer ( ) == Player ( 0 ) then
call SelectUnit ( PANELS [ 0 ], true )
else
call SelectUnit ( PANELS [ 1 ], true )
endif
endfunction
function CreateDummyPanels takes nothing returns nothing
//! Initializer - Create dummy panels
local real x = GetRectCenterX ( gg_rct_WorldBounds )
local real y = GetRectCenterY ( gg_rct_WorldBounds )
set PANELS [ 0 ] = CreateUnit ( Player ( 0 ), DUMMY_ID, x, y, 0 )
set PANELS [ 1 ] = CreateUnit ( Player ( 1 ), DUMMY_ID, x, y, 0 )
call TimerStart ( CreateTimer ( ), UPDATE_CYCLE, true, function Selection )
endfunction
endlibrary
//TESH.scrollpos=53
//TESH.alwaysfold=0
scope ArrowKeysHeight initializer init
globals
private constant real HEIGHT_UPDATE_CYCLE = 0.02
private constant real HEIGHT_CHANGE_SPEED = 1.00
constant real MAXIMUM_Z_ANGLE = 90.00
constant real MINIMUM_Z_ANGLE = -5.00
boolean array UP
private timer array TIMER
endglobals
function UpdateHeight takes nothing returns nothing
local integer i = 0
if GetExpiredTimer ( ) == TIMER [ 1 ] then
set i = 1
endif
if not CONTROL_ACTIVE [ i ] then
return
endif
if UP [ i ] then
if FINE_TUNING [ i ] then
set Z_ANGLE [ i ] = Z_ANGLE [ i ] + ( HEIGHT_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set Z_ANGLE [ i ] = Z_ANGLE [ i ] + HEIGHT_CHANGE_SPEED
endif
if Z_ANGLE [ i ] > MAXIMUM_Z_ANGLE then
set Z_ANGLE [ i ] = MAXIMUM_Z_ANGLE
call PauseTimer ( TIMER [ i ] )
endif
else
if FINE_TUNING [ i ] then
set Z_ANGLE [ i ] = Z_ANGLE [ i ] - ( HEIGHT_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set Z_ANGLE [ i ] = Z_ANGLE [ i ] - HEIGHT_CHANGE_SPEED
endif
if Z_ANGLE [ i ] < MINIMUM_Z_ANGLE then
set Z_ANGLE [ i ] = MINIMUM_Z_ANGLE
call PauseTimer ( TIMER [ i ] )
endif
endif
call UpdateZAngle ( i )
endfunction
private function StartArrowKeysZAngle takes nothing returns boolean
local integer i = GetPlayerIdEx ( GetTriggerPlayer ( ) )
if not CONTROL_ACTIVE [ i ] then
return false
endif
if GetTriggerEventId ( ) == EVENT_PLAYER_ARROW_UP_DOWN then
set UP [ i ] = true
if FINE_TUNING [ i ] then
set Z_ANGLE [ i ] = Z_ANGLE [ i ] + ( HEIGHT_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set Z_ANGLE [ i ] = Z_ANGLE [ i ] + HEIGHT_CHANGE_SPEED
endif
if Z_ANGLE [ i ] > MAXIMUM_Z_ANGLE then
set Z_ANGLE [ i ] = MAXIMUM_Z_ANGLE
return false
endif
else
set UP [ i ] = false
if FINE_TUNING [ i ] then
set Z_ANGLE [ i ] = Z_ANGLE [ i ] - ( HEIGHT_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set Z_ANGLE [ i ] = Z_ANGLE [ i ] - HEIGHT_CHANGE_SPEED
endif
if Z_ANGLE [ i ] < MINIMUM_Z_ANGLE then
set Z_ANGLE [ i ] = MINIMUM_Z_ANGLE
return false
endif
endif
call UpdateZAngle ( i )
call TimerStart ( TIMER [ i ], HEIGHT_UPDATE_CYCLE, true, function UpdateHeight )
return false
endfunction
private function EndArrowKeysZAngle takes nothing returns boolean
local integer i = GetPlayerIdEx ( GetTriggerPlayer ( ) )
if GetTriggerEventId ( ) == EVENT_PLAYER_ARROW_UP_UP and UP [ i ] then
call PauseTimer ( TIMER [ i ] )
elseif GetTriggerEventId ( ) == EVENT_PLAYER_ARROW_DOWN_UP and not UP [ i ] then
call PauseTimer ( TIMER [ i ] )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_UP_DOWN )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_DOWN_DOWN )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_UP_DOWN )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_DOWN_DOWN )
call TriggerAddCondition ( t, Condition ( function StartArrowKeysZAngle ) )
set t = CreateTrigger ( )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_UP_UP )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_DOWN_UP )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_UP_UP )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_DOWN_UP )
call TriggerAddCondition ( t, Condition ( function EndArrowKeysZAngle ) )
set TIMER [ 0 ] = CreateTimer ( )
set TIMER [ 1 ] = CreateTimer ( )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ArrowKeysRotation initializer init
globals
private constant real ANGLE_UPDATE_CYCLE = 0.02
private constant real ANGLE_CHANGE_SPEED = 1.00
boolean array LEFT
private timer array TIMER
endglobals
function UpdateRotation takes nothing returns nothing
local integer i = 0
if GetExpiredTimer ( ) == TIMER [ 1 ] then
set i = 1
endif
if not CONTROL_ACTIVE [ i ] or TWO_DIMENSIONAL then
return
endif
//! Ooohh.. Shiny..
if LEFT [ i ] then
if FINE_TUNING [ i ] then
set ANGLE [ i ] = ANGLE [ i ] + ( ANGLE_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set ANGLE [ i ] = ANGLE [ i ] + ANGLE_CHANGE_SPEED
endif
if ANGLE [ i ] > 360 then
set ANGLE [ i ] = ANGLE [ i ] - 360
endif
else
if FINE_TUNING [ i ] then
set ANGLE [ i ] = ANGLE [ i ] - ( ANGLE_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set ANGLE [ i ] = ANGLE [ i ] - ANGLE_CHANGE_SPEED
endif
if ANGLE [ i ] < 0 then
set ANGLE [ i ] = ANGLE [ i ] + 360
endif
endif
call UpdateXYAngle ( i )
endfunction
private function StartArrowKeysXYAngle takes nothing returns boolean
local integer i = GetPlayerIdEx ( GetTriggerPlayer ( ) )
if not CONTROL_ACTIVE [ i ] or TWO_DIMENSIONAL then
return false
endif
if GetTriggerEventId ( ) == EVENT_PLAYER_ARROW_LEFT_DOWN then
set LEFT [ i ] = true
if FINE_TUNING [ i ] then
set ANGLE [ i ] = ANGLE [ i ] + ( ANGLE_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set ANGLE [ i ] = ANGLE [ i ] + ANGLE_CHANGE_SPEED
endif
if ANGLE [ i ] > 360 then
set ANGLE [ i ] = ANGLE [ i ] - 360
endif
else
set LEFT [ i ] = false
if FINE_TUNING [ i ] then
set ANGLE [ i ] = ANGLE [ i ] - ( ANGLE_CHANGE_SPEED / FINE_TUNING_DIVIDE )
else
set ANGLE [ i ] = ANGLE [ i ] - ANGLE_CHANGE_SPEED
endif
if ANGLE [ i ] < 0 then
set ANGLE [ i ] = ANGLE [ i ] + 360
endif
endif
call UpdateXYAngle ( i )
call TimerStart ( TIMER [ i ], ANGLE_UPDATE_CYCLE, true, function UpdateRotation )
return false
endfunction
private function EndArrowKeysXYAngle takes nothing returns boolean
local integer i = GetPlayerIdEx ( GetTriggerPlayer ( ) )
if GetTriggerEventId ( ) == EVENT_PLAYER_ARROW_LEFT_UP and LEFT [ i ] then
call PauseTimer ( TIMER [ i ] )
elseif GetTriggerEventId ( ) == EVENT_PLAYER_ARROW_RIGHT_UP and not LEFT [ i ] then
call PauseTimer ( TIMER [ i ] )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_LEFT_DOWN )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_RIGHT_DOWN )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_LEFT_DOWN )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_RIGHT_DOWN )
call TriggerAddCondition ( t, Condition ( function StartArrowKeysXYAngle ) )
set t = CreateTrigger ( )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_LEFT_UP )
call TriggerRegisterPlayerEvent ( t, Player ( 0 ), EVENT_PLAYER_ARROW_RIGHT_UP )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_LEFT_UP )
call TriggerRegisterPlayerEvent ( t, Player ( 1 ), EVENT_PLAYER_ARROW_RIGHT_UP )
call TriggerAddCondition ( t, Condition ( function EndArrowKeysXYAngle ) )
set TIMER [ 0 ] = CreateTimer ( )
set TIMER [ 1 ] = CreateTimer ( )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope StrengthMod initializer init
globals
private constant integer INCREASE_ABILITY_ID = 'A000'
private constant integer DECREASE_ABILITY_ID = 'A001'
private constant real AMOUNT = 5.00
endglobals
private function ModStrength takes nothing returns boolean
local integer id = GetSpellAbilityId ( )
local integer i = GetPlayerIdEx ( GetOwningPlayer ( GetTriggerUnit ( ) ) )
if id == INCREASE_ABILITY_ID then
call AddPower.execute ( i, AMOUNT )
elseif id == DECREASE_ABILITY_ID then
call AddPower.execute ( i, -AMOUNT )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function ModStrength ) )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope FineTuning initializer init
globals
private constant integer ABILITY_ID = 'A00C'
constant real FINE_TUNING_DIVIDE = 10.00
private constant string MESSAGE_TURN_ON = "Fine Tuning |cff33ff33ON|r"
private constant string MESSAGE_TURN_OFF = "Fine Tuning |cffff3333OFF|r"
boolean array FINE_TUNING
endglobals
private function FineTuningOnOff takes nothing returns boolean
local integer id = GetSpellAbilityId ( )
local integer i = GetPlayerIdEx ( GetOwningPlayer ( GetTriggerUnit ( ) ) )
if id == ABILITY_ID then
set FINE_TUNING [ i ] = not FINE_TUNING [ i ]
if GetLocalPlayer ( ) == GetOwningPlayer ( GetTriggerUnit ( ) ) then
call ClearTextMessages ( )
endif
if FINE_TUNING [ i ] then
call DisplayTimedTextToPlayer ( GetOwningPlayer ( GetTriggerUnit ( ) ), 1, 0, 1, MESSAGE_TURN_ON )
else
call DisplayTimedTextToPlayer ( GetOwningPlayer ( GetTriggerUnit ( ) ), 1, 0, 1, MESSAGE_TURN_OFF )
endif
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function FineTuningOnOff ) )
set FINE_TUNING [ 0 ] = false
set FINE_TUNING [ 1 ] = false
endfunction
endscope
//TESH.scrollpos=40
//TESH.alwaysfold=0
scope FireProjectile initializer init
globals
constant integer PROJECTILES_MAX = 3 //! Amount of projectiles per turn
private constant integer FIRE_ABILITY_ID = 'A006' //! Ability executing the fire trigger
integer array PROJECTILES //! Current amount of projectiles
private timer T = CreateTimer ( ) //! Chase camera timer
boolean CHASE_CAM = false //! Is true when the chase camera is enabled
endglobals
function ResetProjectileCount takes nothing returns nothing
set PROJECTILES [ 0 ] = PROJECTILES_MAX
set PROJECTILES [ 1 ] = PROJECTILES_MAX
endfunction
private function ChaseCam takes nothing returns nothing
call PanCameraToTimed ( PROJECTILE.pos.x, PROJECTILE.pos.y, 0.25 )
call SetCameraControllerField ( 0, CAMERA_FIELD_ZOFFSET, PROJECTILE.pos.z + 900 )
call SetCameraControllerField ( 1, CAMERA_FIELD_ZOFFSET, PROJECTILE.pos.z + 900 )
endfunction
function EndChaseCam takes nothing returns nothing
local integer i = CURRENT_PLAYER
//!*************************************
//! End chasing the projectile
//!
set CHASE_CAM = false
call PauseTimer ( T )
call SetSkyModel ( "Environment\\Sky\\LordaeronSummerSky\\LordaeronSummerSky.mdl" )
call MultiboardDisplay ( BOARD, true )
call ResetToGameCamera ( 30 )
if HIT_POINTS [ 0 ] <= 0 or HIT_POINTS [ 1 ] <= 0 or PROJECTILES [ i ] <= 0 then
//! If a player is dead, or the player is out of ammo, end this round
call EndTurn ( )
else
//! Player has remaining projectiles - Resume game
call EnableAbilities ( i, true )
call EnableCameraCustomize ( true )
if not PRACTICE_MODE then
call ResumeRoundTimer ( )
endif
endif
endfunction
private function FireInTheHole takes nothing returns boolean
local integer i = GetPlayerIdEx ( GetOwningPlayer ( GetTriggerUnit ( ) ) )
if GetSpellAbilityId ( ) == FIRE_ABILITY_ID then
//! Retract projectile variable
if not PRACTICE_MODE then
set PROJECTILES [ i ] = PROJECTILES [ i ] - 1
endif
//! Update multiboard ammo display
call UpdateAmmoDisplay ( )
//! Projectile launched!
call Launch ( i )
//! Pause the round timer
call PauseRoundTimer ( )
//! Temporary disable abilities
call EnableAbilities ( i, false )
call EnableCameraCustomize ( false )
//! Hide multiboard while chasing the projectile
call MultiboardDisplay ( BOARD, false )
//!*************************************
//! Start chasing the projectile
//!
set CHASE_CAM = true
call ReleaseCamera ( 0 )
call ReleaseCamera ( 1 )
if not TWO_DIMENSIONAL then
call SetCameraControllerField ( 0, CAMERA_FIELD_TARGET_DISTANCE, 3000 )
call SetCameraControllerField ( 0, CAMERA_FIELD_ANGLE_OF_ATTACK, 300 )
call SetCameraControllerField ( 1, CAMERA_FIELD_TARGET_DISTANCE, 3000 )
call SetCameraControllerField ( 1, CAMERA_FIELD_ANGLE_OF_ATTACK, 300 )
if i == 0 then
call SetCameraControllerField ( 0, CAMERA_FIELD_ROTATION, 135 )
call SetCameraControllerField ( 1, CAMERA_FIELD_ROTATION, 135 )
else
call SetCameraControllerField ( 0, CAMERA_FIELD_ROTATION, 45 )
call SetCameraControllerField ( 1, CAMERA_FIELD_ROTATION, 45 )
endif
//! Skies will not display in 3D mode - It's just ugly to look at
call SetSkyModel ( "" )
endif
call TimerStart ( T, 0.01, true, function ChaseCam )
//!
//!*************************************
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function FireInTheHole ) )
endfunction
endscope
//TESH.scrollpos=35
//TESH.alwaysfold=0
scope SwitchWeapon initializer init
globals
private constant integer ABILITY_ID = 'A00B'
integer array WEAPON
constant integer WEAPON_MAX = 2
endglobals
function SwitchToWeapon takes integer playerId returns nothing
local integer i = playerId
if IS_SINGLE_PLAYER then
set i = SINGLE_PLAYER_ID
endif
if WEAPON [ playerId ] == 1 then
//! Grenade
set PROJECTILE.bounce = true
set PROJECTILE.timed = true
set PROJECTILE.dualdmg = true
set PROJECTILE.divdmg = false
set PROJECTILE.resist = true
call SetUnitScale ( PROJECTILE.dum, 3.0, 3.0, 3.0 )
call SetUnitVertexColor ( PROJECTILE.dum, 0, 255, 0, 255 )
call UnitRemoveAbility ( PANELS [ i ], 'A00D' )
call UnitRemoveAbility ( PANELS [ i ], 'A00F' )
call UnitAddAbility ( PANELS [ i ], 'A00E' )
elseif WEAPON [ playerId ] == 2 then
//! Small
set PROJECTILE.bounce = false
set PROJECTILE.timed = false
set PROJECTILE.dualdmg = false
set PROJECTILE.divdmg = true
set PROJECTILE.resist = true
call SetUnitScale ( PROJECTILE.dum, 1.5, 1.5, 1.5 )
call SetUnitVertexColor ( PROJECTILE.dum, 255, 255, 255, 255 )
call UnitRemoveAbility ( PANELS [ i ], 'A00E' )
call UnitRemoveAbility ( PANELS [ i ], 'A00D' )
call UnitAddAbility ( PANELS [ i ], 'A00F' )
else
//! Normal
set PROJECTILE.bounce = false
set PROJECTILE.timed = false
set PROJECTILE.dualdmg = false
set PROJECTILE.divdmg = false
set PROJECTILE.resist = false
call SetUnitScale ( PROJECTILE.dum, 3.0, 3.0, 3.0 )
call SetUnitVertexColor ( PROJECTILE.dum, 255, 255, 255, 255 )
call UnitRemoveAbility ( PANELS [ i ], 'A00F' )
call UnitRemoveAbility ( PANELS [ i ], 'A00E' )
call UnitAddAbility ( PANELS [ i ], 'A00D' )
endif
endfunction
private function Switching takes nothing returns boolean
local integer id = GetSpellAbilityId ( )
local integer i = GetPlayerIdEx ( GetOwningPlayer ( GetTriggerUnit ( ) ) )
if id == ABILITY_ID then
set WEAPON [ i ] = WEAPON [ i ] + 1
if WEAPON [ i ] > WEAPON_MAX then
set WEAPON [ i ] = 0
endif
//! Switch weapon type here
call SwitchToWeapon ( i )
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 0 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerRegisterPlayerUnitEvent ( t, Player ( 1 ), EVENT_PLAYER_UNIT_SPELL_CHANNEL, TrueExpr )
call TriggerAddCondition ( t, Condition ( function Switching ) )
set WEAPON [ 0 ] = 0
set WEAPON [ 1 ] = 0
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_PlayerLeft_Actions takes nothing returns nothing
local integer i = GetPlayerId ( GetTriggerPlayer ( ) )
call DisplayTextToPlayer ( GetLocalPlayer ( ), 1, 0, PlayerHexColor ( GetTriggerPlayer ( ) ) + GetPlayerName ( GetTriggerPlayer ( ) ) + "|r has left the game!" )
set IS_SINGLE_PLAYER = true
if i == 0 then
set PLAYER [ 0 ] = Player ( 1 )
else
set PLAYER [ 1 ] = Player ( 0 )
endif
//! Disable abilities
call EnableAbilities ( 0, false )
call EnableAbilities ( 1, false )
//! Remove aiming pointer
call RemovePointer.execute ( )
//! Pause the round timer
call PauseRoundTimer.execute ( )
//! Round not finished, decrease round number
set ROUND_NUMBER = ROUND_NUMBER - 1
//! Restart round as singleplayer
call DisableTrigger ( DIALOG_TRIG )
call NewRound ( )
endfunction
//!===========================================================================
function InitTrig_PlayerLeft takes nothing returns nothing
set gg_trg_PlayerLeft = CreateTrigger ( )
call TriggerRegisterPlayerEvent ( gg_trg_PlayerLeft, Player ( 0 ), EVENT_PLAYER_LEAVE )
call TriggerRegisterPlayerEvent ( gg_trg_PlayerLeft, Player ( 1 ), EVENT_PLAYER_LEAVE )
call TriggerAddAction ( gg_trg_PlayerLeft, function Trig_PlayerLeft_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
YAY! YOU`VE FOUND A EASTER EGG!
MMMMMMMMM MM
MM MM MM MM
MM MM M MMM
MM M MM MM
MM M MMMMM MM
MMMMMMMMMMM MM MM
MM M M MM
MM M MM M MM
MM M M M M M
MM MM MM MMM M M
MM MMM M M MMMMM M
MMMMMM M M M MMM M
M M MM M M M M
M M M M MM MM M MMMMMM
M MMMMM M MM
M M MM
MM MM M
MM MMM MMM MMMM
M M MMM M
M M M M
MM MM M M
M MMM MMMMMMMM M
M M M MM MM MMMMM
M MMMM MM MM M
M M M M M
M M MM M MM
M MMMMMM M MM
M M M
M M MM M
M MMMMM M
M , .7 MM
M M= ~Z?NM MM $MMZ7 I, 8 M === ZN+ MZM = MOM MMN: M
M Z,M, , ,M M M IO=M = M MM :M MM : M Z , : M
M Z M M M M M,+M M M M : M , M
M Z M .MM MZ 8M.Z M: 7, 7 M ,=M IZM M$O~ M : M MM M
MM = M M ? N M
M M
M M
MM M
M M MM M
M MMM M M M MM M
M M MM MMMM M M M
MMMM M MM MM M MM M
M M MM M M M
M M M M M
M M MM M M
MMM M M M
MM MM MMMM MM M
MM MMMM M MMM MMM MM
M M MM M M M M MM
M MMMMMMMMM MMMM M M M MM M
M M MM M M M MM MM MM
MM M MM M MMM M M MM
MMMM MM M MM M MM MM
M MMMM MM M MMMMMMMMMMM
M M MM M M
M M MMMMMMMMMMM MM
MM M M M MM
MMM MM M M
M MMMM MMM
MM MMMM MM MM
MMM M M M MMMM
MMMMMMMMMM MMMMMM
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Preloader initializer init requires UnitAPI
private function init takes nothing returns nothing
local real x = GetRectCenterX ( gg_rct_MapDef )
local real y = GetRectCenterY ( gg_rct_MapDef )
//! Preload units
call RemoveUnitEx ( CreateUnit ( Player ( 3 ), DUMMY_UNIT_ID, x, y, 0 ) )
call RemoveUnitEx ( CreateUnit ( Player ( 3 ), DUMMY_EXP_UNIT_ID, x, y, 0 ) )
call RemoveUnitEx ( CreateUnit ( Player ( 3 ), 'e001', x, y, 0 ) )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Documentation initializer init
//! Adding quest log documentations
private function init takes nothing returns nothing
//! =======================================================
//! CREDITS
local quest q = CreateQuest ( )
call QuestSetTitle ( q, "Credits" )
call QuestSetDescription ( q, "* |cffff2222Punisher_x|r ::: |cffffcc00Metal Tile|r
* |cffff2222Chris.|r ::: |cffffcc00Everwood Tree|r
* |cffff2222Born2Modificate|r ::: |cffffcc00Cloud Model|r
* |cffff2222Anitarf|r ::: |cffffcc00Vector System|r
* |cffff2222Vexorian|r ::: |cffffcc00Bound Sentinel|r
* |cffff2222Ubisoft|r (|cffff2222Rayman|r) ::: |cffffcc00Music|r
* |cffff2222Ray Larabie|r ::: |cffffcc00Font|r
* |cffff2222Sourc[e]x|r (|cffff2222Illidan(evil)x|r) ::: |cffffcc00The rest|r
* |cffff2222PitzerMike, SFilip, PipeDream and Vexorian|r ::: |cffffcc00JassNewGenPack|r
" )
call QuestSetIconPath ( q, "ReplaceableTextures\\CommandButtons\\BTNEngineeringUpgrade.blp" )
call QuestSetDiscovered ( q, true )
call QuestSetEnabled ( q, true )
//! =======================================================
//! ABOUT
set q = CreateQuest ( )
call QuestSetTitle ( q, "About" )
call QuestSetDescription ( q, "
Cannon Commander is a turn-based |cffffcc00WarCraft III|r scenario developed by |cffff3333Sourc[e]x|r (|cffff3333Illidan(evil)x|r) for |cffffcc00The Hive Workshop's Speed Mapping Contest #1|r (|cff3333ffwww.hiveworkshop.com|r).
Cannon Commander has been designed with two players in mind, but is also playable by only one player.
As it's a turn-based game, it is playable for two players on a single computer (Versus Mode) as well.
" )
call QuestSetIconPath ( q, "ReplaceableTextures\\CommandButtons\\BTNEngineeringUpgrade.blp" )
call QuestSetRequired ( q, false )
call QuestSetDiscovered ( q, true )
call QuestSetEnabled ( q, true )
//! =======================================================
//! HOTKEYS
set q = CreateQuest ( )
call QuestSetTitle ( q, "Hotkeys" )
call QuestSetDescription ( q, "|cffff2222HOTKEYS:|r
* General:
- |cffffcc00W|r = |cff6666ffNext Cameraset.|r (3D Mode)
- |cffffcc00X|r = |cff6666ffPrevius Cameraset.|r (3D Mode)
- |cffffcc00Q|r = |cff6666ffIncrease Power.|r
- |cffffcc00Z|r = |cff6666ffDecrease Power.|r
- |cffffcc00E|r = |cff6666ffSwitch Weapontype.|r
- |cffffcc00D|r = |cff6666ffFine Tuning On/Off.|r
- |cffffcc00F|r = |cff6666ffFire Cannon.|r
- |cffffcc00UP|r = |cff6666ffIncrease cannon elevation angle.|r
- |cffffcc00DOWN|r = |cff6666ffDecrease cannon elevation angle.|r
- |cffffcc00LEFT|r = |cff6666ffRotate cannon left.|r (3D mode)
- |cffffcc00RIGHT|r = |cff6666ffRotate cannon right.|r (3D Mode)
* Multiplayer:
- |cffffcc00ESC|r = |cff6666ffOpen the request dialog.|r
* Singleplayer:
- |cffffcc00ESC|r = |cff6666ffReturn to start menu.|r
* Practice Mode:
- |cffffcc00R|r = |cff6666ffRandomize wind conditions.|r
- |cffffcc00V|r = |cff6666ffRandomize terrain.|r" ) //"//! If this gets any longer, it'll crash warcraft.
call QuestSetIconPath ( q, "ReplaceableTextures\\CommandButtons\\BTNEngineeringUpgrade.blp" )
call QuestSetRequired ( q, false )
call QuestSetDiscovered ( q, true )
call QuestSetEnabled ( q, true )
//! =======================================================
endfunction
endscope