initial commit
This commit is contained in:
@@ -0,0 +1,341 @@
|
||||
|
||||
require( "map_encounter" )
|
||||
require( "aghanim_utility_functions" )
|
||||
require( "spawner" )
|
||||
require( "encounters/encounter_bonus_base" )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
if CMapEncounter_PenguinsTransition == nil then
|
||||
CMapEncounter_PenguinsTransition = class( {}, {}, CMapEncounter_BonusBase )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:constructor( hRoom, szEncounterName )
|
||||
CMapEncounter_BonusBase.constructor( self, hRoom, szEncounterName )
|
||||
|
||||
self.flPenguinTimeLimit = 55.0
|
||||
self:AddSpawner( CDotaSpawner( "penguin_spawner", "penguin_spawner",
|
||||
{
|
||||
{
|
||||
EntityName = "npc_dota_sled_penguin",
|
||||
Team = DOTA_TEAM_GOODGUYS,
|
||||
Count = 1,
|
||||
PositionNoise = 0.0,
|
||||
},
|
||||
}
|
||||
) )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:Precache( context )
|
||||
CMapEncounter_BonusBase.Precache( self, context )
|
||||
|
||||
PrecacheResource( "particle", "particles/gameplay/location_hint_goal.vpcf", context )
|
||||
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_wandering_ogre_seal", context, -1 )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:GetPreviewUnit()
|
||||
return "npc_dota_sled_penguin"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:OnEncounterLoaded()
|
||||
CMapEncounter_BonusBase.OnEncounterLoaded( self )
|
||||
self:SetupBristlebackShop( true )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:InitializeObjectives()
|
||||
self:AddEncounterObjective( "objective_saddle_up_on_penguin", 0, 4 )
|
||||
self:AddEncounterObjective( "objective_sled_to_collect_gold", 0, 0 )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:Start()
|
||||
CMapEncounter_BonusBase.Start( self )
|
||||
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
|
||||
self.flEndTime = 99999999999999999
|
||||
|
||||
local hUnits = self:GetSpawner( "penguin_spawner" ):SpawnUnits()
|
||||
|
||||
self.Penguins = {}
|
||||
|
||||
local hFacingTargets = self:GetRoom():FindAllEntitiesInRoomByName( "penguin_facing_target", true )
|
||||
local hFacingTarget = hFacingTargets[ 1 ]
|
||||
|
||||
local nPlayerID = 0
|
||||
for _, hPenguin in pairs ( hUnits ) do
|
||||
local hPlayerHero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
|
||||
if hPlayerHero then
|
||||
hPlayerHero:AddNewModifier( hPlayerHero, nil, "modifier_bonus_room_start", {} )
|
||||
end
|
||||
|
||||
hPenguin.Encounter = self
|
||||
hPenguin:SetOwner( hPlayerHero )
|
||||
|
||||
hPenguin:FaceTowards( hFacingTarget:GetAbsOrigin() )
|
||||
|
||||
hPenguin.nFXIndex = ParticleManager:CreateParticleForPlayer( "particles/gameplay/location_hint_goal.vpcf", PATTACH_WORLDORIGIN, nil, PlayerResource:GetPlayer( nPlayerID ) )
|
||||
local vArrowFXPos = hPenguin:GetAbsOrigin()
|
||||
ParticleManager:SetParticleControl( hPenguin.nFXIndex, 0, vArrowFXPos )
|
||||
ParticleManager:SetParticleControl( hPenguin.nFXIndex, 1, Vector( 1.0, 0.8, 0.2 ) )
|
||||
|
||||
local vLocation = hPenguin:GetAbsOrigin()
|
||||
local WorldTextHint = {}
|
||||
WorldTextHint["hint_text"] = "hint_ride_penguin"
|
||||
WorldTextHint["command"] = 18 -- DOTA_KEYBIND_HERO_MOVE
|
||||
WorldTextHint["ent_index"] = -1
|
||||
WorldTextHint["location_x"] = vLocation.x
|
||||
WorldTextHint["location_y"] = vLocation.y
|
||||
WorldTextHint["location_z"] = vLocation.z
|
||||
|
||||
CustomGameEventManager:Send_ServerToPlayer( PlayerResource:GetPlayer( nPlayerID ), "start_world_text_hint", WorldTextHint )
|
||||
|
||||
table.insert( self.Penguins, hPenguin )
|
||||
nPlayerID = nPlayerID + 1
|
||||
end
|
||||
|
||||
self.fCoinPileCreationInterval = 0.5
|
||||
self.fNextCoinPileSpawn = GameRules:GetGameTime() + self.fCoinPileCreationInterval
|
||||
|
||||
local nTotalGold = 5000 -- this is probably not needed since we have the self.nGoldForBags value
|
||||
self.nTotalGoldBagsToSpawn = 475
|
||||
self.nGoldPerBag = nTotalGold / self.nTotalGoldBagsToSpawn
|
||||
--printf( "Start - self.nGoldPerBag: %d", self.nGoldPerBag )
|
||||
self.nGoldForBags = self.nGoldReward * AGHANIM_PLAYERS
|
||||
--printf( "Start - self.nGoldForBags: %d", self.nGoldForBags )
|
||||
self.nGoldReward = 0
|
||||
self.nMinCoinsPerTarget = 8
|
||||
self.nMaxCoinsPerTarget = 8
|
||||
|
||||
self.nPreplacedBagsToSpawn = self.nTotalGoldBagsToSpawn / 3
|
||||
|
||||
self.GoldBags = {}
|
||||
|
||||
self.hPreplacedBagTargets = self:GetRoom():FindAllEntitiesInRoomByName( "gold_bag_target_preplaced", true )
|
||||
|
||||
self.hDynamicBagTargets = self:GetRoom():FindAllEntitiesInRoomByName( "gold_bag_target", true )
|
||||
--printf( "#self.hDynamicBagTargets: %d", #self.hDynamicBagTargets )
|
||||
|
||||
for _, hBagTarget in pairs( self.hPreplacedBagTargets ) do
|
||||
local nCoinSpawnsPerTarget = RandomInt( self.nMinCoinsPerTarget, self.nMaxCoinsPerTarget )
|
||||
for i = 1, nCoinSpawnsPerTarget do
|
||||
if TableLength( self.GoldBags ) >= self.nPreplacedBagsToSpawn then
|
||||
break
|
||||
end
|
||||
|
||||
local vGoldBagPos = self:GetValidCoinSpawnPos( hBagTarget )
|
||||
self.nGoldForBags = self.nGoldForBags - self.nGoldPerBag
|
||||
|
||||
local newItem = CreateItem( "item_bag_of_gold", nil, nil )
|
||||
newItem:SetPurchaseTime( 0 )
|
||||
newItem:SetCurrentCharges( self.nGoldPerBag )
|
||||
|
||||
-- NOTE: CreateItemOnPositionSync will drop the item to the ground, so the z height is going to be ignored
|
||||
-- However, LaunchLootRequiredHeight will fix it back up for us.
|
||||
local drop = CreateItemOnPositionSync( vGoldBagPos, newItem )
|
||||
--drop:SetModelScale( 1.5 )
|
||||
local fHeight = 0
|
||||
newItem:LaunchLootRequiredHeight( true, fHeight, fHeight, 0.75, vGoldBagPos )
|
||||
table.insert( self.GoldBags, newItem )
|
||||
end
|
||||
end
|
||||
|
||||
--printf( "[preplaced] total gold bags: %d", #self.GoldBags )
|
||||
|
||||
-- Create wandering ogre seals
|
||||
self.hOgreSeals = {}
|
||||
self.hOgreSealSpawners = self:GetRoom():FindAllEntitiesInRoomByName( "ogre_seal", true )
|
||||
--printf( "#self.hOgreSealSpawners: %d", #self.hOgreSealSpawners )
|
||||
|
||||
local nAscLevel = GameRules.Aghanim:GetAscensionLevel()
|
||||
local nTotalOgreSealsToSpawn = 7 + ( 2 * nAscLevel )
|
||||
--printf( "nTotalOgreSealsToSpawn: %d", nTotalOgreSealsToSpawn )
|
||||
|
||||
for i = 1, nTotalOgreSealsToSpawn do
|
||||
if #self.hOgreSealSpawners > 0 then
|
||||
local nRandomIndex = RandomInt( 1, #self.hOgreSealSpawners )
|
||||
local hRandomOgreSealSpawner = self.hOgreSealSpawners[ nRandomIndex ]
|
||||
|
||||
local vSpawnPos = hRandomOgreSealSpawner:GetAbsOrigin()
|
||||
local hOgreSeal = CreateUnitByName( "npc_dota_creature_wandering_ogre_seal", vSpawnPos, true, nil, nil, DOTA_TEAM_BADGUYS )
|
||||
if hOgreSeal ~= nil then
|
||||
table.insert( self.hOgreSeals, hOgreSeal )
|
||||
table.remove( self.hOgreSealSpawners, nRandomIndex )
|
||||
end
|
||||
else
|
||||
printf( "WARNING - self.hOgreSealSpawners is empty, can't spawn more seals" )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:OnThink()
|
||||
CMapEncounter_BonusBase.OnThink( self )
|
||||
|
||||
if not IsServer() or GameRules:IsGamePaused() then
|
||||
return
|
||||
end
|
||||
|
||||
if not self.bGameStarted then
|
||||
return
|
||||
end
|
||||
|
||||
if self.bGameStarted and not self.bStartedMusic then
|
||||
EmitGlobalSound( "BonusRoom.ParadeMusicLoop" )
|
||||
self.bStartedMusic = true
|
||||
end
|
||||
|
||||
if self:HasStarted() and not self:IsComplete() then
|
||||
if TableLength( self.GoldBags ) >= self.nTotalGoldBagsToSpawn then
|
||||
return
|
||||
end
|
||||
|
||||
if GameRules:GetGameTime() >= self.fNextCoinPileSpawn then
|
||||
local hRandomBagTarget = self.hDynamicBagTargets[ RandomInt( 1, #self.hDynamicBagTargets ) ]
|
||||
local nCoinSpawnsPerTarget = RandomInt( self.nMinCoinsPerTarget, self.nMaxCoinsPerTarget )
|
||||
for i = 1, nCoinSpawnsPerTarget do
|
||||
if TableLength( self.GoldBags ) >= self.nTotalGoldBagsToSpawn then
|
||||
break
|
||||
end
|
||||
|
||||
local vGoldBagPos = self:GetValidCoinSpawnPos( hRandomBagTarget )
|
||||
self.nGoldForBags = self.nGoldForBags - self.nGoldPerBag
|
||||
|
||||
local newItem = CreateItem( "item_bag_of_gold", nil, nil )
|
||||
newItem:SetPurchaseTime( 0 )
|
||||
newItem:SetCurrentCharges( self.nGoldPerBag )
|
||||
|
||||
-- NOTE: CreateItemOnPositionSync will drop the item to the ground, so the z height is going to be ignored
|
||||
-- However, LaunchLootRequiredHeight will fix it back up for us.
|
||||
local drop = CreateItemOnPositionSync( vGoldBagPos, newItem )
|
||||
--drop:SetModelScale( 1.5 )
|
||||
local fHeight = 0
|
||||
newItem:LaunchLootRequiredHeight( true, fHeight, fHeight, 0.75, vGoldBagPos )
|
||||
table.insert( self.GoldBags, newItem )
|
||||
end
|
||||
--printf( "[dynamic] total gold bags: %d", #self.GoldBags )
|
||||
|
||||
self.fNextCoinPileSpawn = GameRules:GetGameTime() + self.fCoinPileCreationInterval
|
||||
end
|
||||
|
||||
--printf( "Total gold bags spawned: %d", TableLength( self.GoldBags ) )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:OnComplete()
|
||||
CMapEncounter_BonusBase.OnComplete( self )
|
||||
|
||||
StopListeningToGameEvent( self.nItemPickedUpListener ) -- redundant? already done in BonusBase
|
||||
|
||||
for _, hPenguin in pairs ( self.Penguins ) do
|
||||
hPenguin:SetOwner( nil )
|
||||
hPenguin:RemoveModifierByName( "modifier_sled_penguin_passive" )
|
||||
end
|
||||
|
||||
for nPlayerID = 0, AGHANIM_PLAYERS - 1 do
|
||||
local hHero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
|
||||
if hHero then
|
||||
hHero:RemoveModifierByName( "modifier_bonus_room_start" )
|
||||
PlayerResource:SetCameraTarget( nPlayerID, nil )
|
||||
PlayerResource:SetOverrideSelectionEntity( nPlayerID, nil )
|
||||
|
||||
local hEndPosition = self:GetRoom():FindAllEntitiesInRoomByName( "bonus_room_end_position", true )
|
||||
FindClearSpaceForUnit( hHero, hEndPosition[1]:GetAbsOrigin(), true )
|
||||
CenterCameraOnUnit( nPlayerID, hHero )
|
||||
end
|
||||
end
|
||||
|
||||
for _,GoldBag in pairs ( self.GoldBags ) do
|
||||
if GoldBag and not GoldBag:IsNull() then
|
||||
UTIL_Remove( GoldBag:GetContainer() )
|
||||
UTIL_Remove( GoldBag )
|
||||
end
|
||||
end
|
||||
|
||||
for _, hOgreSeal in pairs ( self.hOgreSeals ) do
|
||||
if hOgreSeal and not hOgreSeal:IsNull() then
|
||||
UTIL_Remove( hOgreSeal )
|
||||
end
|
||||
end
|
||||
|
||||
StopGlobalSound( "BonusRoom.ParadeMusicLoop" )
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:GetValidCoinSpawnPos( hBagTarget )
|
||||
local fMinOffset = 25
|
||||
local fMaxOffset = 600
|
||||
|
||||
local vPos = hBagTarget:GetAbsOrigin() + RandomVector( RandomFloat( fMinOffset, fMaxOffset ) )
|
||||
|
||||
local nAttempts = 0
|
||||
while ( ( not GridNav:CanFindPath( hBagTarget:GetOrigin(), vPos ) ) and ( nAttempts < 5 ) ) do
|
||||
vPos = hBagTarget:GetOrigin() + RandomVector( fMaxOffset )
|
||||
nAttempts = nAttempts + 1
|
||||
|
||||
if nAttempts >= 5 then
|
||||
vPos = hBagTarget:GetOrigin()
|
||||
end
|
||||
end
|
||||
|
||||
return vPos
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:OnPlayerRidePenguin( nPlayerID, hPenguin )
|
||||
ParticleManager:DestroyParticle( hPenguin.nFXIndex, true )
|
||||
CustomGameEventManager:Send_ServerToPlayer( PlayerResource:GetPlayer( nPlayerID ), "stop_world_text_hint", {} )
|
||||
|
||||
--PlayerResource:SetCameraTarget( nPlayerID, hPenguin )
|
||||
--PlayerResource:SetOverrideSelectionEntity( nPlayerID, hPenguin )
|
||||
|
||||
local nCurrentValue = self:GetEncounterObjectiveProgress( "objective_saddle_up_on_penguin" )
|
||||
local nSaddledPlayers = nCurrentValue + 1
|
||||
self:UpdateEncounterObjective( "objective_saddle_up_on_penguin", nSaddledPlayers, nil )
|
||||
|
||||
local nPlayerCount = 0
|
||||
for nPlayerID = 0, AGHANIM_PLAYERS - 1 do
|
||||
if PlayerResource:GetTeam( nPlayerID ) == DOTA_TEAM_GOODGUYS and PlayerResource:IsValidPlayerID( nPlayerID ) then
|
||||
nPlayerCount = nPlayerCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
if nSaddledPlayers >= nPlayerCount then
|
||||
self:DisableBlocker()
|
||||
self:StartBonusRound( self.flPenguinTimeLimit )
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
function CMapEncounter_PenguinsTransition:DisableBlocker()
|
||||
--print("Disabling Starting Blockers!")
|
||||
-- Disable any nav blockers in the start
|
||||
local hRelays = self:GetRoom():FindAllEntitiesInRoomByName( "starting_relay", false )
|
||||
for _, hRelay in pairs( hRelays ) do
|
||||
hRelay:Trigger( nil, nil )
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
return CMapEncounter_PenguinsTransition
|
||||
Reference in New Issue
Block a user