Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function OnInitID()
- -- [[ Markers ]]
- mkr_hold_passengers = Marker_FromName("mkr_hold_passengers","Ability")
- mkr_tunnel1_a = Marker_FromName("mkr_tunnel1_a","Ability")
- mkr_tunnel1_b = Marker_FromName("mkr_tunnel1_b","Ability")
- -- [[ Squad Groups ]]
- -- [[ Entity Groups ]]
- --[[
- ***********************************************
- Virtual Tunnels v1.0 By Janne "Janne252" Varjo
- - This system can be used to create virtual tunnels. The travelling squad is set invisible during the transport and set to
- visible again after the transport.
- - Each tunnel can be configured with:
- - points: Tunnel entry & exit markers in a table.
- - travelTime: How many seconds it takes to transport a squad from point_a to point_b or vice versa.
- - lockedToTeam: Only specified team can use the tunnel. Use "both" to allow all teams.
- - simultaneousTransport: Allow transporting multiple squads at the same time. Set to false to allow only one squad to transport at a time.
- - lockForTeamDuringTransport: Allow transporting team 1 and 2 units in the tunnel at the same time.
- - allowInfantry: Allow transporting infantry squads.
- - allowVehicles: Allow transporting vehicle squads.
- - allowATGuns: Allow transporting AT-Gun squads.
- - id: Unique id for the tunnel.
- - In addition there are other global settings, descbribed below:
- --]]
- --GLOBAL CONFIG
- -- How far squad must be from the tunnel entrance to allow squad to use the tunnel again (prevents resonance)
- g_registerExitAt = 6
- -- How far from the tunnel entrance squad moves after the transportation
- g_moveToAfterTransport = 10
- -- How many times squad is told to move to the tunnel door until forced to move
- g_moveTreshold = 25
- -- How many meters foward from the tunnel door vehicles are spawned
- g_vehicleForwardSpawn = 2
- -- How many meters further vehicles are detected to begin the transport (vehicles cannot get as close to tunnel doors as infantry can)
- g_vehicleDetectIncrease = 2
- -- Marker for holding passengers during transport
- g_holdPassengersMarker = mkr_hold_passengers
- --Tunnel configration
- g_tunnels = {
- {
- points = {mkr_tunnel1_a, mkr_tunnel1_b},
- travelTime = 5,
- lockedToTeam = "both",
- simultaneousTransport = true,
- lockForTeamDuringTransport = true,
- allowInfantry = true,
- allowVehicles = false,
- allowATGuns = false,
- allowTeamWeapons = false,
- id = 1,
- },
- }
- --END OF GLOBAL CONFIG
- -- Global variables, data holders
- sg_tunnel = SGroup_CreateIfNotFound("sg_tunnel")
- sg_blah = SGroup_CreateIfNotFound("sg_blah")
- g_in_tunnel_squads = {}
- g_fancyDespawn = {}
- g_fancySpawn = {}
- g_debug = true
- g_text = ""
- g_floodTimer = 0
- msg("Tunnel system intitialized with "..table.getn(g_tunnels).." tunnels.")
- -- System initialization and startup
- Rule_Add(MonitorTunnels)
- Rule_Add(FancyDespawnManager)
- Rule_AddInterval(FancySpawnManager, 0.4)
- end
- function MonitorTunnels()
- --[[
- - Monitors tunnels configured in g_tunnels
- - Performs actions to squads based on the config
- --]]
- for key, tunnel in ipairs(g_tunnels) do
- for t_key, point in ipairs(tunnel.points) do
- for i = 1, World_GetPlayerCount() do
- local player = World_GetPlayerAt(i)
- SGroup_Clear(sg_tunnel)
- World_GetSquadsNearMarker(player, sg_tunnel, point, OT_Player)
- SGroup_ForEach(sg_tunnel,
- function(sgid, idx, squad)
- if check_NotInTunnel(squad) and not Squad_IsInHoldSquad(squad) then
- g_floodTimer = g_floodTimer + 1
- local owner = Squad_GetPlayerOwner(squad)
- local team = Player_GetTeam(owner)
- if (tunnel.lockedToTeam == team or tunnel.lockedToTeam == "both") then
- if (not tunnelHasTransports(tunnel.id) or tunnel.simultaneousTransport) then
- if (tunnel.allowVehicles or not Squad_IsVehicle(squad)) then
- if (tunnel.allowATGuns or not Squad_IsAtGun(squad)) then
- if (tunnel.allowTeamWeapons or not Squad_IsTeamWeapon(squad)) then
- if (tunnel.allowInfantry or Squad_IsVehicle(squad)) then
- local ownerTeam = getCurrentTunnelOwner(tunnel.id)
- if ownerTeam == "world" or ownerTeam == Player_GetTeam(owner) or tunnel.lockForTeamDuringTransport == false then
- msg("despawning a squad with count "..Squad_Count(squad))
- local controlGroup = -1
- if Player_GetID(Game_GetLocalPlayer()) == Player_GetID(owner) then
- SGroup_Clear(sg_blah)
- Misc_GetSelectedSquads(sg_blah, false)
- if not SGroup_IsEmpty(sg_blah) then
- Camera_MoveTo(Util_GetOffsetPosition(Camera_GetCurrentTargetPos(), OFFSET_FRONT, 1))
- end
- controlGroup = Misc_GetSquadControlGroup(squad)
- msg("seting controlgroup to "..controlGroup)
- end
- Squad_DeSpawnFancy(squad, point)
- _squad = {
- id = Squad_GetGameID(squad),
- destination = getDestination(tunnel.points, point),
- travelled = false,
- travelTime = tunnel.travelTime,
- timer = 0,
- tunnelId = tunnel.id,
- spawnedCount = Squad_Count(squad),
- deSpawnedCount = 0,
- startedSpawning = false,
- fullySpawned = false,
- fullyDespawned = false,
- owner = Squad_GetPlayerOwner(squad),
- controlGroup = controlGroup,
- }
- table.insert(g_in_tunnel_squads, _squad)
- else
- msg("Tunnel is currently owned by team "..ownerTeam..", team "..Player_GetTeam(owner).." is not permitted!", g_floodTimer)
- end
- else
- msg("squad is infantry, infantry transports not permitted!", g_floodTimer)
- end
- else
- msg("squad is Team Weapon, Team weapon squad transports not permitted!", g_floodTimer)
- end
- else
- msg("squad is AT-Gun, AT-Gun transports not permitted!", g_floodTimer)
- end
- else
- msg("squad is vehicle, vehicle transports not permitted!", g_floodTimer)
- end
- else
- msg("Tunnel is occupied, simultaneous transporting is not permitted!", g_floodTimer)
- end
- else
- msg("Tunnel is locked to team "..tunnel.lockedToTeam.." team "..team.." is not permitted!", g_floodTimer)
- end
- end
- end
- )
- end
- end
- end
- for key, _squad in ipairs(g_in_tunnel_squads) do
- if Squad_IsValid(_squad.id) and _squad.fullyDespawned then
- local squad = Squad_FromWorldID(_squad.id)
- _squad.timer = _squad.timer + 1
- if _squad.timer % 10 == 0 and _squad.timer <= (_squad.travelTime * 8) then
- msg("timer is now ".._squad.timer)
- end
- if _squad.timer >= _squad.travelTime * 8 and not _squad.travelled and not _squad.startedSpawning then
- _squad.startedSpawning = true
- msg("starting to spawn a squad")
- Squad_SpawnFancy(squad, _squad)
- end
- if _squad.startedSpawning and not _squad.travelled then
- if _squad.fullySpawned then
- msg("all squad members are spawned")
- _squad.travelled = true
- end
- end
- if _squad.travelled then
- if Squad_DistanceToIsGreater(squad, Marker_GetPosition(_squad.destination), g_registerExitAt) then
- msg("squad is far enough from dest")
- table.remove(g_in_tunnel_squads, key)
- end
- end
- elseif not Squad_IsValid(_squad.id) then
- msg("removing, squad is invalid!")
- table.remove(g_in_tunnel_squads, key)
- end
- end
- end
- function tunnelHasTransports(tunnelId)
- -- Used to check whether or not a tunnel with tunnelId has squads in it.
- for key, value in ipairs(g_in_tunnel_squads) do
- if value.tunnelId == tunnelId and not value.travelled then
- return true
- end
- end
- return false
- end
- function getCurrentTunnelOwner(tunnelId)
- -- Used to return the owner of the squad in the tunnel.
- for key, value in ipairs(g_in_tunnel_squads) do
- if value.tunnelId == tunnelId then
- return Player_GetTeam(value.owner)
- end
- end
- return "world"
- end
- function Squad_DistanceToIsGreater(squad, pos, distance)
- -- Used to check if all entities in a squad are at a certain distance of a pos
- for n = 1, Squad_Count(squad) do
- local entity = Squad_EntityAt(squad, n-1)
- local _distance = World_DistancePointToPoint(Entity_GetPosition(entity), pos)
- if _distance < distance then
- return false
- end
- end
- return true
- end
- function Squad_SpawnFancy(squad, _squad)
- -- Used to spawn despawned squads in a Fancy way (coming out of the tunnel doors one by one)
- local movePos = Marker_GetPosition(_squad.destination)
- Squad_SetPosition(squad, movePos, movePos)
- local squad_count = Squad_Count(squad)
- for n = 1, Squad_Count(squad) do
- local entity = Squad_EntityAt(squad, n-1)
- local _entity = {
- id = Entity_GetGameID(entity),
- destination = _squad.destination,
- squad = Squad_GetGameID(squad),
- moveAttempts = 0,
- }
- table.insert(g_fancySpawn, _entity)
- end
- SGroup_Clear(sg_blah)
- Squad_GetSquadsHeld(squad, sg_blah)
- SGroup_ForEach(sg_blah,
- function(sgid, idx, squad)
- Squad_SpawnFancy(squad, _squad)
- end
- )
- end
- function FancySpawnManager()
- -- Used to control fancy spawning
- local hasSpawned = false
- for key, _entity in ipairs(g_fancySpawn) do
- if not hasSpawned then
- hasSpawned = true
- if Entity_IsValid(_entity.id) then
- local entity = Entity_FromWorldID(_entity.id)
- UI_EnableEntitySelectionVisuals(entity, true)
- UI_EnableEntityMinimapIndicator(entity, true)
- local squad = Squad_FromWorldID(_entity.squad)
- local spawnPos = Marker_GetPosition(_entity.destination)
- local moveToPos = Util_GetOffsetPosition(_entity.destination, OFFSET_FRONT, g_moveToAfterTransport)
- if Squad_IsVehicle(squad) then
- spawnPos = Util_GetOffsetPosition(_entity.destination, OFFSET_FRONT, g_vehicleForwardSpawn)
- end
- _verifySpawn(entity, _entity, squad, spawnPos, moveToPos, key)
- else
- msg("!! entity is not valid (spawn), not going to spawn")
- end
- table.remove(g_fancySpawn, key)
- else
- break
- end
- end
- end
- function _verifySpawn(entity, _entity, squad, spawnPos, moveToPos, key)
- -- Used to perform the actual fancy spawn actions
- Entity_SetPosition(entity, spawnPos)
- Entity_SetHeading(entity, Marker_GetDirection(_entity.destination), false)
- Entity_VisHide(entity, false)
- Entity_SimHide(entity, false)
- Cmd_Move(Squad_GetSGroup(squad), moveToPos)
- for k, v in ipairs(g_in_tunnel_squads) do
- if v.id == _entity.squad then
- v.spawnedCount = v.spawnedCount + 1
- v.deSpawnedCount = v.deSpawnedCount - 1
- msg("+ entity spawnCount, deSpawnedCount = "..v.spawnedCount..", "..v.deSpawnedCount.." ["..BP_GetName(Entity_GetBlueprint(entity)).."]")
- if v.deSpawnedCount == 0 then
- v.fullySpawned = true
- msg("Fully spawned!")
- EnableSquad(squad)
- local owner = Squad_GetPlayerOwner(squad)
- if Player_GetID(Game_GetLocalPlayer()) == Player_GetID(owner) then
- if _squad.controlGroup > -1 then
- Misc_SetSquadControlGroup(squad, _squad.controlGroup)
- msg("getting controlgroup ".._squad.controlGroup)
- end
- end
- end
- end
- end
- end
- function EnableSquad(squad)
- local sg_squad = Squad_GetSGroup(squad)
- Squad_SetInvulnerable(squad, false, -1)
- SGroup_SetSelectable(sg_squad, true)
- SGroup_EnableUIDecorator(sg_squad, true)
- SGroup_EnableMinimapIndicator(sg_squad, true)
- Modify_SightRadius(sg_squad, 1000000)
- SGroup_Clear(sg_blah)
- Squad_GetSquadsHeld(squad, sg_blah)
- SGroup_ForEach(sg_blah,
- function(sgid, idx, squad)
- EnableSquad(squad)
- end
- )
- end
- function DisableSquad(squad)
- local sg_squad = Squad_GetSGroup(squad)
- Squad_SetInvulnerable(squad, true, -1)
- SGroup_SetSelectable(sg_squad, false)
- SGroup_EnableUIDecorator(sg_squad, false)
- SGroup_EnableMinimapIndicator(sg_squad, false)
- Modify_SightRadius(sg_squad, 1/1000000)
- SGroup_Clear(sg_blah)
- Squad_GetSquadsHeld(squad, sg_blah)
- SGroup_ForEach(sg_blah,
- function(sgid, idx, squad)
- DisableSquad(squad)
- end
- )
- end
- function Squad_DeSpawnFancy(squad, pos)
- -- used to despawn squads in a fancy way (moving to the tunnel doors one by one)
- DisableSquad(squad)
- local squad_count = Squad_Count(squad)
- for n = 1, Squad_Count(squad) do
- local entity = Squad_EntityAt(squad, n-1)
- local _entity = {
- id = Entity_GetGameID(entity),
- destination = pos,
- squad = Squad_GetGameID(squad),
- moveAttempts = 0,
- }
- table.insert(g_fancyDespawn, _entity)
- end
- SGroup_Clear(sg_blah)
- Squad_GetSquadsHeld(squad, sg_blah)
- SGroup_ForEach(sg_blah,
- function(sgid, idx, squad)
- Squad_DeSpawnFancy(squad, pos)
- end
- )
- end
- function FancyDespawnManager()
- -- Used to control fancy despawning
- for key, _entity in ipairs(g_fancyDespawn) do
- if Entity_IsValid(_entity.id) then
- local entity = Entity_FromWorldID(_entity.id)
- UI_EnableEntitySelectionVisuals(entity, false)
- UI_EnableEntityMinimapIndicator(entity, false)
- local distance = World_DistancePointToPoint(Entity_GetPosition(entity), Marker_GetPosition(_entity.destination))
- --msg("distance: "..distance)
- local squad = Squad_FromWorldID(_entity.squad)
- local increasedSearch = 0
- if Squad_IsVehicle(squad) then
- increasedSearch = g_vehicleDetectIncrease
- end
- if distance < (1 + increasedSearch) then
- _verifyDeSpawn(entity, _entity, squad, key)
- else
- --Cmd_Move(Squad_GetSGroup(Squad_FromWorldID(_entity.squad)), Marker_GetPosition(_entity.destination))
- _entity.moveAttempts = _entity.moveAttempts + 1
- if _entity.moveAttempts >= g_moveTreshold then
- msg("force deSpawning")
- Entity_SetPosition(entity, Marker_GetPosition(_entity.destination))
- _verifyDeSpawn(entity, _entity, squad, key)
- end
- end
- else
- msg("removing from despawn, invalid entity")
- table.remove(g_fancyDespawn, key)
- end
- end
- end
- function _verifyDeSpawn(entity, _entity, squad, key)
- -- used to perform the actual despawn actions
- Entity_VisHide(entity, true)
- Entity_SimHide(entity, true)
- for k, v in ipairs(g_in_tunnel_squads) do
- if v.id == _entity.squad then
- v.spawnedCount = v.spawnedCount - 1
- v.deSpawnedCount = v.deSpawnedCount + 1
- msg("- entity spawnCount, deSpawnedCount = "..v.spawnedCount..", "..v.deSpawnedCount.." ["..BP_GetName(Entity_GetBlueprint(entity)).."]")
- if v.spawnedCount == 0 then
- v.fullyDespawned = true
- msg("Fully DeSpawned!")
- Squad_SetPosition(squad, Marker_GetPosition(g_holdPassengersMarker), Util_GetOffsetPosition(Squad_GetPosition(squad), OFFSET_FRONT, 4))
- Cmd_Stop(Squad_GetSGroup(squad))
- end
- end
- end
- table.remove(g_fancyDespawn, key)
- end
- function getDestination(tunnel, point)
- -- Used to get x from table {x, y} if y is selected and vice versa
- for key, value in ipairs(tunnel) do
- if value ~= point then
- msg("destination: "..Marker_GetName(value))
- return value
- end
- end
- msg("destination: same")
- return point
- end
- function check_NotInTunnel(squad)
- -- Used to check if squad is not in a tunnel
- for key, _squad in ipairs(g_in_tunnel_squads) do
- if _squad.id == Squad_GetGameID(squad) then
- return false
- end
- end
- return true
- end
- function Squad_GetSGroup(squad)
- -- Used to return a temporaly sgroup for performing quick SGroup only actions for a squad
- local sg_temptunnel = SGroup_CreateIfNotFound("sg_temptunnel")
- SGroup_Clear(sg_temptunnel)
- SGroup_Add(sg_temptunnel, squad)
- return sg_temptunnel
- end
- function Entity_GetEGroup(entity)
- -- Used to return a temporaly egroup for performing quick EGroup only actions for an entity
- local eg_temptunnel = EGroup_CreateIfNotFound("eg_temptunnel")
- EGroup_Clear(eg_temptunnel)
- EGroup_Add(eg_temptunnel, entity)
- return eg_temptunnel
- end
- function Squad_IsVehicle(squad)
- -- Used to check if squad is a vehicle
- local entity = Squad_EntityAt(squad, 0)
- if Entity_IsOfType(entity, "vehicle") and not Entity_IsOfType(entity, "team_weapon") then
- return true
- end
- return false
- end
- function Squad_IsTeamWeapon(squad)
- -- Used to check if squad is a team weapon squad
- for n = 1, Squad_Count(squad) do
- local entity = Squad_EntityAt(squad, n-1)
- if Entity_IsOfType(entity, "team_weapon") then
- return true
- end
- end
- return false
- end
- function Squad_IsAtGun(squad)
- -- Used to check if squad is an AT-Gun squad
- for n = 1, Squad_Count(squad) do
- local entity = Squad_EntityAt(squad, n-1)
- if Entity_IsOfType(entity, "at_gun") then
- return true
- end
- end
- return false
- end
- function msg(text, floodTimer)
- -- used to print debug messages
- if not floodTimer then floodTimer = 10 end
- if g_debug then
- if floodTimer % 10 == 0 then
- dr_clear("UI2")
- dr_setautoclear("UI2", false)
- g_text = text.."\n"..g_text
- dr_text2d("UI2", 0.715, 0.02, g_text, 255, 0, 0)
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement