fortressforever-scripts/maps/includes/base_training.lua

659 lines
23 KiB
Lua

-- base_training.lua
-- contains common useful functionality for maps that include training elements.
IncludeScript("base_teamplay")
IncludeScript("base_respawnturret")
-----------------------------------------------------------------------------
-- helper functions
-----------------------------------------------------------------------------
function restoreEntityByName(name)
local e = GetInfoScriptByName(name)
if e ~= nil then e:Restore() end
end
-----------------------------------------------------------------------------
-- glass
-----------------------------------------------------------------------------
breakable_glass = info_ff_script:new({ })
function breakable_glass:spawn() end
function breakable_glass:OnBreak()
if self.BotSignal ~= nil then
bot.signal(self.BotSignal.."_OnBreak")
end
end
function breakable_glass:ondamage() end
-----------------------------------------------------------------------------
-- Class specific trainer spawns
-----------------------------------------------------------------------------
training_spawn = info_ff_script:new({
name="Trainer",
model="",
botteam=Team.kYellow,
botclass=0,
botgoaltype=Bot.kTrainerSpawn,
})
function training_spawn:spawn()
info_ff_script.spawn(self)
local info = CastToInfoScript(entity)
info:SpawnBot(self.name, self.botteam, self.botclass);
end
scout_trainer = training_spawn:new({ name="Scout Instructor", botclass=Player.kScout, })
sniper_trainer = training_spawn:new({ name="Sniper Instructor", botclass=Player.kSniper, })
soldier_trainer = training_spawn:new({ name="Soldier Instructor", botclass=Player.kSoldier, })
demoman_trainer = training_spawn:new({ name="Demo-man Instructor", botclass=Player.kDemoman, })
medic_trainer = training_spawn:new({ name="Medic Instructor", botclass=Player.kMedic, })
hwguy_trainer = training_spawn:new({ name="HwGuy Instructor", botclass=Player.kHwguy, })
pyro_trainer = training_spawn:new({ name="Pyro Instructor", botclass=Player.kPyro, })
engineer_trainer = training_spawn:new({ name="Engineer Instructor", botclass=Player.kEngineer, })
spy_trainer = training_spawn:new({ name="Spy Instructor", botclass=Player.kSpy, })
civilian_trainer = training_spawn:new({ name="Civilian Instructor", botclass=Player.kCivilian, })
random_target = training_spawn:new({ name="Target", botclass=Player.kRandom, })
-----------------------------------------------------------------------------
-- Training buttons
-----------------------------------------------------------------------------
train_button = func_button:new({})
function train_button:allowed() return true end
function train_button:ondamage() end
function train_button:ontouch() end
function train_button:onuse()
if self.restoreentity ~= nil then
local e = GetInfoScriptByName(self.restoreentity)
if e ~= nil then
e:Restore()
else
ConsoleToAll("Could not restore " .. self.restoreentity)
end
end
bot.signal(entity:GetName())
ConsoleToAll(entity:GetName() .. " onuse")
end
function train_button:onfailuse()
ConsoleToAll("button failuse")
end
-----------------------------------------------------------------------------
-- Fake weapon pickups
-----------------------------------------------------------------------------
fakeweapon_spawn = info_ff_script:new({
model = "models/items/backpack/backpack.mdl",
weaponname = "ff_weapon_crowbar",
ammo = {},
touchsound = "HealthKit.Touch",
materializesound = "Item.Materialize",
respawntime = 5,
removeOnSpawn = false,
touchflags = {AllowFlags.kOnlyPlayers,AllowFlags.kBlue, AllowFlags.kRed, AllowFlags.kYellow, AllowFlags.kGreen}
})
function fakeweapon_spawn:spawn()
-- temporary override
--self.model = "models/items/backpack/backpack.mdl"
info_ff_script.spawn(self)
local info = CastToInfoScript(entity)
if self.removeOnSpawn then
info:Remove()
end
end
function fakeweapon_spawn:precache( )
PrecacheSound(self.materializesound)
PrecacheSound(self.touchsound)
--PrecacheModel(self.model)
end
function fakeweapon_spawn:materialize( )
entity:EmitSound(self.materializesound)
end
function fakeweapon_spawn:touch( touch_entity )
if IsPlayer( touch_entity ) then
local player = CastToPlayer( touch_entity )
local dispensed = 0
if self.weaponclass ~= nil and not player:OwnsWeaponType(self.weaponclass) then
player:GiveWeapon(self.weaponclass)
dispensed = dispensed + 1
end
if self.weaponclass2 ~= nil and not player:OwnsWeaponType(self.weaponclass2) then
player:GiveWeapon(self.weaponclass2)
dispensed = dispensed + 1
end
-- give player some health and armor
if self.health ~= nil and self.health ~= 0 then player:AddHealth(self.health) end
if self.armor ~= nil and self.armor ~= 0 then player:AddArmor(self.armor) end
-- give the player some ammo
if self.nails ~= nil and self.nails ~= 0 then player:AddAmmo(Ammo.kNails, self.nails) end
if self.shells ~= nil and self.shells ~= 0 then player:AddAmmo(Ammo.kShells, self.shells) end
if self.rockets ~= nil and self.rockets ~= 0 then player:AddAmmo(Ammo.kRockets, self.rockets) end
if self.cells ~= nil and self.cells ~= 0 then player:AddAmmo(Ammo.kCells, self.cells) end
if self.detpacks ~= nil and self.detpacks ~= 0 then player:AddAmmo(Ammo.kDetpack, self.detpacks) end
if self.mancannons ~= nil and self.mancannons ~= 0 then player:AddAmmo(Ammo.kManCannon, self.mancannons) end
if self.gren1 ~= nil and self.gren1 ~= 0 then player:AddAmmo(Ammo.kGren1, self.gren1) end
if self.gren2 ~= nil and self.gren2 ~= 0 then player:AddAmmo(Ammo.kGren2, self.gren2) end
if dispensed > 0 then
local item = CastToInfoScript(entity);
item:EmitSound(self.touchsound)
-- Do this or don't call Respawn?
--item:SetStartOrigin(item:GetOrigin())
--item:SetStartAngles(item:GetAngles())
--item:Remove()
--item:Respawn(self.respawntime);
end
end
end
function fakeweapon_spawn:add_weapon( weaponname )
ConsoleToAll("fakeweapon_spawn:add_weapon " .. weaponname)
self.weaponclass2 = weaponname
end
-----------------------------------------------------------------------------
-- Weapon pickup variations.
-----------------------------------------------------------------------------
weapon_assaultcannon = fakeweapon_spawn:new({ model = "models/weapons/assaultcannon/w_assaultcannon.mdl", weaponclass = "ff_weapon_assaultcannon", shells = 400 })
weapon_autorifle = fakeweapon_spawn:new({ model = "models/weapons/autorifle/w_autorifle.mdl", weaponclass = "ff_weapon_autorifle", shells = 400 })
weapon_crowbar = fakeweapon_spawn:new({ model = "models/weapons/crowbar/w_crowbar.mdl", weaponclass = "ff_weapon_crowbar", })
weapon_flamethrower = fakeweapon_spawn:new({ model = "models/weapons/flamethrower/w_flamethrower.mdl", weaponclass = "ff_weapon_flamethrower", cells = 400 })
weapon_grenadelauncher = fakeweapon_spawn:new({ model = "models/weapons/grenadelauncher/w_grenadelauncher.mdl", weaponclass = "ff_weapon_grenadelauncher", rockets = 400 })
weapon_incendiarycannon = fakeweapon_spawn:new({ model = "models/weapons/incendiarycannon/w_incendiarycannon.mdl", weaponclass = "ff_weapon_ic", rockets = 400 })
weapon_knife = fakeweapon_spawn:new({ model = "models/weapons/knife/w_knife.mdl", weaponclass = "ff_weapon_knife" })
weapon_medkit = fakeweapon_spawn:new({ model = "models/weapons/medkit/w_medkit.mdl", weaponclass = "ff_weapon_medkit" })
weapon_nailgun = fakeweapon_spawn:new({ model = "models/weapons/nailgun/w_nailgun.mdl", weaponclass = "ff_weapon_nailgun", nails = 400 })
weapon_pipelauncher = fakeweapon_spawn:new({ model = "models/weapons/pipelauncher/w_pipelauncher.mdl", weaponclass = "ff_weapon_pipelauncher", rockets = 400 })
weapon_railgun = fakeweapon_spawn:new({ model = "models/weapons/railgun/w_railgun.mdl", weaponclass = "ff_weapon_railgun", nails = 400 })
weapon_rpg = fakeweapon_spawn:new({ model = "models/weapons/rpg/w_rpg.mdl", weaponclass = "ff_weapon_rpg", rockets = 400 })
weapon_shotgun = fakeweapon_spawn:new({ model = "models/weapons/shotgun/w_shotgun.mdl", weaponclass = "ff_weapon_shotgun", shells = 400 })
weapon_sniperrifle = fakeweapon_spawn:new({ model = "models/weapons/sniperrifle/w_sniperrifle.mdl", weaponclass = "ff_weapon_sniperrifle", nails = 400 })
weapon_spanner = fakeweapon_spawn:new({ model = "models/weapons/spanner/w_spanner.mdl", weaponclass = "ff_weapon_spanner" })
weapon_supernailgun = fakeweapon_spawn:new({ model = "models/weapons/supernailgun/w_supernailgun.mdl", weaponclass = "ff_weapon_supernailgun", nails = 400 })
weapon_supershotgun = fakeweapon_spawn:new({ model = "models/weapons/supershotgun/w_supershotgun.mdl", weaponclass = "ff_weapon_supershotgun", shells = 400 })
weapon_tommygun = fakeweapon_spawn:new({ model = "models/weapons/tommygun/w_tommygun.mdl", weaponclass = "ff_weapon_tommygun", shells = 400 })
weapon_tranq = fakeweapon_spawn:new({ model = "models/weapons/tranq/w_tranq.mdl", weaponclass = "ff_weapon_tranq", nails = 400 })
weapon_umbrella = fakeweapon_spawn:new({ model = "models/weapons/umbrella/w_umbrella.mdl", weaponclass = "ff_weapon_umbrella" })
grenade_pack = fakeweapon_spawn:new({ model = "models/items/backpack/backpack.mdl", gren1 = 4, gren2 = 4 })
weapon_sentry = fakeweapon_spawn:new({ weaponclass = "ff_weapon_deploysentrygun" })
weapon_dispenser = fakeweapon_spawn:new({ weaponclass = "ff_weapon_deploydispenser" })
-----------------------------------------------------------------------------
-- class scanner triggers
-----------------------------------------------------------------------------
function perform_player_scan(player, expectedclass, respawnturret)
if expectedclass ~= player:GetClass() then
BroadCastMessage("Wrong Class")
respawnturret.killplayer = true
else
--BroadCastMessage("Wrong Class")
end
end
scanner_class = trigger_ff_script:new({ })
function scanner_class:ontouch( touch_entity )
if IsPlayer( touch_entity ) then
local p = CastToPlayer( touch_entity )
if not p:IsBot() then
AddSchedule("perform_player_scan", 0, perform_player_scan, p, self.class, self.turret)
end
end
end
function scanner_class:onendtouch()
RemoveSchedule("perform_player_scan")
end
scout_scanner = scanner_class:new({ class=Player.kScout, })
sniper_scanner = scanner_class:new({ class=Player.kSniper, })
soldier_scanner = scanner_class:new({ class=Player.kSoldier, })
demoman_scanner = scanner_class:new({ class=Player.kDemoman, })
medic_scanner = scanner_class:new({ class=Player.kMedic, })
hwguy_scanner = scanner_class:new({ class=Player.kHwguy, })
pyro_scanner = scanner_class:new({ class=Player.kPyro, })
engineer_scanner = scanner_class:new({ class=Player.kEngineer, })
spy_scanner = scanner_class:new({ class=Player.kSpy, })
civilian_scanner = scanner_class:new({ class=Player.kCivilian, })
-----------------------------------------------------------------------------
-- class turrets
-----------------------------------------------------------------------------
scanner_turret = respawnturret:new({ team = Team.kGreen })
function scanner_turret:deploydelay( target_entity ) return 0.5 end
function scanner_turret:validtarget( target_entity )
--local entity = GetEntity(ent_id)
if self.killplayer then
local player = CastToPlayer( target_entity )
if player ~= nil and not player:IsBot() then
return true
end
end
if not AreTeamsAllied(self.team, target_entity:GetTeamId()) then return true end
return false
end
scout_turret = scanner_turret:new({ class=Player.kScout, })
sniper_turret = scanner_turret:new({ class=Player.kSniper, })
soldier_turret = scanner_turret:new({ class=Player.kSoldier, })
demoman_turret = scanner_turret:new({ class=Player.kDemoman, })
medic_turret = scanner_turret:new({ class=Player.kMedic, })
hwguy_turret = scanner_turret:new({ class=Player.kHwguy, })
pyro_turret = scanner_turret:new({ class=Player.kPyro, })
engineer_turret = scanner_turret:new({ class=Player.kEngineer, })
spy_turret = scanner_turret:new({ class=Player.kSpy, })
civilian_turret = scanner_turret:new({ class=Player.kCivilian, })
-----------------------------------------------------------------------------
-- class holograms
-----------------------------------------------------------------------------
base_hologram = info_ff_script:new({ model = "models/player/pyro/pyro.mdl", renderfx = RenderFx.kHologram })
scout_hologram = base_hologram:new({ model = "models/player/scout/scout.mdl" })
sniper_hologram = base_hologram:new({ model = "models/player/sniper/sniper.mdl" })
soldier_hologram = base_hologram:new({ model = "models/player/soldier/soldier.mdl" })
demoman_hologram = base_hologram:new({ model = "models/player/demoman/demoman.mdl" })
medic_hologram = base_hologram:new({ model = "models/player/medic/medic.mdl" })
hwguy_hologram = base_hologram:new({ model = "models/player/hwguy/hwguy.mdl" })
pyro_hologram = base_hologram:new({ model = "models/player/pyro/pyro.mdl" })
engineer_hologram = base_hologram:new({ model = "models/player/engineer/engineer.mdl" })
spy_hologram = base_hologram:new({ model = "models/player/spy/spy.mdl" })
-----------------------------------------------------------------------------
-- Beams
-----------------------------------------------------------------------------
base_beam = baseclass:new({ startstate="on",startcolor="0 255 0" })
function base_beam:spawn()
if startstate == "on" then
OutputEvent( entity:GetName(), "TurnOn" )
else
OutputEvent( entity:GetName(), "TurnOff" )
end
if startstate ~= nil then
OutputEvent( entity:GetName(), "Color", startcolor )
end
end
function base_beam:turnon()
OutputEvent( entity:GetName(), "TurnOn" )
end
function base_beam:turnoff()
OutputEvent( entity:GetName(), "TurnOff" )
end
function base_beam:setcolor(newcolor)
if newcolor ~= nil then
OutputEvent( entity:GetName(), "Color", newcolor )
end
end
-----------------------------------------------------------------------------
-- training room triggers
-----------------------------------------------------------------------------
training_room = trigger_ff_script:new({ })
function training_room:allowed()
-- if self.restrictClass ~= nil then
-- entity:EmitSound(self.speakOnceOnEnter)
-- end
return EVENT_ALLOWED
end
function training_room:ontrigger()
--ConsoleToAll("training_room:ontrigger() ")
end
function training_room:ontouch( touch_entity )
if IsPlayer( touch_entity ) then
local p = CastToPlayer( touch_entity )
if not p:IsBot() then
bot.signal(entity:GetName())
end
end
------------------
ConsoleToAll(entity:GetName() .. " ontouch")
------------------
end
function training_room:onendtouch()
------------------
ConsoleToAll(entity:GetName() .. " onendtouch")
------------------
end
function training_room:onfailtouch()
end
function training_room:onexplode()
return EVENT_ALLOWED
end
function training_room:onbuild()
return EVENT_ALLOWED
end
function training_room:onfailuse()
end
function training_room:onuse()
end
function training_room:onactive()
end
function training_room:oninactive()
end
function training_room:onremoved()
end
function training_room:onrestored()
end
function training_room:spawn()
end
-----------------------------------------------------------------------------
-- current training status
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- bot helper functions
-----------------------------------------------------------------------------
function restore_entity(entname)
local info = GetInfoScriptByName(entname)
if info ~= nil then
info:Restore()
end
end
function remove_entity(entname)
local info = GetInfoScriptByName(entname)
if info ~= nil then
info:Remove()
end
end
function update_grenadecount(entname, g1, g2)
local info = GetInfoScriptByName(entname)
if info ~= nil then
info.gren1 = tonumber(g1)
info.gren2 = tonumber(g2)
end
end
function vec_tostring(v)
return string.format("%f %f %f", v.x, v.y, v.z)
end
bot = {}
bot.spawnAtEntity = function(spawnent, name, team, class)
local info = GetInfoScriptByName(spawnent)
if info ~= nil then
info:SpawnBot(name, team, class);
end
end
bot.sendMsg = function(botname, msg, d1, d2, d3)
local p = GetPlayerByName(botname)
if p ~= nil then
p:SendBotMessage(msg, d1, d2, d3)
else
ConsoleToAll("bot.sendMsg: player not found: " .. botname)
end
end
bot.signal = function(signalname)
SendBotSignal(signalname)
end
bot.moveTo = function(botname, targetentity)
local e = GetEntityByName(targetentity)
if e ~= nil then
local epos = e:GetOrigin()
local eface = e:GetAbsFacing()
-- convert epos to string
bot.sendMsg(botname, "run_to", vec_tostring(epos), vec_tostring(eface))
end
end
bot.setIdlePoint = function(botname, targetentity)
local e = GetEntityByName(targetentity)
if e ~= nil then
local epos = e:GetOrigin()
local eface = e:GetAbsFacing()
-- convert epos to string
bot.sendMsg(botname, "set_idle_position", vec_tostring(epos), vec_tostring(eface))
end
end
bot.leaveGame = function(botname)
bot.sendMsg(botname, "leave_game")
end
-- teleportTo(botname, targetEntName)
-- local p = GetPlayerByName(botname)
-- local e = GetEntityByName(targetentity)
-- if p ~= nil and e ~= nil then
-- p:SetOrigin(e:GetOrigin())
-- p:SetAngles(e:GetAngles())
-- else
-- ConsoleToAll("teleportTo: player not found: " .. botname)
-- end
-- end
function player_giveweapon(weaponname, as)
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
local autoselect = false
if as == "true" then autoselect = true end
player:GiveWeapon(weaponname, autoselect)
end
end
function player_giveammo(ammoname, amount)
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
if ammoname == "nails" then player:AddAmmo(Ammo.kNails, tonumber(amount)) end
if ammoname == "shells" then player:AddAmmo(Ammo.kShells, tonumber(amount)) end
if ammoname == "rockets" then player:AddAmmo(Ammo.kRockets, tonumber(amount)) end
if ammoname == "cells" then player:AddAmmo(Ammo.kCells, tonumber(amount)) end
if ammoname == "detpack" then player:AddAmmo(Ammo.kDetpack, tonumber(amount)) end
if ammoname == "mancannon" then player:AddAmmo(Ammo.kManCannon, tonumber(amount)) end
if ammoname == "gren1" then player:AddAmmo(Ammo.kGren1, tonumber(amount)) end
if ammoname == "gren2" then player:AddAmmo(Ammo.kGren2, tonumber(amount)) end
end
end
function player_removeweapon(weaponname)
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
player:RemoveWeapon(weaponname)
end
end
function player_givedetpack()
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
player:AddAmmo(Ammo.kDetpack, 1)
end
end
function player_givemancannon()
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
player:AddAmmo(Ammo.kManCannon, 1)
end
end
function player_givegren1()
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
player:AddAmmo(Ammo.kGren1, 4)
end
end
function player_givegren2()
local c = Collection()
c:GetByFilter({ CF.kHumanPlayers })
for temp in c.items do
local player = CastToPlayer( temp )
player:AddAmmo(Ammo.kGren2, 4)
end
end
function player_removehealth(playername, amt)
p = GetPlayerByName(playername)
if p ~= nil then
p:AddHealth(-tonumber(amt))
else
ConsoleToAll("player_removehealth: Unable to find " .. playername)
end
end
function player_removearmor(playername, amt)
p = GetPlayerByName(playername)
if p ~= nil then
p:RemoveArmor(tonumber(amt))
else
ConsoleToAll("player_removehealth: Unable to find " .. playername)
end
end
function player_forcerespawn(playername, amt)
p = GetPlayerByName(playername)
if p ~= nil then
ApplyToPlayer(p, { AT.kRespawnPlayers })
else
ConsoleToAll("player_forcerespawn: Unable to find " .. playername)
end
end
function broadcast_message(message)
BroadCastMessage(message)
end
function training_intro(classname)
if classname == "Scout" then
BroadCastSound("training.fem_scout_ovr")
elseif classname == "Sniper" then
BroadCastSound("training.fem_sniper_ovr")
elseif classname == "Soldier" then
BroadCastSound("training.fem_soldier_ovr")
elseif classname == "Demoman" then
BroadCastSound("training.fem_demo_ovr")
elseif classname == "Medic" then
BroadCastSound("training.fem_medic_ovr")
elseif classname == "HwGuy" then
BroadCastSound("training.fem_hwguy_ovr")
elseif classname == "Pyro" then
BroadCastSound("training.fem_pyro_ovr")
elseif classname == "Spy" then
BroadCastSound("training.fem_spy_ovr")
elseif classname == "Engineer" then
BroadCastSound("training.fem_engy_ovr")
end
end
function section_complete(sectionname, room)
BroadCastSound("training.section_complete")
end
function training_complete(classname)
if classname == "Scout" then
BroadCastSound("training.fem_scout_comp")
elseif classname == "Sniper" then
BroadCastSound("training.fem_sniper_comp")
elseif classname == "Soldier" then
BroadCastSound("training.fem_soldier_comp")
elseif classname == "Demoman" then
BroadCastSound("training.fem_demo_comp")
elseif classname == "Medic" then
BroadCastSound("training.fem_medic_comp")
elseif classname == "HwGuy" then
BroadCastSound("training.fem_hwguy_comp")
elseif classname == "Pyro" then
BroadCastSound("training.fem_pyro_comp")
elseif classname == "Spy" then
BroadCastSound("training.fem_spy_comp")
elseif classname == "Engineer" then
BroadCastSound("training.fem_engy_comp")
end
end
function training_classname(classId)
if classId == Player.kScout then return "Scout" end
if classId == Player.kSniper then return "Sniper" end
if classId == Player.kSoldier then return "Soldier" end
if classId == Player.kDemoman then return "Demoman" end
if classId == Player.kMedic then return "Medic" end
if classId == Player.kHwguy then return "HwGuy" end
if classId == Player.kPyro then return "Pyro" end
if classId == Player.kSpy then return "Spy" end
if classId == Player.kEngineer then return "Engineer" end
if classId == Player.kCivilian then return "Civilian" end
end