- Joined
- Mar 18, 2012
- Messages
- 1,716
UICamera
Handles the camerasetup, while viewing a custom UI.
SCREEN_WIDTH and SCREEN_HEIGHT are empirical values
and may not work for other screen resolution than mine.
If this is the case, there is not much we can do about it.
JASS:
//* Written by BPower.
library UICamera initializer Init/* v1.0
*************************************************************************************
*
* Adjusts the camera setup while viewing a UIScreen.
*
*************************************************************************************
*
* */ uses /*
*
* */ UIBasic /*
*
************************************************************************************
*
* Import instruction:
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the UICamera script into your map.
*/
globals
//* Constants:
//* ==========
private constant timer TIMER = CreateTimer()
private constant real UPDATE_CAMERA = (1./32.)
private constant real SCREEN_WIDTH = 1.632//* Empirical values.
private constant real SCREEN_HEIGHT = 0.906
endglobals
globals
//* Data structure:
//* ===============
private integer array stack
private integer size = 0
//* Variables:
//* ==========
private camerasetup array camera
private unit array dummy
private real array resetX
private real array resetY
private real array update
endglobals
private function SetCameraTargetDistance takes integer index, real width, real height, real time returns nothing
local real d = RMaxBJ(width*SCREEN_HEIGHT, height*SCREEN_WIDTH)
call CameraSetupSetField(camera[index], CAMERA_FIELD_TARGET_DISTANCE, d, time)
endfunction
//* The stack has a lookup speed of O(n).
//* This is utterly acceptable as the maximum
//* stack size is bj_MAX_PLAYERS, which equals 12.
private function Get takes player p returns integer
local integer index = 0
local integer id = GetPlayerId(p)
loop
exitwhen (index == size)
if (id == stack[index]) then
return index
endif
set index = index + 1
endloop
return -1
endfunction
private function OnPeriodic takes nothing returns nothing
local integer index = 0
local integer id
loop
exitwhen index == size
set id = stack[index]
if GetLocalClient() == Player(id) then
call CameraSetupApplyForceDuration(camera[id], true, 0.)
call SetCameraTargetController(dummy[id], 0., 0., false)
endif
set index = index + 1
endloop
endfunction
//* Push to stack:
//* ==============
private function Push takes integer id returns nothing
if (0 == size) then
call TimerStart(TIMER, UPDATE_CAMERA, true, function OnPeriodic)
endif
set stack[size] = id
set size = size + 1
//* Camera position natives have a internal delay of ~0.05.
//* In multiplayer seasons it's probably more.
//* We don't not want to end up between to windows.
if (update[id] < TimerGetElapsed(UI_STAMP) - 0.5) then
//* Always returns coordinates for a local client.
set resetX[id] = GetCameraTargetPositionX()
set resetY[id] = GetCameraTargetPositionY()
endif
endfunction
function UI_StopCamera takes player p returns nothing
local integer index = Get(p)
local integer id = GetPlayerId(p)
if (-1 != index) then
set size = size - 1
set stack[index] = stack[size]
if (0 == size) then
call PauseTimer(TIMER)
endif
if (GetLocalClient() == p) then
call SetCameraBoundsToRect(bj_mapInitialCameraBounds)
call SetCameraTargetController(null, 0., 0., false)
call CameraSetSmoothingFactor(1.)
call ResetToGameCamera(0.)
call SetCameraPosition(resetX[id], resetY[id])
endif
//* Bug fix:
//* ========
set update[id] = TimerGetElapsed(UI_STAMP)
//* Only in DEBUG_MODE:
debug else
debug call ThrowWarning((true), "UICamera", "UI_StopCamera", "index", -1, GetPlayerName(p) + " was not found in the stack!")
endif
endfunction
function UI_StartCamera takes player p, real originX, real originY, real width, real height returns nothing
local integer id = GetPlayerId(p)
local real x = originX + width*.5
local real y = originY + height*.5
local real maxX = originX + width
local real maxY = originY + height
if (IsPlayerUser(p)) then
//* If the player is not in the stack
//* function Get will return -1.
if (-1 == Get(p)) then
call Push(id)
endif
//* Set camerasetup:
//* ================
call SetCameraTargetDistance(id, width, height, 0.)
call SetUnitX(dummy[id], x)
call SetUnitY(dummy[id], y)
if (GetLocalClient() == p) then
call SetCameraBounds(originX, originY, originX, maxY, maxX, maxY, maxX, originY)
call CameraSetupSetDestPosition(camera[id], x, y, 0.)
call CameraSetSmoothingFactor(0.)
call CameraSetupApplyForceDuration(camera[id], true, 0.)
call SetCameraTargetController(dummy[id], 0., 0., false)
endif
//* Only in DEBUG_MODE:
debug else
debug call ThrowWarning(true, "UICamera", "UI_StartCamera", "p", 0, GetPlayerName(p) + " is a computer player! Only non-computer players are valid for UI_StartCamera!")
endif
endfunction
private function Init takes nothing returns nothing
local integer index = 0
local boolean prev
loop
exitwhen (index == bj_MAX_PLAYERS)
if IsPlayerUser(Player(index)) then
set prev = ToogleUnitIndexer(false)
set dummy[index] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), UI_CAMERA_DUMMY_ID, 0., 0., 0.)
call ToogleUnitIndexer(prev)
//* In case you don't have those fields set in the object editor.
call UnitAddAbility(dummy[index], 'Aloc')
call PauseUnit(dummy[index], true)
call SetUnitVertexColor(dummy[index], 0, 0, 0, 0)
set camera[index] = CreateCameraSetup()
call CameraSetupSetField(camera[index], CAMERA_FIELD_ANGLE_OF_ATTACK, 270., 0.)
call CameraSetupSetField(camera[index], CAMERA_FIELD_ROLL, 0., 0.)
call CameraSetupSetField(camera[index], CAMERA_FIELD_ROTATION, 90., 0.)
//* Only in DEBUG_MODE:
debug call ThrowError((GetUnitTypeId(dummy[index]) == 0), "UICamera", "Init", "dummy", index, "Unable to create a camera dummy. Invalid id for 'UI_CAMERA_DUMMY_ID' in UIBasic!")
endif
set index = index + 1
endloop
endfunction
endlibrary
Last edited:

