- Joined
- Dec 29, 2008
- Messages
- 271
Please Comment/ Rate and maybe vote for approval
Please try to give only helpful critism
Please try to give only helpful critism
library AdvancedCameraSystem initializer Init
// Advanced Camera System by The_Witcher
//
// This is a very advanced advanced camera system which adjusts the camera
// distance to the target so the camera isn't looking through houses/trees/...
// and the cameras angle of attack so the view isn't blocked because of hills...
//
// useful for RPGs and that stuff
//
// To bind the camera to a unit for a player use
// SetCameraUnit( unit, player )
//
// if you want to have your normal camera again use
// ReleaseCameraUnit( player )
//
// in case you want to know which unit is bound to the camera for player xy use
// GetCameraUnit( player )
//
// to change the AngleOfAttack of a player ingame use
// SetCamDefaultAngleOfAttack( Player, NewValue )
//
// to change the maximal camera target distance of a player ingame use
// SetCamMaxDistance( Player, NewValue )
//
// to change the maximal distance behind the target, the z-offset is checked (for z-angle), of a player ingame use
// SetCamMaxZCheckDistance( Player, NewValue )
//
// SETUP PART
globals
// The max. distance the camera can have to the target
private real DEFAULT_MAX_DISTANCE = 1000
// The max. distance the zOffset behind the unit is checked (for zAngle)
private real DEFAULT_MAX_Z_CHECK_DISTANCE = 500
// the camera angle of attack correction after the zAngle calculation
private real DEFAULT_ANGLE_OF_ATTACK = -20
// the timer interval (0.01 is best but can lagg in huge maps with many of these short intervals)
private constant real INTERVAL = 0.03
// the time the camera will need to adjust
private constant real DELAY = 0.25
// the standart z of the camera
private constant real NORMAL_HEIGHT = 100
// the accuracy increases if the value gets smaller
private constant real ACCURACY = 50
// the secondary accruracy when the camera reaches a barricade (just leave at this amount)
private constant real EXTREME_ACCURACY = 10
endglobals
// SETUP END
// don't modify the code below!
globals
private item ite
private real array Aoa[15]
private real array Dist[15]
private real array CheckDist[15]
private unit array CamUnit[15]
private timer tim = CreateTimer()
private location loc = Location(0,0)
private integer active = 0
private hashtable h = InitHashtable()
endglobals
private function IsCoordPathable takes real x, real y returns boolean
call SetItemVisible(ite,true)
call SetItemPosition(ite,x,y)
set x = GetItemX( ite) - x
set y = GetItemY( ite) - y
call SetItemVisible(ite,false)
if x < 1 and x > -1 and y < 1 and y > -1 then
return true
endif
return false
endfunction
private function HideAllItems takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
call SaveInteger(h,GetHandleId(GetEnumItem()),0,1)
endif
call SetItemVisible(GetEnumItem(),false)
endfunction
private function ShowAllItems takes nothing returns nothing
if LoadInteger(h,GetHandleId(GetEnumItem()),0) == 1 then
call SetItemVisible(GetEnumItem(),true)
call FlushChildHashtable(h,GetHandleId(GetEnumItem()))
endif
endfunction
private function Actions takes nothing returns nothing
local real x
local real y
local real angle
local real rz
local real z
local integer i = 0
local integer Check
local real CheckDistance
local real DistanceDone
local rect rec
loop
exitwhen i >= bj_MAX_PLAYERS
if CamUnit[i] != null then
set DistanceDone = 0
set rz = 0
set x = GetUnitX(CamUnit[i])
set y = GetUnitY(CamUnit[i])
set Check = 1
set angle = (GetUnitFacing(CamUnit[i]) - 180)*bj_DEGTORAD
set CheckDistance = ACCURACY
set z = DEFAULT_ANGLE_OF_ATTACK
if not IsUnitType(CamUnit[i], UNIT_TYPE_FLYING) then
loop
set x = x + CheckDistance * Cos(angle)
set y = y + CheckDistance * Sin(angle)
set DistanceDone = DistanceDone + CheckDistance
call MoveLocation(loc,x,y)
set z = GetLocationZ(loc)
if RAbsBJ(z) > RAbsBJ(rz) and DistanceDone <= CheckDist[i] then
set rz = z
endif
if not IsCoordPathable(x,y)then
set rec = Rect(x-ACCURACY,y-ACCURACY,x+ACCURACY,y+ACCURACY)
call EnumItemsInRect(rec,null, function HideAllItems)
if not IsCoordPathable(x,y)then
set Check = 0
endif
call RemoveRect(rec)
endif
if Check == 0 and CheckDistance == ACCURACY then
set DistanceDone = DistanceDone - CheckDistance
set x = x - CheckDistance * Cos(angle)
set y = y - CheckDistance * Sin(angle)
set Check = 1
set CheckDistance = EXTREME_ACCURACY
endif
exitwhen (Check == 0 and CheckDistance == EXTREME_ACCURACY) or DistanceDone > Dist[i]
endloop
else
set DistanceDone = Dist[i]
endif
call MoveLocation(loc,GetUnitX(CamUnit[i]),GetUnitY(CamUnit[i]))
set x = GetLocationZ(loc)
loop
exitwhen x - rz < 180
set x = x - 180
endloop
set z = Atan2(x-rz,200) * bj_RADTODEG + Aoa[i]
if IsUnitType(CamUnit[i], UNIT_TYPE_FLYING) then
set z = Aoa[i]
endif
if GetLocalPlayer() == Player(i) then
call CameraSetSmoothingFactor(1)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, DistanceDone, DELAY)
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, z, DELAY)
call SetCameraField(CAMERA_FIELD_ZOFFSET,GetCameraField(CAMERA_FIELD_ZOFFSET)+x+GetUnitFlyHeight(CamUnit[i])+NORMAL_HEIGHT-GetCameraTargetPositionZ(),DELAY)
call SetCameraField(CAMERA_FIELD_ROTATION, angle*bj_RADTODEG+180, DELAY)
call SetCameraTargetController(CamUnit[i],0,0,false)
endif
endif
set i = i + 1
endloop
call EnumItemsInRect(bj_mapInitialPlayableArea,null, function ShowAllItems)
set rec = null
endfunction
function ReleaseCameraUnit takes player p returns nothing
if CamUnit[GetPlayerId(p)] != null then
set CamUnit[GetPlayerId(p)] = null
call ResetToGameCameraForPlayer(p,0)
if GetLocalPlayer() == p then
call CameraSetSmoothingFactor(0)
endif
set active = active - 1
if active == 0 then
call PauseTimer(tim)
endif
endif
endfunction
function SetCameraUnit takes unit u, player owner returns nothing
if CamUnit[GetPlayerId(owner)] != null then
call ReleaseCameraUnit(owner)
endif
set CamUnit[GetPlayerId(owner)] = u
set active = active + 1
if active == 1 then
call TimerStart(tim,INTERVAL,true,function Actions)
endif
endfunction
function SetCamDefaultAngleOfAttack takes player p, real a returns nothing
set Aoa[GetPlayerId(p)] = a
endfunction
function SetCamMaxDistance takes player p, real d returns nothing
set Dist[GetPlayerId(p)] = d
endfunction
function SetCamMaxZCheckDistance takes player p, real d returns nothing
set CheckDist[GetPlayerId(p)] = d
endfunction
function GetCameraUnit takes player pl returns unit
return CamUnit[GetPlayerId(pl)]
endfunction
private function Init takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
set CamUnit[i] = null
set Aoa[i] = DEFAULT_ANGLE_OF_ATTACK
set Dist[i] = DEFAULT_MAX_DISTANCE
set CheckDist[i] = DEFAULT_MAX_Z_CHECK_DISTANCE
set i = i + 1
endloop
set ite = CreateItem( 'wolg', 0,0 )
call SetItemVisible(ite,false)
endfunction
endlibrary
library ArrowKeyMovement initializer Init requires KeyboardSystem, ArrowKeyMovementPlugins
// Arrow key movement by The_Witcher
// this system allows each player to control 1 unit
// with his arrow keys even if he doesn't own the unit!
// It features turning on the left and right arrow, walking foreward
// by pressing the up arrow and walking backwards by pressing the down arrow...
//
// You can improve this system with plugins but you need vJass knowledge for that!
//
// --> The TurnRate of a unit inside the object editor STILL influences the turn rate from this system <--
//
// Included functions:
//
// SetMovementUnit ( whichunit, forWhichPlayer, walkAnimationIndex )
// unit player integer
// this gives the player the arrow key movement control over the unit
// while the unit moves the animation of the given index is played
// (just try around to find the index... start at 0 and increase
// by 1 until you find the walk index of that unit)
//
//
// ReleaseMovementUnit ( fromWhichPlayer )
// player
// this function removes the control from a player
//
//
// GetMovementUnit ( fromWhichPlayer ) returns unit
// player
// I think its self explaining...
//
//
// SetMovementUnitAnimation ( fromWhichPlayer, animation )
// player integer
// this function allows ingame changing of the played animation of a unit
// ------- SETUP PART ---------
globals
// the timer interval... increase if laggy
private constant real INTERVAL = 0.01
// the facing change in degrees each interval (must be a positive value)
private constant real DEFAULT_VIEW_CHANGE = 4
// when you move backwards you move slower than normal...
private constant real BACKWARDS_MOVING_FACTOR = 0.7
// if the unit turns it will turn faster the longer it does...
// some people may need that but then it should be 1.02 (1.0 means disabled)
private constant real TURN_ACCELERATION = 1
// (can only be 1 or -1) if you walk backwards you have 2 ways of turning
// 1. way: pressing left will make the char turn left
// 2. way: pressing left will make the char turn so he moves to the left
private constant integer REVERSED_BACKWARDS_MOVING = 1
endglobals
// whenever this function returns false for a unit it won't be moved even if the player
// presses the keys! change to create your own "No Movement" conditions
private function MoveConditions takes unit u returns boolean
return not IsUnitType(u,UNIT_TYPE_SLEEPING) and not IsUnitType(u,UNIT_TYPE_STUNNED) and not (IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0 )
endfunction
// --------- don't modify anything below this line ------------
struct ArrowKeyMovement
private static ArrowKeyMovement array all [12] // = bj_MAX_PLAYERS
private static timer tim
integer walking
unit u
integer animation
real SpeedFactor
real ViewChange
real SpecialDirection
boolean SpecialDirectionActive
static method operator [] takes player p returns ArrowKeyMovement
local integer i = GetPlayerId(p)
if .all[i] == 0 then
set .all[i] = ArrowKeyMovement.create()
set .all[i].SpeedFactor = 1
set .all[i].SpecialDirection = 0
set .all[i].SpecialDirectionActive = false
set .all[i].ViewChange = DEFAULT_VIEW_CHANGE
endif
return .all[i]
endmethod
private static method Walking takes nothing returns nothing
local integer i = 0
local real x
local real y
local real X
local real Y
local boolean boolX
local boolean boolY
local boolean left
local boolean right
local boolean up
local boolean down
local ArrowKeyMovement mov
loop
exitwhen i >= 12 // = bj_MAX_PLAYERS
set mov = .all[i]
if mov.u != null and MoveConditions(mov.u) then
// special movement <-- plugins
if mov.SpecialDirectionActive then
if mov.walking != 1 then
call SetUnitTimeScale(mov.u,mov.SpeedFactor)
call SetUnitAnimationByIndex(mov.u,mov.animation)
set mov.walking = 1
else
call SetUnitTimeScale(mov.u,mov.SpeedFactor)
endif
set x = GetUnitX(mov.u)
set y = GetUnitY(mov.u)
set X = x + GetUnitMoveSpeed(mov.u)*INTERVAL * Cos(mov.SpecialDirection*bj_DEGTORAD) * mov.SpeedFactor
set Y = y + GetUnitMoveSpeed(mov.u)*INTERVAL * Sin(mov.SpecialDirection*bj_DEGTORAD) * mov.SpeedFactor
call SetUnitPosition(mov.u,X,Y)
if (RAbsBJ(GetUnitX(mov.u)-X)>0.5)or(RAbsBJ(GetUnitY(mov.u)-Y)>0.5)then
call SetUnitPosition(mov.u,X,y)
set boolX = RAbsBJ(GetUnitX(mov.u)-X)<=0.5
call SetUnitPosition(mov.u,x,Y)
set boolY = RAbsBJ(GetUnitY(mov.u)-Y)<=0.5
if boolX then
call SetUnitPosition(mov.u,X,y)
elseif boolY then
call SetUnitPosition(mov.u,x,Y)
else
call SetUnitPosition(mov.u,x,y)
endif
endif
else
// Normal movement
set left = IsKeyDown(KEY_LEFT,Player(i))
set right = IsKeyDown(KEY_RIGHT,Player(i))
set up = IsKeyDown(KEY_UP,Player(i))
set down = IsKeyDown(KEY_DOWN,Player(i))
//right down
if right then
if down then
call SetUnitFacing(mov.u,GetUnitFacing(mov.u)-mov.ViewChange * -REVERSED_BACKWARDS_MOVING)
else
call SetUnitFacing(mov.u,GetUnitFacing(mov.u)-mov.ViewChange)
endif
set mov.ViewChange = mov.ViewChange * TURN_ACCELERATION
elseif not left then
set mov.ViewChange = DEFAULT_VIEW_CHANGE
endif
//left down
if left then
if down then
call SetUnitFacing(mov.u,GetUnitFacing(mov.u)+mov.ViewChange * -REVERSED_BACKWARDS_MOVING)
else
call SetUnitFacing(mov.u,GetUnitFacing(mov.u)+mov.ViewChange)
endif
set mov.ViewChange = mov.ViewChange * TURN_ACCELERATION
elseif not right then
set mov.ViewChange = DEFAULT_VIEW_CHANGE
endif
if mov.ViewChange > 179 then
set mov.ViewChange = 179
endif
//up down
if up then
if mov.walking != 1 then
call SetUnitTimeScale(mov.u,mov.SpeedFactor)
call SetUnitAnimationByIndex(mov.u,mov.animation)
set mov.walking = 1
else
call SetUnitTimeScale(mov.u,mov.SpeedFactor)
endif
set x = GetUnitX(mov.u)
set y = GetUnitY(mov.u)
set X = x + GetUnitMoveSpeed(mov.u)*INTERVAL * Cos(GetUnitFacing(mov.u)*bj_DEGTORAD) * mov.SpeedFactor
set Y = y + GetUnitMoveSpeed(mov.u)*INTERVAL * Sin(GetUnitFacing(mov.u)*bj_DEGTORAD) * mov.SpeedFactor
//down down
elseif down then
if mov.walking != 2 then
call SetUnitTimeScale(mov.u,-BACKWARDS_MOVING_FACTOR * mov.SpeedFactor)
call SetUnitAnimationByIndex(mov.u,mov.animation)
set mov.walking = 2
else
call SetUnitTimeScale(mov.u,-BACKWARDS_MOVING_FACTOR * mov.SpeedFactor)
endif
set x = GetUnitX(mov.u)
set y = GetUnitY(mov.u)
set X = x - GetUnitMoveSpeed(mov.u) * INTERVAL * Cos(GetUnitFacing(mov.u)*bj_DEGTORAD) * BACKWARDS_MOVING_FACTOR * mov.SpeedFactor
set Y = y - GetUnitMoveSpeed(mov.u) * INTERVAL * Sin(GetUnitFacing(mov.u)*bj_DEGTORAD) * BACKWARDS_MOVING_FACTOR * mov.SpeedFactor
endif
//move
if down or up then
call SetUnitPosition(mov.u,X,Y)
if (RAbsBJ(GetUnitX(mov.u)-X)>0.5)or(RAbsBJ(GetUnitY(mov.u)-Y)>0.5)then
call SetUnitPosition(mov.u,X,y)
set boolX = RAbsBJ(GetUnitX(mov.u)-X)<=0.5
call SetUnitPosition(mov.u,x,Y)
set boolY = RAbsBJ(GetUnitY(mov.u)-Y)<=0.5
if boolX then
call SetUnitPosition(mov.u,X,y)
elseif boolY then
call SetUnitPosition(mov.u,x,Y)
else
call SetUnitPosition(mov.u,x,y)
endif
endif
else
if mov.walking != 0 then
call SetUnitAnimation(mov.u,"stand")
call SetUnitTimeScale(mov.u,1)
set mov.walking = 0
endif
endif
endif
endif
set i = i + 1
endloop
endmethod
static method onInit takes nothing returns nothing
set .tim = CreateTimer()
call TimerStart(.tim,INTERVAL,true,function ArrowKeyMovement.Walking)
endmethod
endstruct
function GetMovementUnit takes player p returns unit
return ArrowKeyMovement.u
endfunction
function SetMovementUnitAnimation takes player p, integer animation returns nothing
set ArrowKeyMovement.animation = animation
endfunction
function ReleaseMovementUnit takes player p returns nothing
if ArrowKeyMovement.u != null then
set ArrowKeyMovement.walking = 0
call SetUnitAnimation(ArrowKeyMovement.u,"stand")
call SetUnitTimeScale(ArrowKeyMovement.u,1)
set ArrowKeyMovement.u = null
endif
endfunction
function SetMovementUnit takes unit u, player p, integer anim returns nothing
if u == null then
call ReleaseMovementUnit(p)
return
endif
if ArrowKeyMovement.u != null then
call ReleaseMovementUnit(p)
endif
call SetUnitAnimation(ArrowKeyMovement.u,"stand")
set ArrowKeyMovement.u = u
set ArrowKeyMovement.animation = anim
endfunction
//! runtextmacro ArrowKeyMovement_Plugins_Functions()
private function Init takes nothing returns nothing
//! runtextmacro Init_ArrowKeyMovement_Plugins()
endfunction
endlibrary