#base robot_giant.pop #base robot_standard.pop // This is an example mission with vscript and popextensions // Functions provided by popextensions are defined at the end of the file WaveSchedule { StartingCurrency 1200 RespawnWaveTime 2 CanBotsAttackWhileInSpawnRoom 1 Mission { Objective Engineer InitialCooldown 0 Where spawnbot BeginAtWave 1 RunForThisManyWaves 1 CooldownTime 1 DesiredCount 1 TFBot { // Template T_TFBot_Engineer_Sentry_Teleporter Template T_TFBot_Engineer_Sentry_Tele_Battle Tag "popext_dispenseroverride|2" // Attributes AlwaysFireWeapon } } Wave { // Add or replace existing InitWaveOutput with code below InitWaveOutput { Target bignet Action RunScriptCode Param " // The original InitWaveOutput trigger, change if necessary // EntFire(`wave_init_relay`, `Trigger`) // Load popextensions script IncludeScript(`popextensions_main`, getroottable()) MissionAttrs({ NoReanimators = 1 ForceHoliday = 8 NoRome = 2 BotHeadshots = 1 NoCrumpkins = 1 WaveStartCountdown = 3 PlayersAreRobots = 1|8|16 //see missionattributes.nut for bitflag info ReverseMVM = 1|2|8|16|32|64 //see missionattributes.nut for bitflag info SpellRateCommon = 0.5 NoSkeleSplit = 1 WaveNum = 3 MaxWaveNum = 60 StandableHeads = 1 MultiSapper = 1 TeamWipeWaveLoss = 1 GiantSentryKillCountOffset = -4 SoundOverrides = { //overrides teamplay_broadcast_audio sounds `Announcer.MVM_Get_To_Upgrade`: null `music.mvm_end_last_wave`: null `Game.YourTeamWon`: null `MVM.PlayerDied`: null } AddCond = [32, 10] //speed boost for 10s PlayerAttributes = { `damage bonus`: 10, `can breathe under water`: 1, `mult swim speed`: 3, `teleport instead of die`: 1, `crit when health below`: 75, [TF_CLASS_SCOUT] = { `damage bonus` : 5, `fire rate penalty` : 2, `max health additive bonus` : 100, }, [TF_CLASS_SOLDIER] = { `damage penalty` : 0.5, `fire rate bonus` : 0.5, `mult dmg vs same class`: 10 }, [TF_CLASS_DEMOMAN] = { `fire rate bonus` : 0.5, } }, ItemAttributes = { tf_weapon_scattergun = { `max health additive bonus` : 100 `fire rate bonus` : 0.5 `Reload time decreased` : 0.5 `clip size bonus` : 2 `reloads full clip at once`: 1 `passive reload`: 1 `collect currency on kill`: 1 }, tf_weapon_rocketlauncher = { //string with no spaces (like item classnames) can use this syntax `projectile gravity`: 10 `fire rate penalty` : 3 `damage bonus` : 10 `custom projectile model`: `models/player/heavy.mdl` `add cond when active`: 91 // `self add cond on hit`: [91, 1] }, tf_weapon_pistol = { `passive reload`: 1 }, tf_weapon_shotgun = { `reloads full clip at once`: 1 } tf_weapon_crossbow = { `fires milk bolt`: 1 `set turn to ice`: 1 `radius sleeper`: 1 }, [132] = { //item id, eyelander `melee cleave attack`: 32 `stun on hit`: { duration = 4 type = 2 speedmult = 0.2 stungiants = true } }, tf_weapon_wrench = { // `mult teleporter recharge rate` : 2 `build small sentries`: 1 }, `The Sydney Sleeper`: { //localized name in items_game.txt/item_map.nut `radius sleeper`: 1 `explosive bullets ext`: { damage = 300 radius = 100 team = TF_TEAM_RED } } `The Sandman` : { //strings with spaces require this syntax. `old sandman stun`: 1 } `Iron Curtain` : { `alt-fire disabled`: 1 } } }) //parameters: text, prefix color, prefix text, sync with game_text true/false Info(`This is an explanation text example|PAUSE 2|Explanation text can support pauses, and optionally syncing chat prints with the game_text|By default, text lifetime is determined by the length of the sentence|See PopExtUtil::Explanation in util.nut for more info`, `FFFF66`, `Explanation: `, true) " } StartWaveOutput { Target wave_start_relay Action Trigger } DoneOutput { Target wave_finished_relay Action trigger } // WaveSpawn // { // Name "Wave1" // Where spawnbot // TotalCount 50 // MaxActive 5 // SpawnCount 5 // WaitBeforeStarting 0 // TotalCurrency 200 // TFBot // { // // Tag "popext_forceromevision" // // Tag "popext_addcond|32|10" // // Tag "popext_usehumanmodel" // // Tag "popext_alwaysglow" // // Tag "popext_usebestweapon" // // Tag "popext_giveweapon|tf_weapon_shotgun_pyro|425" //family business // // Tag "popext_homingprojectile|1.0|1.0" // // Tag "popext_improvedairblast" // // Tag "popext_usehumananims" // // Tag "popext_spell|11|5|2" // // Tag "popext_ringoffire|20|2" // Tag "popext_meleeai" // Tag "popext_reprogrammed" // // Tag "popext_weaponswitch|2" // // Tag "popext_weaponresist|tf_weapon_minigun|99999" // // Tag "popext_weaponresist|11|0.01" //stock heavy shotgun // Class Pyro // Skill Hard // // Item "The Thermal Thruster" // // Item "TF_WEAPON_SPELLBOOK" // // Attributes IgnoreEnemies // // WeaponRestrictions PrimaryOnly // CharacterAttributes // { // "damage bonus" -10 // } // } // } WaveSpawn { Name "Wave1a" Where spawnbot TotalCount 10 MaxActive 5 SpawnCount 5 WaitBeforeStarting 1 WaitBetweenSpawns 5 TotalCurrency 5000 TFBot { Template T_TFBot_Giant_Soldier Attributes HoldFireUntilFullReload //now works with every clip-based weapon Item "The Cow Mangler 5000" // Tag "popext_homingprojectile|0.5|1.0" Tag "popext_homingprojectile|0.5|0.5" Tag "popext_reprogrammed" Tag "popext_spawnhere|-779.491150 3302.379883 312.992340|3" //custom spawn origin Tag "popext_customattr|wet immunity|1" Tag "popext_weaponresist|298|20" //20x damage from iron curtain Tag "popext_setskin|0" //red skin // Tag "popext_fireweapon|2048" Tag "popext_rocketcustomtrail|eyeboss_projectile" } } } Wave { InitWaveOutput { Target gamerules // gamerules or tf_gamerules, depending on the map Action RunScriptCode Param " IncludeScript(`popextensions_main`, getroottable()) MissionAttrs({ `WaveStartCountdown`: 1 `ExtraTankPath`: [ [`686 4000 392`, `667 4358 390`, `378 4515 366`, `-193 4250 289`], [`640 5404 350`, `640 4810 350`, `640 4400 550`, `1100 4100 650`, `1636 3900 770`] ] `SoundOverrides` : { //overrides teamplay_broadcast_audio sounds `Announcer.MVM_Get_To_Upgrade`: null `music.mvm_end_last_wave`: null `Game.YourTeamWon`: null } }) // PopExt.SetWaveIconsFunction(function() { // PopExt.SetWaveIconSpawnCount(`blimp2_lite`, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_NORMAL, 1) // PopExt.SetWaveIconSpawnCount(`tank_red`, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_NORMAL, 1) // }) PopExt.AddTankName(`abc*`, { OnSpawn = function(tank, name) { local prop = SpawnEntityFromTable(`prop_dynamic`, {model = `models/props_badlands/barrel01.mdl`, origin = `0 0 79`}) local trigger = SpawnEntityFromTable(`trigger_ignite`, {origin = `0 0 100`, spawnflags = `1`}) PopExtUtil.SetupTriggerBounds(trigger, Vector(-175,-175,-175), Vector(175,175,175)) PopExtUtil.SetParentLocalOrigin([prop, trigger], tank) tank.KeyValueFromString(`rendercolor`, `255 0 0`) }, // OnDeath = function(tank, params) { // PopExt.DecrementWaveIconSpawnCount(`tank_red`, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_NORMAL, 1) // } Scale = `0.5` DisableSmoke = true }) PopExt.AddCustomTankIcon(`blimp2_lite`, 1, true, false, false, false) PopExt.AddTankName(`tank2`, { IsBlimp = true StartTrack = `extratankpath2_1` //this is only required for blimps so the func_tracktrain knows where to go CritImmune = true NoScreenShake = true CrushDamageMult = 0 Team = 2 SoundOverrides = { Ping = `npc/combine_gunship/ping_search.wav` Start = `ui/chime_rd_2base_pos.wav` EngineLoop = `npc/combine_gunship/dropship_engine_distant_loop1.wav` Destroy = `ui/chime_rd_2base_neg.wav` Deploy = `ui/chime_rd_2base_neg.wav` } // SpawnTemplate = `templateName` }) " } // WaveSpawn // { // Name "Wave2" // TotalCount 1 // TotalCurrency 0 // Tank // { // Health 100 // Speed 75 // Name "abcd" // StartingPathTrackNode "extratankpath1_1" // OnBombDroppedOutput // { // Target boss_deploy_relay // Action Trigger // } // } // } WaveSpawn { Name "Wave2" TotalCount 1 TotalCurrency 0 Tank { Health 10000 Speed 70 Name "tank2" Skin 0 StartingPathTrackNode "extratankpath2_1" OnBombDroppedOutput { Target boss_deploy_relay Action Trigger } } } } Wave { InitWaveOutput { Target gamerules // gamerules or tf_gamerules, depending on the map Action RunScriptCode Param " IncludeScript(`popextensions_main`, getroottable()) // Besides loading your 'point templates' from a separate pointtemplates.nut file, // you can also add them on the fly if(!(`PointTemplates` in getroottable())) ::PointTemplates <- {} PointTemplates.SampleTemplateName <- { NoFixup = 1, //Name fix-up behaves somewhat similarly to point_template name fix-up, appending a unique number to the end of the targetname to separate identical templates. Set NoFixup 1 to disable this behavior [0] = { //first entity to spawn in the template item_teamflag = { //entity classnames here targetname = `example_flag` origin = `0 0 0` angles = `0 0 0` //other item_teamflag key/values go in here } }, [1] = { //second entity to spawn in the template prop_dynamic = { targetname = `example_barrel` parentname = `example_flag` //parent a barrel prop to the flag model = `models/props_badlands/barrel01.mdl` } } } PointTemplates.Sentry <- { KeepAlive = 1, //Dont remove entities after their spawner had been killed RemoveIfKilled = `sentry`, // Remove all entities in template if the specified entity is killed [0] = { OnSpawnOutput = { //Parent entity is the !activator. Set builder to parent entity Target = `sentry` //targetname of an entity added below Action = `setbuilder` Delay = 0.00 } }, [1] = { OnParentKilledOutput = { //kill players after the carrier was dead Target = `player` Action =`sethealth` Delay = 0.00 Param = 1 } }, [2] = { prop_dynamic = { //Entity classname model = `models/props_coalmines/wood_fence_short_128.mdl` //keyvalue solid = 0 //Physics collision model (0- No collision, 1 - BSP, 2 - Bounding box, 3 - Oriented bounding box, 6 - VPhysics)= } }, [3] = { obj_sentrygun = { targetname = `sentry` //Entity name. Required if the entity is going to be referenced somewhere origin = `0 0 0` teamnum = 3 // 2 - Red team, 3 - Blu team SolidToPlayer = 0 } } } " } StartWaveOutput { // if you have templates that you want to spawn on wave start, replace the StartWaveOutput trigger with RunScriptCode Target gamerules // gamerules or tf_gamerules, depending on the map Action RunScriptCode Param " // The original StartWaveOutput trigger, change if necessary EntFire(`wave_start_relay`, `Trigger`) // SpawnTemplate's signature is (string pointtemplatename, handle parent = null, string|vector origin = '', string|QAngle angles = '') // calling SpawnTemplate here will spawn when the wave starts SpawnTemplate(`Sentry`, null, `0 -800 500`) " } DoneOutput { Target wave_finished_relay Action trigger } WaveSpawn { Name "Wave3" Where spawnbot TotalCount 2 MaxActive 2 SpawnCount 2 WaitBeforeStarting 1 WaitBetweenSpawns 5 TotalCurrency 5000 TFBot { Template T_TFBot_Giant_Soldier Attributes HoldFireUntilFullReload //now works with every clip-based weapon Item "The Cow Mangler 5000" Tag "popext_spawntemplate|Sentry" // spawns the template with the bot as its parent } } } } // Functions provided by popextensions: // Sets parent immediately in a dirty way. Does not retain absolute origin, retains local origin instead // child parameter may also be an array of entities // void SetParentLocalOrigin(handle|array child, handle parent, string attachment = null) // Make a wearable prop that is attached to the player. The wearable is automatically removed when the owner is killed or respawned // handle CreatePlayerWearable(handle player, string model, bool bonemerge = true, string attachment = null, bool autoDestroy = true) // Setup collision bounds of a trigger entity // handle SetupTriggerBounds(handle trigger, Vector mins = null, Vector maxs = null) // Prints a table to client console // void PrintTable(table|array table) // Adds hooks to robots with specified Tag // void AddRobotTag(string tag, table hooks) // Adds hooks to tanks with specified Name. Wildcard * suffix is supported // void AddTankName(string name, table hooks) // ALERT! Functions that change wavebar icons will crash linux servers! // Add custom tank icon to the wavebar, should be called in WaveInitOutput // void AddCustomTankIcon(string name, int count, bool isCrit = false, bool isBoss = true, bool isSupport = false, bool isSupportLimited = false) // Add custom icon to the wavebar, should be called in WaveInitOutput // void AddCustomIcon(string name, int count, bool isCrit = false, bool isBoss = false, bool isSupport = false, bool isSupportLimited = false) // If you want to use IncrementWaveIconSpawnCount functions to add icons to the wavebar, use this function // void SetWaveIconsFunction(function func) // Flags for use in wavebar functions below. Joinable with | operator // MVM_CLASS_FLAG_NONE 0; // MVM_CLASS_FLAG_NORMAL 1 << 0; // Non support or mission icon // MVM_CLASS_FLAG_SUPPORT 1 << 1; // Support icon flag. Mission icon does not have this flag // MVM_CLASS_FLAG_MISSION 1 << 2; // Mission icon flag. Support icon does not have this flag // MVM_CLASS_FLAG_MINIBOSS 1 << 3; // Giant icon flag. Support and mission icons do not display red background when set // MVM_CLASS_FLAG_ALWAYSCRIT 1 << 4; // Crit icon flag. Support and mission icons do not display crit outline when set // MVM_CLASS_FLAG_SUPPORT_LIMITED 1 << 5; // Support limited flag. Game uses it together with support flag // Get wavebar spawn count of an icon with specified name and flags // int GetWaveIconSpawnCount(string name, int flags) // Set wavebar spawn count of an icon with specified name and flags // If count is set to 0, removes the icon from the wavebar // Can be used to put custom icons on a wavebar // void SetWaveIconSpawnCount(string name, int flags, int count = 1, bool changeMaxEnemyCount = true) // Increment wavebar spawn count of an icon with specified name and flags // Can be used to put custom icons on a wavebar // void IncrementWaveIconSpawnCount(string name, int flags, int count = 1, bool changeMaxEnemyCount = true) // Increment wavebar spawn count of an icon with specified name and flags // Use it to decrement the spawn count when the enemy is killed. Should not be used for support type icons // void DecrementWaveIconSpawnCount(string name, int flags, int count = 1, bool changeMaxEnemyCount = false) // Used for mission and support limited bots to display them on a wavebar during the wave, set by the game automatically when an enemy with this icon spawn // void SetWaveIconActive(string name, int flags, bool active) // Used for mission and support limited bots to display them on a wavebar during the wave, set by the game automatically when an enemy with this icon spawn // bool GetWaveIconActive(string name, int flags)