TacticalInsertion - DoktorSAS/IW6X-S1X-Scripting-Guide GitHub Wiki

Tactical Insertion

The Tactical Insertion is a very famous item in the Call of Duty community. This item is often used by players who practice Trickshottin and Sniping. This simple script will allow you to implement the Tactical Insertion on Call of Duty Ghost as well.

if(game:getdvar("gamemode") ~= "mp") then
    print("returning gamemode..");
    return
end
if(game:getdvar("g_gametype") == "infect") then
    print("returning g_gametype..");
    return
end

-- utils
AllPlayers = {};

level:onnotify("connected", function (player)
    table.insert(AllPlayers, player);
    
    player:onnotifyonce("disconnect", function ()
        for i, p in ipairs(AllPlayers) do
            if p == player then
                table.remove(AllPlayers, i);
                break;
            end
        end
    end)
end);


function makePersonalUsable(trig, plr)
    trig:makeusable();
    
    local players = AllPlayers;
    for i, player in ipairs(players) do
        if player == plr then
            trig:enableplayeruse(player);
        else
            trig:disableplayeruse(player);
        end
    end
end


function makeTeamUsable(trig, team)
    trig:makeusable();
    
    function updateTeamUsable()
        local players = AllPlayers;
        for i, player in ipairs(players) do
            if player.team == team then
                trig:enableplayeruse(player);
            else
                trig:disableplayeruse(player);
            end
        end
    end
    updateTeamUsable();

    local updater = level:onnotify("joined_team", updateTeamUsable);
    trig:onnotifyonce("death", function ()
        updater:clear();
    end);
end


function makeEnemyUsable(trig, owner)
    trig:makeusable();
    
    local team = owner.team;

    function updateEnemyUsable()
        local players = AllPlayers;
        for i, player in ipairs(players) do
            if player.team ~= team then
                trig:enableplayeruse(player);
            else
                trig:disableplayeruse(player);
            end
        end
    end
    updateEnemyUsable();

    local updater = level:onnotify("joined_team", function() updateEnemyUsable(); end);
    trig:onnotifyonce("death", function ()
        updater:clear();
    end);
end
--

game:precacheitem("flare_mp");
game:precachemodel("emergency_flare_iw6");

local flarefx_green = game:loadfx("fx/misc/flare_ambient_green");
local flarefx_red = game:loadfx("fx/misc/flare_ambient");

tactical_weapons = {
    "concussion_grenade_mp",
    "flash_grenade_mp",
    "smoke_grenade_mp",
    "trophy_mp",
    "motion_sensor_mp",
    "thermobaric_grenade_mp"
};

tactical_insertions = {};
for i = 0, 18, 1 do
    tactical_insertions[i] = {origin = nil, angles = nil, stick = nil, fx = nil, enemy_stick = nil, enemy_fx = nil};
end

function onPlayerSpawned(player)
    player:freezecontrols(0);
    for i,weapon in ipairs(tactical_weapons) do
        player:takeweapon(weapon);
    end
    player:setoffhandsecondaryclass("flash");
    player:giveweapon("flare_mp");
    player:givestartammo("flare_mp");
    local tactical_insertion_monitor = player:onnotify("grenade_fire", function (ent, weapName)
      
        if weapName ~= "flare_mp" then
            return;
        end

        local playerId = player:getentitynumber();
        local playerPos = player:getorigin();
        local groundPos = game:playerphysicstrace(vector:new(playerPos.x, playerPos.y, playerPos.z + 16), vector:new(playerPos.x, playerPos.y, playerPos.z - 2048));
        groundPos.z = groundPos.z + 1;

        if(player:isonground() == 0) then
            if(game:distance(playerPos, groundPos) > 48) then
                player:iclientprintlnbold("^1You can't use insertion here");
                player:givestartammo("flare_mp");
                return;
            end
        end

        local glowStick = game:spawn("script_model", groundPos);
        glowStick.angles = player.angles;
        glowStick.team = player.team;
        glowStick.owner = player;
        glowStick:setmodel("emergency_flare_iw6");
        glowStick:playloopsound("emt_road_flare_burn");
        glowStick:playsound("tactical_insert_iw5_flare_ignite_npc");
        makePersonalUsable(glowStick, player);
        glowStick:setcursorhint("HINT_NOICON");
        glowStick:sethintstring("Press ^3[{+activate}]^7 to pick up Tactical Insertion");
        glowStick:setcandamage(true);
        local tagOrigin = glowStick:gettagorigin("tag_fire_fx");
        local tagAngles = glowStick:gettagangles("tag_fire_fx");
        local fxEnt = game:spawnfx(flarefx_green, tagOrigin, game:anglestoforward(tagAngles), game:anglestoup(tagAngles));

        local enemyGlowStick = game:spawn("script_model", groundPos);
        enemyGlowStick:setmodel("emergency_flare_iw6");
        enemyGlowStick:hide();
        makeEnemyUsable(enemyGlowStick, player);
        enemyGlowStick:setcursorhint("HINT_NOICON");
        enemyGlowStick:sethintstring("Press ^3[{+activate}] ^7to smash Tactical Insertion");
        local enemyfxEnt = game:spawnfx(flarefx_red, tagOrigin, game:anglestoforward(tagAngles), game:anglestoup(tagAngles));
        
        game:triggerfx(fxEnt);
        game:triggerfx(enemyfxEnt);

        tactical_insertions[playerId] = {
            origin = groundPos,
            angles = player:getangles(),
            stick = glowStick,
            fx = fxEnt,
            enemy_stick = enemyGlowStick,
            enemy_fx = enemyfxEnt
        };

        function glowStickTeamUpdater()
            fxEnt:hide();
            enemyfxEnt:hide();
        
            local players = AllPlayers;
            for i, plr in ipairs(players) do
                if plr.team == player.team then
                    fxEnt:showtoplayer(plr);
                else
                    enemyfxEnt:showtoplayer(plr);
                end
            end
        end
        glowStickTeamUpdater();

        local updater = level:onnotify("joined_team", glowStickTeamUpdater);
        enemyGlowStick:onnotifyonce("death", function ()
            updater:clear();
        end);

        function enemy_use_react(enemy)
            tactical_insertions[playerId].stick:delete();
            tactical_insertions[playerId].fx:delete();
            tactical_insertions[playerId].enemy_stick:delete();
            tactical_insertions[playerId].enemy_fx:delete();
            tactical_insertions[playerId] = {origin = nil, angles = nil, stick = nil, fx = nil, enemy_stick = nil, enemy_fx = nil};
            player:iclientprintlnbold("Your ^2tactical insertion^7 was ^1denied^7!");
            player:playlocalsound("mp_enemy_obj_captured");
            if player.team == "allies" then
                player:playlocalsound("US_1mc_glowstick_gone");
            else
                player:playlocalsound("US_1mc_glowstick_gone");
            end

            enemy:notify("destroyed_insertion", player);
            enemy:notify("destroyed_explosive");
        end

        function use_react()
            tactical_insertions[playerId].stick:delete();
            tactical_insertions[playerId].fx:delete();
            tactical_insertions[playerId].enemy_stick:delete();
            tactical_insertions[playerId].enemy_fx:delete();
            tactical_insertions[playerId] = {origin = nil, angles = nil, stick = nil, fx = nil, enemy_stick = nil, enemy_fx = nil};
            player:playsound("tactical_insert_flare_pu");
            player:giveweapon("flare_mp");
            player:givestartammo("flare_mp");
        end

        function damage_react(amount, attacker)
            if(attacker.team == player.team) then
                return;
            end

            tactical_insertions[playerId].stick:delete();
            tactical_insertions[playerId].fx:delete();
            tactical_insertions[playerId].enemy_stick:delete();
            tactical_insertions[playerId].enemy_fx:delete();
            tactical_insertions[playerId] = {origin = nil, angles = nil, stick = nil, fx = nil, enemy_stick = nil, enemy_fx = nil};
            player:iclientprintlnbold("Your ^2tactical insertion^7 was ^1denied^7!");

            player:playlocalsound("mp_enemy_obj_captured");
            if player.team == "allies" then
                player:playlocalsound("US_1mc_glowstick_destroyed");
            else
                player:playlocalsound("SP_1mc_glowstick_destroyed");
            end

            attacker:setclientomnvar( "damage_feedback", "standard" );
            attacker:playlocalsound( "MP_hit_alert" );

            attacker:notify("destroyed_insertion", player);
            attacker:notify("destroyed_explosive");
        end

        tactical_insertions[playerId].enemy_stick:onnotify("trigger", enemy_use_react);
        tactical_insertions[playerId].stick:onnotify("trigger", use_react);
        tactical_insertions[playerId].stick:onnotify("damage", damage_react);
    end);

    local pID = player:getentitynumber();
    if tactical_insertions[pID].origin ~= nil then
        if game:canspawn(tactical_insertions[pID].origin) then
            player:setorigin(tactical_insertions[pID].origin);
            player:setangles(tactical_insertions[pID].angles);
        else
            player:iclientprintlnbold("Your Tactical Insertion got bugged!");
        end
        tactical_insertions[pID].stick:delete();
        tactical_insertions[pID].fx:delete();
        tactical_insertions[pID].enemy_stick:delete();
        tactical_insertions[pID].enemy_fx:delete();
        tactical_insertions[pID] = {origin = nil, angles = nil, stick = nil, fx = nil, enemy_stick = nil, enemy_fx = nil};
    end

    player:onnotifyonce("death", function ()
        tactical_insertion_monitor:clear();
    end);
end

local onPlayerConnected = function (player)
    local spawnlistener = player:onnotify("spawned_player", function() onPlayerSpawned(player); end);
    player:onnotifyonce("disconnect", function ()
        spawnlistener:clear();
    end);
end

level:onnotify("connected", onPlayerConnected);

print("==============================================");
print("IW6x Tactical Insertion Script Loaded");
print("Developed by GEEKiDoS, DoktorSAS & quaK");
print("==============================================");