local DRILLTANK_WATERMINE_VALUES_TABLE = { DRILLTANK_WATERMINE_MODEL = "models/bots/boss_bot/drill_tank/drill_tank.mdl" DRILLTANK_WATERMINE_MODEL_DAMAGE1 = "models/bots/boss_bot/drill_tank/drill_tank_damage1.mdl" DRILLTANK_WATERMINE_MODEL_DAMAGE2 = "models/bots/boss_bot/drill_tank/drill_tank_damage2.mdl" DRILLTANK_WATERMINE_MODEL_DAMAGE3 = "models/bots/boss_bot/drill_tank/drill_tank_damage3.mdl" DRILLTANK_WATERMINE_DAMAGE = 10 DRILLTANK_WATERMINE_DAMAGE_DELAY = 0.05 DRILLTANK_WATERMINE_DAMAGE_SPEED_PENALTY = 0.3 DRILLTANK_WATERMINE_DAMAGE_DEBUFF_DURATION = 1 DRILLTANK_WATERMINE_FRIENDLY_FIRE = true DRILLTANK_WATERMINE_SOUND_SPIN1 = ")ambient/machines/machine_whine1.wav" DRILLTANK_WATERMINE_SOUND_SPIN2 = ")ambient/machines/spin_loop.wav" DRILLTANK_WATERMINE_HATCH_PARTICLE1 = "rocketbackblastsparks" DRILLTANK_WATERMINE_HATCH_PARTICLE2 = "halloween_boss_axe_hit_world" } foreach(k,v in DRILLTANK_WATERMINE_VALUES_TABLE) if(!(k in TankExtPacked.ValueOverrides)) ROOT[k] <- v PrecacheModel(DRILLTANK_WATERMINE_MODEL) PrecacheModel(DRILLTANK_WATERMINE_MODEL_DAMAGE1) PrecacheModel(DRILLTANK_WATERMINE_MODEL_DAMAGE2) PrecacheModel(DRILLTANK_WATERMINE_MODEL_DAMAGE3) TankExtPacked.PrecacheSound(DRILLTANK_WATERMINE_SOUND_SPIN1) TankExtPacked.PrecacheSound(DRILLTANK_WATERMINE_SOUND_SPIN2) PrecacheSound(")ambient/sawblade.wav") PrecacheSound("ambient/sawblade.wav") PrecacheSound("physics/metal/canister_scrape_smooth_loop1.wav") ::DrillTankWatermineEvents <- { function OnGameEvent_recalculate_holidays(_) { if(GetRoundState() == 3) delete ::DrillTankWatermineEvents } function OnScriptHook_OnTakeDamage(params) { local hVictim = params.const_entity local hAttacker = params.attacker if(hVictim && hAttacker && hAttacker.GetClassname() == "tank_boss") { local DrillScope = TankExtPacked.GetMultiScopeTable(hAttacker.GetScriptScope(), "drilltank_watermine") if(DrillScope) params.force_friendly_fire = DRILLTANK_WATERMINE_FRIENDLY_FIRE } } } __CollectGameEventCallbacks(DrillTankWatermineEvents) TankExtPacked.NewTankType("drilltank_watermine", { DisableBomb = 1 Model = { Default = DRILLTANK_WATERMINE_MODEL Damage1 = DRILLTANK_WATERMINE_MODEL_DAMAGE1 Damage2 = DRILLTANK_WATERMINE_MODEL_DAMAGE2 Damage3 = DRILLTANK_WATERMINE_MODEL_DAMAGE3 } function OnSpawn() { EmitSoundEx({ sound_name = DRILLTANK_WATERMINE_SOUND_SPIN1 sound_level = 80 pitch = 85 entity = self filter_type = RECIPIENT_FILTER_GLOBAL }) EmitSoundEx({ sound_name = DRILLTANK_WATERMINE_SOUND_SPIN2 sound_level = 80 pitch = 85 entity = self filter_type = RECIPIENT_FILTER_GLOBAL }) local bFinalSkin = self.GetSkin() == 1 local bBlueTeam = self.GetTeam() == TF_TEAM_BLUE self.SetSkin(bBlueTeam ? bFinalSkin ? 3 : 2 : bFinalSkin ? 1 : 0) local hDrillHurt = TankExtPacked.SpawnEntityFromTableSafe("trigger_multiple", { origin = "130 0 90" spawnflags = 1 }) hDrillHurt.SetSize(Vector(-42, -64, -64), Vector(42, 64, 64)) hDrillHurt.SetSolid(SOLID_OBB) hDrillHurt.ConnectOutput("OnStartTouch", "StartTouch") hDrillHurt.ConnectOutput("OnEndTouch", "EndTouch") TankExtPacked.SetParentArray([hDrillHurt], self) local hTank = self local hTouching = {} hDrillHurt.ValidateScriptScope() hDrillHurt.GetScriptScope().StartTouch <- function() { local iPlayerTeamNum = activator.GetTeam() if(DRILLTANK_WATERMINE_FRIENDLY_FIRE || iPlayerTeamNum != hTank.GetTeam()) { if(hTouching.len() == 0) EmitSoundEx({ sound_name = ")ambient/sawblade.wav" sound_level = 85 pitch = 90 entity = hTank filter_type = RECIPIENT_FILTER_GLOBAL }) hTouching[activator] <- iPlayerTeamNum } } hDrillHurt.GetScriptScope().EndTouch <- function() { if(activator in hTouching) { if(hTouching.len() == 1) EmitSoundEx({ sound_name = ")ambient/sawblade.wav" entity = hTank filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_STOP }) delete hTouching[activator] } } local bDeploying = false local flTimeDeployStart = 0 local flTimeSparkLast = 0 local flTimeDrillLast = 0 local vecDeploy = Vector() function Think() { if(flTime >= flTimeDrillLast) { flTimeDrillLast = flTime + DRILLTANK_WATERMINE_DAMAGE_DELAY local bPlayDrillSound = false foreach(hPlayer, iPlayerTeamNum in hTouching) if(hPlayer.IsValid()) { bPlayDrillSound = true hPlayer.TakeDamageEx(self, self, null, Vector(), Vector(), DRILLTANK_WATERMINE_DAMAGE, DMG_CRUSH) hPlayer.BleedPlayer(DRILLTANK_WATERMINE_DAMAGE_DEBUFF_DURATION) hPlayer.StunPlayer(DRILLTANK_WATERMINE_DAMAGE_DEBUFF_DURATION, 1 - DRILLTANK_WATERMINE_DAMAGE_SPEED_PENALTY, 1, null) } else delete hTouching[hPlayer] } if(bDeploying) { local flTimeDiff = flTime - flTimeDeployStart local flPercent = flTimeDiff / 8.0 if(flPercent < 1 && flTimeDiff >= 4.5) { EmitSoundEx({ sound_name = DRILLTANK_WATERMINE_SOUND_SPIN1 pitch = flPercent < 1 ? 170 * flPercent : 100 entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_CHANGE_PITCH }) EmitSoundEx({ sound_name = DRILLTANK_WATERMINE_SOUND_SPIN2 pitch = flPercent < 1 ? 170 * flPercent : 100 entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_CHANGE_PITCH }) } if(flPercent < 1 && flTimeDiff >= 5) { EmitSoundEx({ sound_name = "ambient/sawblade.wav" pitch = 150 - flPercent * 70 entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = flPercent < 1 ? SND_CHANGE_PITCH : SND_STOP }) if(flTime - flTimeSparkLast >= 0.01) { flTimeSparkLast = flTime local vecTowards = Vector(0.7, 0, 0.7) local vecOffset = Vector(flPercent * 61) local flAngleOffset = RandomFloat(0, 360) for(local i = 1; i <= 8; i++) { local Rotate = @(Input) RotatePosition(Vector(), QAngle(0, flAngleOffset + 45 * i), Input) DispatchParticleEffect(RandomInt(0, 4) ? DRILLTANK_WATERMINE_HATCH_PARTICLE1 : DRILLTANK_WATERMINE_HATCH_PARTICLE2, vecDeploy + Rotate(vecOffset), Rotate(vecTowards)) } } } } else if(!bDeploying && self.GetSequenceName(self.GetSequence()) == "deploy") { flTimeDeployStart = Time() bDeploying = true vecDeploy = vecOrigin + self.GetForwardVector() * 194 self.StopSound("MVM.TankDeploy") TankExtPacked.DelayFunction(self, this, 1, function() { self.EmitSound("MVM.TankDeploy") }) TankExtPacked.DelayFunction(self, this, 2 function() { hDrillHurt.SetLocalOrigin(Vector(176, 0, 40)) hDrillHurt.SetSize(Vector(-64, -64, -40), Vector(64, 64, 40)) }) TankExtPacked.DelayFunction(self, this, 4.3, function() { self.StopSound("MVM.TankDeploy") }) TankExtPacked.DelayFunction(self, this, 5, function() { EmitSoundEx({ sound_name = "physics/metal/canister_scrape_smooth_loop1.wav" pitch = 100 entity = self filter_type = RECIPIENT_FILTER_GLOBAL }) }) TankExtPacked.DelayFunction(self, this, 8, function() { EmitSoundEx({ sound_name = "physics/metal/canister_scrape_smooth_loop1.wav" entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_STOP }) EmitSoundEx({ sound_name = "ambient/sawblade.wav" entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_STOP }) EmitSoundEx({ sound_name = DRILLTANK_WATERMINE_SOUND_SPIN1 pitch = 100 entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_CHANGE_PITCH }) EmitSoundEx({ sound_name = DRILLTANK_WATERMINE_SOUND_SPIN2 pitch = 100 entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_CHANGE_PITCH }) }) } } } function OnDeath() { self.StopSound("MVM.TankDeploy") EmitSoundEx({ sound_name = "misc/null.wav" entity = self filter_type = RECIPIENT_FILTER_GLOBAL flags = SND_STOP | SND_IGNORE_NAME }) } })