Skip to content
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Donate
Collapse

Plutonium

undefined

S3VDITO

@S3VDITO
About
Posts
65
Topics
10
Groups
0
Followers
12
Following
0

Posts

Recent Best Controversial

  • [Preview][Animated movement(not fully)] AIBots
    undefined S3VDITO
    May 12, 2020, 2:09 PM

    Since I try to make Survival Mod, the first thing I started is the bots, or rather their logic of movement and attack.

    At the moment I only implemented LookLogic (not fully)

    This is just a preview, I think in the future I can give the bots full logic, but my plans are only related to Survival Mod, I do not consider other modes yet (FFA is currently working)

    Send me PM, if you have any ideas for realizing

    Watching logic
    https://www.youtube.com/watch?v=RDlMABVC9Vw

    Move logic
    https://www.youtube.com/watch?v=N81LXQvNl3k

    Animated move
    https://www.youtube.com/watch?v=3brC8vSBS1w

    Implemeted:

    1. Look logic (default target player with num 0)
    2. Move logic (default target player with num 0) IF BOT SEE YOU
    3. Animated movement

    [this list will be updated]

    Download only look logic

    Download move logic added

    Download movement animation added

    Source:

    // This is preview version 
    // This is only the beginning of creating bots with the logic of movement and attack, 
    // but first of all I want to create Survival mode, so do not expect bots that can play in TDM, FFA, DZ and other.
    // I guess I would do it after creating this script
    
    // AIBots by S3VDITO
    // Ver 0.0.0.3
    // Realized: 
    // 1 - watching for player function (not works now)
    // 2 - move logic [not fully] [without check collision] (in progress...)
    // 3 - animated movement
    
    gsc.setDvar("testClients_doAttack", 0);
    gsc.setDvar("testClients_doCrouch", 0);
    gsc.setDvar("testClients_doMove", 0);
    gsc.setDvar("testClients_doReload", 0);
    gsc.setDvar("testClients_doWatchKillcam", 0);
    
    gsc.setDvarIfUninitialized("testClients_doSpeed", 4);
    
    global bot_speed = to_float(gsc.getDvar("testClients_doSpeed"));
    
    global bots_list = [];
    
    global player_target_list = [];
    
    level.onNotify("connected", fun(args) {
    	var player = args[0];
    	print(player.getGuid().find("bot"));
    	if(player.getGuid().find("bot") != 0)
    	{
    		print("Player connected");
    		player_target_list.push_back_ref(player);
    	}
    });
    
    level.onNotify("prematch_done", fun(args) {
    	if(gsc.getDvar("g_gametype") == "dm") {
    		for(var entRef = 0; entRef < 18; ++entRef)
    		{
    			var tempEntBot = gsc.getEntByNum(entRef);
    			if(tempEntBot.getGuid().find("bot") == 0)
    			{
    				var animBody = gsc.spawn("script_model", tempEntBot.getOrigin());
    				animBody.setmodel("mp_body_delta_elite_assault_ab");
    				animBody.notsolid();
    				
    				animBody.LinkTo(tempEntBot, "tag_origin", [-4, 0, -1], [-4, 0, -1]);
    				
    				bots_list.push_back_ref(tempEntBot);
    				
    				setInterval(fun[tempEntBot, animBody]() { 
    					botMove(tempEntBot, gsc.getEntByNum(0), animBody); 
    				}, 50);
    				
    				setInterval(fun[animBody]() { 
    					animBody.scriptModelPlayAnim("pb_stumble_pistol_walk_forward");
    				}, 1000);
    			}
    		}
    	}
    });
    
    def botMove(bot, target, animModel)
    {		
    	var bot_weapon_origin = bot.getTagOrigin("tag_weapon_left");
    
    	HideTestClientParts(bot);
    	
    	if(LockSightTest(bot, target) == false)
    	{
    		// animModel.scriptModelPlayAnim("pb_stand_alert_pistol");
    		return;
    	}
    	else
    	{
    		
    	
    		var angle = gsc.vectorToAngles([target.getTagOrigin("j_helmet")[0] - bot_weapon_origin[0], target.getTagOrigin("j_helmet")[1] - bot_weapon_origin[1], target.getTagOrigin("j_helmet")[2] - bot_weapon_origin[2]]);
    		bot.setPlayerAngles(angle);
    		
    		// Spaming field bug =(
    		//animModel.set("angles", bot.getPlayerAngles());
    	}
    	
    	var moveTarget = target.getOrigin();
    	var distance = gsc.distanceSquared(moveTarget, bot.getOrigin());
    	if(gsc.distance(moveTarget, bot.getOrigin()) <= 64)
    	{
    		// bot_speed = 0;
    	}
    	else
    	{
    		bot_speed = to_float(gsc.getDvar("testClients_doSpeed"));
    		var normalize = gsc.vectorNormalize([moveTarget[0] - bot.getOrigin()[0], moveTarget[1] - bot.getOrigin()[1], moveTarget[2] - bot.getOrigin()[2]]);
    		bot.setOrigin([bot.getOrigin()[0] + normalize[0] * bot_speed, bot.getOrigin()[1] + normalize[1] * bot_speed, bot.getOrigin()[2] + normalize[2] * bot_speed]);
    	}
    }
    
    def HideTestClientParts(bot)
    {
    	bot.hidepart("j_ankle_le");
    	bot.hidepart("j_hiptwist_le");
    	bot.hidepart("j_head");
    	bot.hidepart("j_helmet");
    	bot.hidepart("j_eyeball_le");
    	bot.hidepart("j_clavicle_le");
    }
    
    
    // Stolen from _stinger.gsc :)
    def LockSightTest(self, target)
    {
    	var eyePos = self.GetEye();
    	
    	var passed = gsc.SightTracePassed(eyePos, target.getOrigin(), false, target);
    	if ( passed == 1)
    	{
    		return true;
    	}
    
    	var front = target.GetPointInBounds(1, 0, 0);
    	passed = gsc.SightTracePassed( eyePos, front, false, target );
    	if (passed == 1)
    	{
    		return true;
    	}	
    
    	var back = target.GetPointInBounds(-1, 0, 0);
    	passed = gsc.SightTracePassed( eyePos, back, false, target );
    	if (passed == 1)
    	{
    		return true;
    	}
    
    	return false;
    }
    
    

  • [Release] [GSC] MapEdit
    undefined S3VDITO
    Jan 30, 2021, 6:12 PM

    Simple MapEdit, don't wait for anything more, for now...

    Special thanks to TTV_WIZEQC for the motivation to do this XD
    This script worked without problems on servers:

    • TF-Infected TP #1
    • TF-Infected TP #2

    I use GSC functions for rotate crates, script not using fields for modification angles

    UPDATED: Rewrited on GSC
    Source (notepad++ bad formating code 😞 )

    // #include maps\mp\gametypes\_teams; // error
    
    init()
    {
        switch(GetDvar("mapname"))
        {
            case "mp_rust":
                CreateFloor((0, 0, 0), (512, 512, 0), false);
    			
    			createElevator((0, 0, 0), 512, (0, 0, 0));
                break;
    		case "mp_paris":
    			thread createJumpZone((-1036.623, -739.0071, 145.1301), (0, 0, 1250));
    			thread createJumpZone((-1888.126, 632.3943, 289.125), (-250, 0, 1150));
    			break;
    		case "mp_dome":
    			thread createTeleportFlagPressedButton((0,0,-350), (500,0,900));
    			thread createTeleportFlag((0,125,-350), (500,0,1500));
    			break;
        }
    }
    
    createFloor(corner1, corner2, isInvisible)
    {
        width = corner1[0] - corner2[0];
        if (width < 0) 
        {
            width = width * -1;
        }
            
        length = corner1[1] - corner2[1];
            
        if (length < 0) 
        {
            length = length * -1;
        }
                
        bwide = floor(width / 50);
        blength = floor(length / 30);
        C = (corner2[0] - corner1[0], corner2[1] - corner1[1], corner2[2] - corner1[2]);
        A = (C[0] / bwide, C[1] / blength, 0);
     
        for (i = 0; i < bwide; ++i)
        {
            for (j = 0; j < blength; ++j)
            {
                crate = spawn("script_model", (corner1[0] + A[0] * i, corner1[1] + A[1] * j, corner1[2]));
                crate setModel("com_plasticcase_friendly");
                crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
                
                if(isInvisible)
                {
                    crate hide();
                }
            }
        }
    }
    
    createRamp(top, bottom, isInvisible) 
    {
        distance = distance(top, bottom);
        blocks = ceil(distance / 30) + 1;
        
        A = ((top[0] - bottom[0]) / blocks, (top[1] - bottom[1]) / blocks, (top[2] - bottom[2]) / blocks);
        temp = vectorToAngles((top[0] - bottom[0], top[1] - bottom[1], top[2] - bottom[2]));
        BA = (temp[2], temp[1] + 90, temp[0]);
     
        
        for (b = 0; b <= blocks; ++b) {
            crate = spawn("script_model", (bottom[0] + A[0] * b, bottom[1] + A[1] * b, bottom[2] + A[2] * b));
            crate setModel("com_plasticcase_friendly");
            crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
            crate.angles = BA;
            
            if(isInvisible)
            {
                crate Hide();
            }
        }
    }
    
    createWall(start, end, isInvisible)
    {
        D = Distance2D(start, end);
        H = Distance((0, 0, start[2]), (0, 0, end[2]));
        blocks = Ceil(D / 60);
        height = Ceil(H / 30);
     
        C = (end[0] - start[0], end[1] - start[1], end[2] - start[2]);
        A = (C[0] / blocks, C[1] / blocks, C[2] / height);
        TXA = A[0] / 4;
        TYA = A[1] / 4;
        angle = vectorToAngles(C);
        angle = (0, angle[1], 90);
     
        for (h = 0; h < height; ++h)
        {
            crate = spawn("script_model", (start[0] + TXA, start[1] + TYA, start[2] + 15 + A[2] * h));
            crate setModel("com_plasticcase_friendly");
            crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    		crate.angles = angle;
            
            if(isInvisible)
            {
                crate Hide();
            }
     
            for (i = 0; i < blocks; ++i)
            {
                crate = spawn("script_model", (start[0] + A[0] * i, start[1] + A[1] * i, start[2] + 15 + A[2] * h));
                crate setModel("com_plasticcase_friendly");
    			crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    			crate.angles = angle;
                
                if(isInvisible)
                {
                    crate Hide();
                }
            }
     
            crate = spawn("script_model", (start[0] + TXA * -1, start[1] + TYA * -1, start[2] + 15 + A[2] * h));
            crate setModel("com_plasticcase_friendly");
            crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    		crate.angles = angle;
            
            if(isInvisible)
            {
                crate Hide();
            }
        }
    }
    
    createJumpZone(position, impulse)
    {
    	level endon("game_ended");
    	
    	zone = spawn("script_model", position);
    	zone setModel("weapon_c4_bombsquad");
    	zone setCursorHint("HINT_NOICON");
    	zone setHintString("Press and hold ^1[{+activate}] ^7for jump");
    	zone makeUsable();
    	
    	for (;;)
    	{
    		wait (.25);
    		
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, position);
    			if (dist < 75 && player isOnGround() && player useButtonPressed())
    			{
    				player setVelocity(impulse);
    			}
    		}
    	}
    }
    
    createTeleportFlagPressedButton(startOrigin, endOrigin)
    {
    	level endon("game_ended");
    	
    	flagEnter = spawn("script_model", startOrigin);
        flagEnter setModel(getTeamFlagModel("allieschar"));
    	flagEnter setCursorHint("HINT_NOICON");
    	flagEnter setHintString("Press and hold ^1[{+activate}] ^7for teleported");
    	flagEnter makeUsable();
    	
        flagExit = spawn("script_model", endOrigin);
        flagExit setModel(getTeamFlagModel("axischar"));
    	flagExit setCursorHint("HINT_NOICON");
    	flagExit setHintString("Press and hold ^1[{+activate}] ^7for go back");
    	flagExit makeUsable();
    	
    	curObjID = maps\mp\gametypes\_gameobjects::getNextObjID();
    	objective_add(curObjID, "active");
    	objective_position(curObjID, startOrigin);
    	objective_icon(curObjID, "compass_waypoint_bomb");
    
    	for (;;)
    	{
    		wait (.5);
    		foreach (player in level.players)
    		{
    			distEnter = distance(player.origin, startOrigin);
    			if (distEnter < 75 && player isOnGround() && player useButtonPressed())
    			{
    				player setOrigin(flagExit.origin);
    				continue;
    			}
    			
    			distExit = distance(player.origin, endOrigin);
    			if (distExit < 75 && player isOnGround() && player useButtonPressed())
    			{
    				player setOrigin(flagEnter.origin);
    				continue;
    			}
    		}
    	}
    }
    
    createTeleportFlag(startOrigin, endOrigin)
    {
    	level endon("game_ended");
    	
    	flagEnter = spawn("script_model", startOrigin);
        flagEnter setModel(getTeamFlagModel("allieschar"));
    	
        flagExit = spawn("script_model", endOrigin);
        flagExit setModel(getTeamFlagModel("axischar"));
    	
    	curObjID = maps\mp\gametypes\_gameobjects::getNextObjID();
    	objective_add(curObjID, "active");
    	objective_position(curObjID, startOrigin);
    	objective_icon(curObjID, "compass_waypoint_bomb");
    
    	for (;;)
    	{
    		wait (.25);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, startOrigin);
    			if (dist < 75)
    			{
    				player setOrigin(endOrigin);
    			}
    		}
    	}
    }
    
    createElevator(start, Z, angle)
    {
    	floors = [];
    	
    	origin = spawn("script_origin", start + (0, 0, 45));
    	
    	floor = spawn("script_model", start);
        floor setModel("com_plasticcase_enemy");
    	floor solid();
    	floor SetContents(1);
        floor CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    	floor.angles = angle;
    	
    	floor linkTo(origin);
    	
    	for (i = 0; i < 4; i++)
    	{
    		offset = (0, 0, 0);
    		
    		if (i == 0)
    			offset = (28, 30, 0);
    		else if (i == 1)
    			offset = (-28, 30, 0);
    		else if (i == 2)
    			offset = (28, -30, 0);
    		else if (i == 3)
    			offset = (-28, -30, 0);
    		
            floor = spawn("script_model", start + offset);
            floor setModel("com_plasticcase_enemy");
            floor CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    		floor.angles = angle;
    		floors[i] = floor;
    		floor linkTo(origin);
    	}
    	
    	for (;;)
    	{
    		wait (10);
    		origin moveZ(Z, 5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player playerLinkTo(origin);
    				player playerLinkedOffsetEnable();
    			}
    		}
    		
    		wait (5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player setOrigin(player.origin + (0, 0, 10));
    				player unLink();
    			}
    		}
    		
    		wait (10);
    		origin moveZ(-1 * Z, 5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player playerLinkTo(origin);
    				player playerLinkedOffsetEnable();
    			}
    		}
    		
    		wait (5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player setOrigin(player.origin + (0, 0, 10));
    				player unLink();
    			}
    		}
    	}
    }
    
    getTeamFlagModel(teamChar)
    {
    	return tableLookup("mp/factionTable.csv", 0, getMapCustom(teamChar), 10);
    }
    

    You can test script now on maps: Resistance(jump zones, tree lunge), Rust (center map), Dome(flags teleporter)

    CreateRamp(topOrigin, bottomOrigin, isInvisible);
    CreateFloor(originA, originB, isInvisible);
    CreateWall(originA, originB, isInvisible);
    
    Origins - is vector type
    [X, Y, Z]
    
    isInvisible - is bool type, false - visible, true - hide
    

    Screenshots from servers
    1.png 2.png 4.png 3.png

    Video
    https://www.youtube.com/watch?v=BJI4NqyLoxM


  • [Release] Hight jump zone
    undefined S3VDITO
    May 8, 2020, 11:27 AM

    I wrote a small script to diversify the infection server 😃
    At first I wanted to make MapEdit, but so far it’s unrealistic ( i don’t know C++ and how to look for the necessary offsets)

    Before declaring me a thief, I’ll say that this is a piece of my code converted to ChaiScript, I just used fragments of QBots, because I don’t know the full syntax of Chai...

    Script can be work on dedicate server/private match

    https://www.youtube.com/watch?v=7v5MURmKecM

    global dev_mode = false;
    
    global jump_zones = [];
    level.onNotify("prematch_done", fun(arguments) {
    	switch(gsc.getDvar("mapname")) {
    	    case("mp_paris") {
    			createJumpZone([-1036.623, -739.0071, 145.1301], [0, 0, 1250]);
    			createJumpZone([-1888.126, 632.3943, 289.125], [-250, 0, 1150]);
            break;
    		}
    	}
    });
    
    level.onNotify("connected", fun(arguments) {
    	var player = arguments[0];
    	var distance = 0;
    	player.notifyOnPlayerCommand("jump_action", "+activate");
    	
    	player.onNotify("jump_action", fun[player](arguments) {
    		if(dev_mode) { 
    			print(player.getOrigin());
    			print(player.getPlayerAngles());
    		}
    		
    		for(var index = 0; index < size(jump_zones); ++index) {
    			if(gsc.distance(player.getOrigin(), jump_zones[index].getOrigin()) < 175 && player.isOnGround() == 1) {
    				
    				// i trying create jump script, but notify damage can't return MOD_DAMAGE...,
    				// pluto-framework can fix it(pluto-framework can handling damage)
    				
    				player.setVelocity(jump_zones[index].get("impulse"));
    				player.iPrintLnBold("I belive, i can fly");
    				break;
    			}
    		}
    	})
    });
    
    def createJumpZone(position, impulse) {
    	var zone = gsc.spawn("script_model", position);
    	zone.setModel("weapon_c4_bombsquad");
    	zone.setCursorHint("HINT_NOICON");
    	zone.setHintString("Press and hold ^1[{+activate}] ^7for jump");
    	zone.makeUsable();
    	zone.set("impulse", impulse);
    	
    	jump_zones.push_back_ref(zone);
    	
    	return zone;
    }
    

    How to install:
    jump.chai
    send jump.chai in "...\AppData\Local\Plutonium\storage\iw5\scripts"

    How to get pos:

    global dev_mode = false; // change false to true
    

    use mode spectator and pressing F (or other button with bind +activate) for show origin and angles on console

    How to add new maps:
    find it:

    	switch(gsc.getDvar("mapname")) {
    	    case("mp_paris") {
    			createJumpZone([-1036.623, -739.0071, 145.1301], [0, 0, 1250]);
    			createJumpZone([-1888.126, 632.3943, 289.125], [-250, 0, 1150]);
            break;
    		}
    

    and add new case (this is example):

    case("mp_dome") { createJumpZone([0, 0, -350], [0, 0, 99999]); break; }
    
    // origin is vector3 [X, Y, Z] (you can check needs origin with enabled dev mode)
    // jump_impulse is vector3 [X, Y, Z]
    createJumpZone(origin, jump_impulse);
    

  • [Preview][Animated movement(not fully)] AIBots
    undefined S3VDITO
    May 15, 2020, 6:37 AM

    The walking animation has been added, it is primitive, but I can explain it with the limitations of the scripting language(ChaiScript), but I hope that the errors will be removed and the possibilities will be expanded.

    Post updated

    Demo video:
    https://www.youtube.com/watch?v=3brC8vSBS1w&t=8s


  • [For fun release] Guided AH-6
    undefined S3VDITO
    Jun 15, 2020, 2:21 PM

    If you suddenly began to miss the controlled helicopters from Battlefield, then this script is for you!
    (I just had nothing to do)

    By the way, the "settargetyaw" function is not implemented in the "script engine", its number is 33328 (I can not rotate helicopter without it)

    alt text

    Script link

    Script code

    global airHeight = gsc.getEnt("airstrikeheight", "targetname").getOrigin()[2];
    global helicopterSpeed = 512;
    level.onNotify("prematch_done", fun(arguments) {
    
    });
    
    level.onNotify("connected", fun(arguments) {
    	var player = arguments[0];
    	
    	player.onNotify("spawned_player", fun[player](arguments) {
    		if(player.getGuid().find("bot") != 0)
    		{	
    			// hmm that not working =(
    			//player.setperk("specialty_explosivebullets", true, true);
    			
    			print("Player connected");
    			
    			var heli_angles = [0, 45, 0];
    			var heli = helicopter_setup(player, [player.getOrigin()[0], player.getOrigin()[1], airHeight], heli_angles);
    			helicopter_controls(player, heli, heli_angles);
    		}
    	});
    });
    
    def helicopter_controls(player, heli, heli_angles)
    {
    	player.PlayerLinkTo(heli, "tag_player_attach_left", .5f, 10, 170, 30, 150, false);
    
    	var moving_forward = false;
    	var moving_backward = false;
    	var moving_left = false;
    	var moving_right = false;
    	
    	var helicopter_height = airHeight;
    
    	player.notifyOnPlayerCommand("pressed_moveforward", "+forward");
    	player.notifyOnPlayerCommand("unpressed_moveforward", "-forward");
    	
    	player.notifyOnPlayerCommand("pressed_moveback", "+back");
    	player.notifyOnPlayerCommand("unpressed_moveback", "-back");
    	
    	player.notifyOnPlayerCommand("pressed_moveleft", "+moveleft");
    	player.notifyOnPlayerCommand("unpressed_moveleft", "-moveleft");
    	
    	player.notifyOnPlayerCommand("pressed_moveright", "+moveright");
    	player.notifyOnPlayerCommand("unpressed_moveright", "-moveright");
    	
    	player.onNotify("pressed_moveforward", fun[moving_forward](arguments) {
    		moving_forward = true;
    	});
    	player.onNotify("unpressed_moveforward", fun[moving_forward](arguments) {
    		moving_forward = false;
    	});
    	
    	player.onNotify("pressed_moveback", fun[moving_backward](arguments) {
    		moving_backward = true;
    	});
    	player.onNotify("unpressed_moveback", fun[moving_backward](arguments) {
    		moving_backward = false;
    	});
    	
    	player.onNotify("pressed_moveleft", fun[moving_left](arguments) {
    		moving_left = true;
    	});
    	player.onNotify("unpressed_moveleft", fun[moving_left](arguments) {
    		moving_left = false;
    	});
    	
    	player.onNotify("pressed_moveright", fun[moving_right](arguments) {
    		moving_right = true;
    	});
    	player.onNotify("unpressed_moveright", fun[moving_right](arguments) {
    		moving_right = false;
    	});
    	
    	setInterval(fun[player, heli, moving_forward, moving_backward, moving_left, moving_right, heli_angles, helicopter_height]() {
    	
    		var origin = heli.getOrigin();
    		var forward = gsc.AnglesToForward(heli_angles);
    		
    		if(player.fragbuttonpressed() == 1)
    		{
    			helicopter_height = helicopter_height - 64;
    			heli.setvehgoalpos([origin[0], origin[1], helicopter_height], true);
    		}
    		if(player.secondaryoffhandbuttonpressed() == 1)
    		{
    			helicopter_height = helicopter_height + 64;
    			heli.setvehgoalpos([origin[0], origin[1], helicopter_height], true);
    		}
    		
    		if(moving_left == true)
    		{
    			heli_angles = [0, heli_angles[1] + 5, 0];
    			// NOT WORKING
    			heli.settargetyaw(heli_angles[1]);
    		}
    		if(moving_right == true)
    		{
    			heli_angles = [0, heli_angles[1] - 5, 0];
    			// NOT WORKING
    			heli.settargetyaw(heli_angles[1]);
    		}
    		if(moving_forward == true)
    		{
    			heli.setvehgoalpos([origin[0] + forward[0] * helicopterSpeed, origin[1] + forward[1] * helicopterSpeed, helicopter_height], true);
    		}
    		if(moving_backward == true)
    		{
    			heli.setvehgoalpos([origin[0] + forward[0] * -helicopterSpeed, origin[1] + forward[1] * -helicopterSpeed, helicopter_height], true);
    		}
    	}, 100);
    }
    
    def helicopter_setup(owner, pathStart, forward)
    {
    	var heli = gsc.spawnHelicopter(owner, pathStart, forward, "attack_littlebird_mp" , "vehicle_little_bird_armed");
    	
    	heli.setMaxPitchRoll(45, 45);	
    	heli.setspeed(100, 100, 40);
    	heli.setYawSpeed(120, 60);
    	
    	return heli;
    }
    

  • [Preview][Animated movement(not fully)] AIBots
    undefined S3VDITO
    May 13, 2020, 11:31 AM

    Mr. Android
    I would like to implement this, but so far I am limited due to the lack of knowledge of many ChaiScript functions, and there is also a lack of GSC function waittill, thread (this is the most necessary), endon.
    MagicBullet => crush server
    BulletTrace(not working) and other functions that can return arrays do not return them
    Set/Get field either have no result or crush the server

    While I made the primitive logic of the movement of bots, I had to hide the model of the bot itself and move the model (otherwise I could not give animations of movement) (attached video, updated post)

    https://www.youtube.com/watch?v=N81LXQvNl3k


  • [Release] Flags Teleporter
    undefined S3VDITO
    May 30, 2020, 9:23 AM

    This answer to the question

    It probably makes sense to add hidden teleporters(Scavenger packs), but so be it.
    (video with demo below)

    Instructions for installing the script and setups here (instruction is similar)

    Download

    Source:

    global flagCount = 0;
    
    level.onNotify("prematch_done", fun(args){
    
    	switch(gsc.getDvar("mapname")) 
    	{
    	    case("mp_dome") 
    		{
    			createTeleportFlag([0,0,-350], [500,0,900]);
    			createTeleportFlag([0,125,-350], [500,0,1500]);
    			break;
    		}
    	}
    });
    
    def createTeleportFlag(startOrigin, endOrigin)
    {
    	var flagEnter = gsc.spawn("script_model", startOrigin);
        flagEnter.setModel(getTeamFlagModel("allieschar"));
    	
        var flagExit = gsc.spawn("script_model", endOrigin);
        flagExit.SetModel(getTeamFlagModel("axischar"));
    	
    	// omg...
    	// my teacher would kill me for this, but he doesn’t see it so everything is fine ;)
    	setInterval(fun[startOrigin, endOrigin]() { 
    		for(var entRef = 0; entRef < 18; ++entRef)
    		{
    			try 
    			{
    				var player = gsc.getEntByNum(entRef);
    				
    				if(gsc.isPlayer(player) == 1)
    				{
    					if(gsc.distance(player.getOrigin(), startOrigin) < 75)
    					{
    						player.setOrigin(endOrigin);
    					}
    				}
    			} 
    			catch (e) 
    			{
    
    			}
    
    		}
    	}, 100);
    	
    	var curObjID = 31 - ++flagCount;
    	gsc.objective_add(curObjID, "active");
    	gsc.objective_position(curObjID, startOrigin);
    	gsc.objective_icon(curObjID, "compass_waypoint_bomb");
    }
    
    // _teams.gsc
    def getTeamFlagModel(teamChar)
    {
    	return gsc.tableLookup("mp/factionTable.csv", 0, gsc.getMapCustom(teamChar), 10);
    }
    

    https://www.youtube.com/watch?v=EVRuloSC6Wg


  • [Release] [GSC] MapEdit
    undefined S3VDITO
    Jun 29, 2021, 7:50 PM

    Added Elevator and Flag teleporter (telopter to/from by button)

    // #include maps\mp\gametypes\_teams; // error
    
    init()
    {
        switch(GetDvar("mapname"))
        {
            case "mp_rust":
                CreateFloor((0, 0, 0), (512, 512, 0), false);
    			
    			createElevator((0, 0, 0), 512, (0, 0, 0));
                break;
    		case "mp_paris":
    			thread createJumpZone((-1036.623, -739.0071, 145.1301), (0, 0, 1250));
    			thread createJumpZone((-1888.126, 632.3943, 289.125), (-250, 0, 1150));
    			break;
    		case "mp_dome":
    			thread createTeleportFlagPressedButton((0,0,-350), (500,0,900));
    			thread createTeleportFlag((0,125,-350), (500,0,1500));
    			break;
        }
    }
    
    createFloor(corner1, corner2, isInvisible)
    {
        width = corner1[0] - corner2[0];
        if (width < 0) 
        {
            width = width * -1;
        }
            
        length = corner1[1] - corner2[1];
            
        if (length < 0) 
        {
            length = length * -1;
        }
                
        bwide = floor(width / 50);
        blength = floor(length / 30);
        C = (corner2[0] - corner1[0], corner2[1] - corner1[1], corner2[2] - corner1[2]);
        A = (C[0] / bwide, C[1] / blength, 0);
     
        for (i = 0; i < bwide; ++i)
        {
            for (j = 0; j < blength; ++j)
            {
                crate = spawn("script_model", (corner1[0] + A[0] * i, corner1[1] + A[1] * j, corner1[2]));
                crate setModel("com_plasticcase_friendly");
                crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
                
                if(isInvisible)
                {
                    crate hide();
                }
            }
        }
    }
    
    createRamp(top, bottom, isInvisible) 
    {
        distance = distance(top, bottom);
        blocks = ceil(distance / 30) + 1;
        
        A = ((top[0] - bottom[0]) / blocks, (top[1] - bottom[1]) / blocks, (top[2] - bottom[2]) / blocks);
        temp = vectorToAngles((top[0] - bottom[0], top[1] - bottom[1], top[2] - bottom[2]));
        BA = (temp[2], temp[1] + 90, temp[0]);
     
        
        for (b = 0; b <= blocks; ++b) {
            crate = spawn("script_model", (bottom[0] + A[0] * b, bottom[1] + A[1] * b, bottom[2] + A[2] * b));
            crate setModel("com_plasticcase_friendly");
            crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
            crate.angles = BA;
            
            if(isInvisible)
            {
                crate Hide();
            }
        }
    }
    
    createWall(start, end, isInvisible)
    {
        D = Distance2D(start, end);
        H = Distance((0, 0, start[2]), (0, 0, end[2]));
        blocks = Ceil(D / 60);
        height = Ceil(H / 30);
     
        C = (end[0] - start[0], end[1] - start[1], end[2] - start[2]);
        A = (C[0] / blocks, C[1] / blocks, C[2] / height);
        TXA = A[0] / 4;
        TYA = A[1] / 4;
        angle = vectorToAngles(C);
        angle = (0, angle[1], 90);
     
        for (h = 0; h < height; ++h)
        {
            crate = spawn("script_model", (start[0] + TXA, start[1] + TYA, start[2] + 15 + A[2] * h));
            crate setModel("com_plasticcase_friendly");
            crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    		crate.angles = angle;
            
            if(isInvisible)
            {
                crate Hide();
            }
     
            for (i = 0; i < blocks; ++i)
            {
                crate = spawn("script_model", (start[0] + A[0] * i, start[1] + A[1] * i, start[2] + 15 + A[2] * h));
                crate setModel("com_plasticcase_friendly");
    			crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    			crate.angles = angle;
                
                if(isInvisible)
                {
                    crate Hide();
                }
            }
     
            crate = spawn("script_model", (start[0] + TXA * -1, start[1] + TYA * -1, start[2] + 15 + A[2] * h));
            crate setModel("com_plasticcase_friendly");
            crate CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    		crate.angles = angle;
            
            if(isInvisible)
            {
                crate Hide();
            }
        }
    }
    
    createJumpZone(position, impulse)
    {
    	level endon("game_ended");
    	
    	zone = spawn("script_model", position);
    	zone setModel("weapon_c4_bombsquad");
    	zone setCursorHint("HINT_NOICON");
    	zone setHintString("Press and hold ^1[{+activate}] ^7for jump");
    	zone makeUsable();
    	
    	for (;;)
    	{
    		wait (.25);
    		
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, position);
    			if (dist < 75 && player isOnGround() && player useButtonPressed())
    			{
    				player setVelocity(impulse);
    			}
    		}
    	}
    }
    
    createTeleportFlagPressedButton(startOrigin, endOrigin)
    {
    	level endon("game_ended");
    	
    	flagEnter = spawn("script_model", startOrigin);
        flagEnter setModel(getTeamFlagModel("allieschar"));
    	flagEnter setCursorHint("HINT_NOICON");
    	flagEnter setHintString("Press and hold ^1[{+activate}] ^7for teleported");
    	flagEnter makeUsable();
    	
        flagExit = spawn("script_model", endOrigin);
        flagExit setModel(getTeamFlagModel("axischar"));
    	flagExit setCursorHint("HINT_NOICON");
    	flagExit setHintString("Press and hold ^1[{+activate}] ^7for go back");
    	flagExit makeUsable();
    	
    	curObjID = maps\mp\gametypes\_gameobjects::getNextObjID();
    	objective_add(curObjID, "active");
    	objective_position(curObjID, startOrigin);
    	objective_icon(curObjID, "compass_waypoint_bomb");
    
    	for (;;)
    	{
    		wait (.5);
    		foreach (player in level.players)
    		{
    			distEnter = distance(player.origin, startOrigin);
    			if (distEnter < 75 && player isOnGround() && player useButtonPressed())
    			{
    				player setOrigin(flagExit.origin);
    				continue;
    			}
    			
    			distExit = distance(player.origin, endOrigin);
    			if (distExit < 75 && player isOnGround() && player useButtonPressed())
    			{
    				player setOrigin(flagEnter.origin);
    				continue;
    			}
    		}
    	}
    }
    
    createTeleportFlag(startOrigin, endOrigin)
    {
    	level endon("game_ended");
    	
    	flagEnter = spawn("script_model", startOrigin);
        flagEnter setModel(getTeamFlagModel("allieschar"));
    	
        flagExit = spawn("script_model", endOrigin);
        flagExit setModel(getTeamFlagModel("axischar"));
    	
    	curObjID = maps\mp\gametypes\_gameobjects::getNextObjID();
    	objective_add(curObjID, "active");
    	objective_position(curObjID, startOrigin);
    	objective_icon(curObjID, "compass_waypoint_bomb");
    
    	for (;;)
    	{
    		wait (.25);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, startOrigin);
    			if (dist < 75)
    			{
    				player setOrigin(endOrigin);
    			}
    		}
    	}
    }
    
    createElevator(start, Z, angle)
    {
    	floors = [];
    	
    	origin = spawn("script_origin", start + (0, 0, 45));
    	
    	floor = spawn("script_model", start);
        floor setModel("com_plasticcase_enemy");
    	floor solid();
    	floor SetContents(1);
        floor CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    	floor.angles = angle;
    	
    	floor linkTo(origin);
    	
    	for (i = 0; i < 4; i++)
    	{
    		offset = (0, 0, 0);
    		
    		if (i == 0)
    			offset = (28, 30, 0);
    		else if (i == 1)
    			offset = (-28, 30, 0);
    		else if (i == 2)
    			offset = (28, -30, 0);
    		else if (i == 3)
    			offset = (-28, -30, 0);
    		
            floor = spawn("script_model", start + offset);
            floor setModel("com_plasticcase_enemy");
            floor CloneBrushmodelToScriptmodel(level.airDropCrateCollision);
    	floor.angles = angle;
    	floors[i] = floor;
    	floor linkTo(origin);
    	}
    	
    	for (;;)
    	{
    		wait (10);
    		origin moveZ(Z, 5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player playerLinkTo(origin);
    				player playerLinkedOffsetEnable();
    			}
    		}
    		
    		wait (5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player setOrigin(player.origin + (0, 0, 10));
    				player unLink();
    			}
    		}
    		
    		wait (10);
    		origin moveZ(-1 * Z, 5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player playerLinkTo(origin);
    				player playerLinkedOffsetEnable();
    			}
    		}
    		
    		wait (5);
    		foreach (player in level.players)
    		{
    			dist = distance(player.origin, origin.origin);
    			if (dist < 125)
    			{
    				player setOrigin(player.origin + (0, 0, 10));
    				player unLink();
    			}
    		}
    	}
    }
    
    getTeamFlagModel(teamChar)
    {
    	return tableLookup("mp/factionTable.csv", 0, getMapCustom(teamChar), 10);
    }
    

    https://www.youtube.com/watch?v=a1tqJ_n29pA


  • Access Violation when handling entities
    undefined S3VDITO
    May 11, 2020, 5:51 AM

    May be a problem in setOrigin itself, because many gsc functions work inappropriately(giveWeapon, openMenu, BulletTrace and may be others)

    For example, I do not get errors when using iPrint functions(but setOrigin crush dedicate and private match(I don’t know, maybe it’s just me)):

    level.onNotify("connected", fun(args) {
    	var player = args[0];
    	// Press space :)
    	player.onNotify("jumped", fun[player](args){
    		avFunction(player);
    	});
    });
    
    def avFunction(player)
    {
        var obj = gsc.spawn("script_model", player.getOrigin());
    
        var interval = setInterval(fun[player, obj]()
        {
    		player.iPrintLnBold("This is test");
    		player.iPrintLn(obj.getOrigin());
        }, 1000);
    }
    

    alt text


  • i don't see my server
    undefined S3VDITO
    May 9, 2020, 7:17 PM

    jeriqualy

    You can use command connect localhost:port
    If server with password:
    Open console

    1. send command: password YOUR_PASSWORD
    2. send command: connect localhost:port
    3. Done
      i can say that I have the same problem (but the players see my server, but I do not 😃 )

  • [Preview][Animated movement(not fully)] AIBots
    undefined S3VDITO
    Jun 11, 2020, 5:55 AM

    VERsingthegamez
    not yet.
    I can’t implement some functions for bots due to problems in Chai.


  • Question on setting client vars
    undefined S3VDITO
    May 20, 2020, 6:12 AM

    Meet-Your-Maker

    For client

    player.setClientDvar("dvar_name", "value");
    

    or

    player.setClientDvars("dvar_name1", "value1", "dvar_name2", "value2"); // but you can add over 2 dvars
    

    but i cant call setclientdvar on plutonium IW5 =(

    For server(global dvar)

    gsc.setDvar("dvar_name", "value");
    

    I wrote small code for changing protected dvars and got hight jump 😃

    level.onNotify("prematch_done", fun(args){
    	gsc.setDvar("sv_cheats", "1");
    	gsc.setDvar("jump_disableFallDamage", "1");
    	gsc.setDvar("jump_height", "500");
    	
            // down better to remove or commented...
    	setTimeout(fun() { gsc.setDvar("sv_cheats", "0"); }, 500);
    	
    });
    

    EDITS:
    Hm... thats dont work on server without password...


  • inf_default.dsr
    undefined S3VDITO
    May 9, 2020, 6:04 PM

    jeriqualy said in inf_default.dsr:

    Hello,
    would there be a charitable soul to give me Infect mode configured with usp without ammunition, etc.
    Thanks

    You can create and edit the mode settings yourself (you don’t even have to use Notepad), this is built into the game

    Go to Private Match => Game Setup => Make Setups => Click on: Save Recipe To Disk => Give name (remember it) => look in folder admin(client folder) => find file with names you gave => Done


  • [For fun release] Guided AH-6
    undefined S3VDITO
    Jun 15, 2020, 6:25 PM

    fed

    I tried to make a controlled turret, but I appeared under a helicopter(but i could shoot from it), I think this can be avoided if the player is not linked

    def TurretLinkerToHelicopter(heli, player)
    {
    	var turret = gsc.spawnTurret( "misc_turret", [0,0,0], "pavelow_minigun_mp" );
    	turret.setModel("weapon_minigun");
    	turret.maketurretoperable();
    	turret.makeUsable();
    	turret.linkto(heli, "tag_minigun_attach_left");
    	player.remotecontrolturret(turret);
    }
    

    if you use LinkTo then assigning angles is pointless

    ent.LinkTo(linkToEnt, (string)tag, (vector)originOffset, (vector)anglesOffset);
    

  • Give killstreak
    undefined S3VDITO
    May 30, 2020, 10:01 AM

    fed

    This is not explosion effect, it's effect red vision and smoke

    // Aftematch smoke and vision effect
    	var effect = gsc.loadFX("dust/nuke_aftermath_mp");      
    	var aftermathEnt = gsc.GetEnt("mp_global_intermission", "classname");
    	var up = gsc.anglesToUp(aftermathEnt.get("angles"));
    	var right = gsc.anglesToRight(aftermathEnt.get("angles"));
    
    	gsc.PlayFX(effect, aftermathEnt.getOrigin(), up, right);
    
            // vison effect needs update
    	setInterval(fun() {
    		gsc.VisionSetNaked("aftermath", 5);
                    gsc.VisionSetPain("aftermath");
    	}, 1000);
    

  • [Release] [GSC] MapEdit
    undefined S3VDITO
    Jun 29, 2021, 12:22 PM

    updated: Rewritten from Chai to GSC


  • Give killstreak
    undefined S3VDITO
    May 29, 2020, 5:11 PM

    The answer is simple - it's impossible...

    Why?
    Everything is simple too: the game uses field pers which regulates killstreaks and not only that.
    (Field pers is currently not implemented in this version of PlutoniumIW5, but this is not implemented on Addon (Steam ver.) and InfinityScript (4D1/TeknoGods))

    At the moment, you can rewrite the MOAB logic from the GSC file, but it is worth noting that some functions on ChaiScript do not work yet (either nothing will happen, either you will get a server crash, or the function will work adequately)

    Example(with using pers field on GSC):

    giveKillstreak( streakName, isEarned, awardXp, owner, skipMiniSplash )
    {
    	if ( !IsDefined( level.killstreakFuncs[streakName] ) || tableLookup( KILLSTREAK_STRING_TABLE, 1, streakName, 0 ) == "" )
    	{
    		AssertMsg( "giveKillstreak() called with invalid killstreak: " + streakName );
    		return;
    	}	
    	//	for devmenu give with spectators in match 
    	if( !IsDefined( self.pers["killstreaks"] ) )
    		return;
    	
    	self endon ( "disconnect" );	
    	
    	if( !IsDefined( skipMiniSplash ) )
    		skipMiniSplash = false;
    
    	//	streaks given from crates go in the gimme 
    	index = undefined;
    	if ( !IsDefined( isEarned ) || isEarned == false )
    	{
    		// put this killstreak in the next available position
    		// 0 - gimme slot (that will index stacked killstreaks)
    		// 1-3 - cac selected killstreaks
    		// 4 - specialist all perks bonus
    		// 5 or more - stacked killstreaks
    
    		nextSlot = self.pers[ "killstreaks" ].size; // the size should be 5 by default, it will grow as they get stacked killstreaks
    		if( !IsDefined( self.pers[ "killstreaks" ][ nextSlot ] ) )
    			self.pers[ "killstreaks" ][ nextSlot ] = spawnStruct();
    
    		self.pers[ "killstreaks" ][ nextSlot ].available = false;
    		self.pers[ "killstreaks" ][ nextSlot ].streakName = streakName;
    		self.pers[ "killstreaks" ][ nextSlot ].earned = false;
    		self.pers[ "killstreaks" ][ nextSlot ].awardxp = IsDefined( awardXp ) && awardXp;
    		self.pers[ "killstreaks" ][ nextSlot ].owner = owner;
    		self.pers[ "killstreaks" ][ nextSlot ].kID = self.pers["kID"];
    		self.pers[ "killstreaks" ][ nextSlot ].lifeId = -1;
    		self.pers[ "killstreaks" ][ nextSlot ].isGimme = true;		
    		self.pers[ "killstreaks" ][ nextSlot ].isSpecialist = false;		
    
    		self.pers[ "killstreaks" ][ KILLSTREAK_GIMME_SLOT ].nextSlot = nextSlot;		
    		self.pers[ "killstreaks" ][ KILLSTREAK_GIMME_SLOT ].streakName = streakName;
    
    		index = KILLSTREAK_GIMME_SLOT;	
    		streakIndex = getKillstreakIndex( streakName );	
    		self setPlayerData( "killstreaksState", "icons", KILLSTREAK_GIMME_SLOT, streakIndex );
    		
    		// some things may need to skip the mini-splash, like deathstreaks that give killstreaks
    		if( !skipMiniSplash )
    		{
    			showSelectedStreakHint( streakName );		
    		}
    	}
    	else
    	{
    		for( i = KILLSTREAK_SLOT_1; i < KILLSTREAK_SLOT_3 + 1; i++ )
    		{
    			if( IsDefined( self.pers["killstreaks"][i] ) && 
    				IsDefined( self.pers["killstreaks"][i].streakName ) &&
    				streakName == self.pers["killstreaks"][i].streakName )
    			{
    				index = i;
    				break;
    			}
    		}		
    		if ( !IsDefined( index ) )
    		{
    			AssertMsg( "earnKillstreak() trying to give unearnable killstreak with giveKillstreak(): " + streakName );
    			return;
    		}		
    	}
    	
    	self.pers["killstreaks"][index].available = true;
    	self.pers["killstreaks"][index].earned = IsDefined( isEarned ) && isEarned;
    	self.pers["killstreaks"][index].awardxp = IsDefined( awardXp ) && awardXp;
    	self.pers["killstreaks"][index].owner = owner;
    	self.pers["killstreaks"][index].kID = self.pers["kID"];
    	//self.pers["kIDs_valid"][self.pers["kID"]] = true;
    	self.pers["kID"]++;
    
    	if ( !self.pers["killstreaks"][index].earned )
    		self.pers["killstreaks"][index].lifeId = -1;
    	else
    		self.pers["killstreaks"][index].lifeId = self.pers["deaths"];
    		
    	// the specialist streak type automatically turns on and there is no weapon to use
    	if( self.streakType == "specialist" && index != KILLSTREAK_GIMME_SLOT )
    	{
    		self.pers[ "killstreaks" ][ index ].isSpecialist = true;		
    		if( IsDefined( level.killstreakFuncs[ streakName ] ) )
    			self [[ level.killstreakFuncs[ streakName ] ]]();
    		//self thread updateKillstreaks();
    		self usedKillstreak( streakName, awardXp );
    	}
    	else
    	{
    		weapon = getKillstreakWeapon( streakName );
    		self giveKillstreakWeapon( weapon );	
    		
    		// NOTE_A (also see NOTE_B): before we change the killstreakIndexWeapon, let's make sure it's not the one we're holding
    		//	if we're currently holding something like an airdrop marker and we earned a killstreak while holding it then we want that to remain the weapon index
    		//	because if it's not, then when you throw it, it'll think we're using a different killstreak and not take it away but it'll take away the other one
    		if( IsDefined( self.killstreakIndexWeapon ) )
    		{
    			streakName = self.pers["killstreaks"][self.killstreakIndexWeapon].streakName;
    			killstreakWeapon = getKillstreakWeapon( streakName );
    			if( self GetCurrentWeapon() != killstreakWeapon )
    			{
    				self.killstreakIndexWeapon = index;
    			}
    		}
    		else
    		{
    			self.killstreakIndexWeapon = index;		
    		}
    	}
    		
    	self updateStreakSlots();
    	
    	if ( IsDefined( level.killstreakSetupFuncs[ streakName ] ) )
    		self [[ level.killstreakSetupFuncs[ streakName ] ]]();
    		
    	if ( IsDefined( isEarned ) && isEarned && IsDefined( awardXp ) && awardXp )
    		self notify( "received_earned_killstreak" );
    }
    

    _nuke.gsc

    #include common_scripts\utility;
    #include maps\mp\_utility;
    
    // the nuke ended the game in MW2, for MW3 it will be an MOAB, not end the game but kill the other team and emp them for 60 seconds, it will also change the visionset for the level
    
    init()
    {
    	precacheItem( "nuke_mp" );
    	precacheLocationSelector( "map_nuke_selector" );
    	precacheString( &"MP_TACTICAL_NUKE_CALLED" );
    	precacheString( &"MP_FRIENDLY_TACTICAL_NUKE" );
    	precacheString( &"MP_TACTICAL_NUKE" );
    
    	level.nukeVisionSet = "aftermath";
    
    	level._effect[ "nuke_player" ] = loadfx( "explosions/player_death_nuke" );
    	level._effect[ "nuke_flash" ] = loadfx( "explosions/player_death_nuke_flash" );
    	level._effect[ "nuke_aftermath" ] = loadfx( "dust/nuke_aftermath_mp" );
    
    	game["strings"]["nuclear_strike"] = &"MP_TACTICAL_NUKE";
    	
    	level.killstreakFuncs["nuke"] = ::tryUseNuke;
    
    	SetDvarIfUninitialized( "scr_nukeTimer", 10 );
    	SetDvarIfUninitialized( "scr_nukeCancelMode", 0 );
    	
    	level.nukeTimer = getDvarInt( "scr_nukeTimer" );
    	level.cancelMode = getDvarInt( "scr_nukeCancelMode" );
    
    	level.teamNukeEMPed["allies"] = false;
    	level.teamNukeEMPed["axis"] = false;
    	level.nukeEmpTimeout = 60.0;
    	level.nukeEmpTimeRemaining = int( level.nukeEmpTimeout );
    	level.nukeInfo = spawnStruct();
    	level.nukeDetonated = undefined;
    
    	level thread nuke_EMPTeamTracker();
    
    	level thread onPlayerConnect();
    
    /#
    	SetDevDvarIfUninitialized( "scr_nuke_empTimeout", 60.0 );
    	SetDevDvarIfUninitialized( "scr_nukeDistance", 5000 );
    	SetDevDvarIfUninitialized( "scr_nukeEndsGame", true );
    	SetDevDvarIfUninitialized( "scr_nukeDebugPosition", false );
    #/
    }
    
    tryUseNuke( lifeId, allowCancel )
    {
    	if( isDefined( level.nukeIncoming ) )
    	{
    		self iPrintLnBold( &"MP_NUKE_ALREADY_INBOUND" );
    		return false;	
    	}
    
    	if ( self isUsingRemote() && ( !isDefined( level.gtnw ) || !level.gtnw ) )
    		return false;
    
    	if ( !isDefined( allowCancel ) )
    		allowCancel = true;
    
    	self thread doNuke( allowCancel );
    	self notify( "used_nuke" );
    	
    	self maps\mp\_matchdata::logKillstreakEvent( "nuke", self.origin );
    	
    	return true;
    }
    
    delaythread_nuke( delay, func )
    {
    	level endon ( "nuke_cancelled" );
    
    	maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( delay );
    	
    	thread [[ func ]]();
    }
    
    doNuke( allowCancel )
    {
    	level endon ( "nuke_cancelled" );
    	
    	level.nukeInfo.player = self;
    	level.nukeInfo.team = self.pers["team"];
    
    	level.nukeIncoming = true;
    	
    	//maps\mp\gametypes\_gamelogic::pauseTimer();
    	//level.timeLimitOverride = true;
    	//setGameEndTime( int( gettime() + (level.nukeTimer * 1000) ) );
    	SetDvar( "ui_bomb_timer", 4 ); // Nuke sets '4' to avoid briefcase icon showing
    
    	if( level.teambased )
    	{
    		thread teamPlayerCardSplash( "used_nuke", self, self.team );
    	}
    	else
    	{
    		if( !level.hardcoreMode )
    			self IPrintLnBold( &"MP_FRIENDLY_TACTICAL_NUKE" );
    	}
    
    	level thread delaythread_nuke( (level.nukeTimer - 3.3), ::nukeSoundIncoming );
    	level thread delaythread_nuke( level.nukeTimer, ::nukeSoundExplosion );
    	level thread delaythread_nuke( level.nukeTimer, ::nukeSlowMo );
    	level thread delaythread_nuke( level.nukeTimer, ::nukeEffects );
    	level thread delaythread_nuke( (level.nukeTimer + 0.25), ::nukeVision );
    	level thread delaythread_nuke( (level.nukeTimer + 1.5), ::nukeDeath );
    	level thread delaythread_nuke( (level.nukeTimer + 1.5), ::nukeEarthquake );
    	level thread nukeAftermathEffect();
    	level thread update_ui_timers();
    
    	if ( level.cancelMode && allowCancel )
    		level thread cancelNukeOnDeath( self ); 
    
    	// leaks if lots of nukes are called due to endon above.
    	clockObject = spawn( "script_origin", (0,0,0) );
    	clockObject hide();
    
    	nukeTimer = level.nukeTimer;
    	while( nukeTimer > 0 )
    	{
    		// TODO: get a new sound for this so we don't remind people of the old nuke
    		clockObject playSound( "ui_mp_nukebomb_timer" );
    		wait( 1.0 );
    		nukeTimer--;
    	}
    }
    
    cancelNukeOnDeath( player )
    {
    	player waittill_any( "death", "disconnect" );
    
    	if ( isDefined( player ) && level.cancelMode == 2 )
    		player thread maps\mp\killstreaks\_emp::EMP_Use( 0, 0 );
    
    
    	//maps\mp\gametypes\_gamelogic::resumeTimer();
    	//level.timeLimitOverride = false;
    
    	SetDvar( "ui_bomb_timer", 0 ); // Nuke sets '4' to avoid briefcase icon showing
    	level.nukeIncoming = undefined;
    
    	level notify ( "nuke_cancelled" );
    }
    
    nukeSoundIncoming()
    {
    	level endon ( "nuke_cancelled" );
    
    	foreach( player in level.players )
    		player playlocalsound( "nuke_incoming" );
    }
    
    nukeSoundExplosion()
    {
    	level endon ( "nuke_cancelled" );
    
    	foreach( player in level.players )
    	{
    		player playlocalsound( "nuke_explosion" );
    		player playlocalsound( "nuke_wave" );
    	}
    }
    
    nukeEffects()
    {
    	level endon ( "nuke_cancelled" );
    
    	SetDvar( "ui_bomb_timer", 0 );
    	//setGameEndTime( 0 );
    
    	level.nukeDetonated = true;
    
    	foreach( player in level.players )
    	{
    		playerForward = anglestoforward( player.angles );
    		playerForward = ( playerForward[0], playerForward[1], 0 );
    		playerForward = VectorNormalize( playerForward );
    	
    		nukeDistance = 5000;
    		/# nukeDistance = getDvarInt( "scr_nukeDistance" );	#/
    
    		nukeEnt = Spawn( "script_model", player.origin + ( playerForward * nukeDistance ) );
    		nukeEnt setModel( "tag_origin" );
    		nukeEnt.angles = ( 0, (player.angles[1] + 180), 90 );
    
    		/#
    		if ( getDvarInt( "scr_nukeDebugPosition" ) )
    		{
    			lineTop = ( nukeEnt.origin[0], nukeEnt.origin[1], (nukeEnt.origin[2] + 500) );
    			thread draw_line_for_time( nukeEnt.origin, lineTop, 1, 0, 0, 10 );
    		}
    		#/
    
    		nukeEnt thread nukeEffect( player );
    		//player.nuked = true;
    	}
    }
    
    nukeEffect( player )
    {
    	level endon ( "nuke_cancelled" );
    
    	player endon( "disconnect" );
    
    	waitframe();
    	PlayFXOnTagForClients( level._effect[ "nuke_flash" ], self, "tag_origin", player );
    }
    
    nukeAftermathEffect()
    {
    	level endon ( "nuke_cancelled" );
    
    	level waittill ( "spawning_intermission" );
    	
    	afermathEnt = getEntArray( "mp_global_intermission", "classname" );
    	afermathEnt = afermathEnt[0];
    	up = anglestoup( afermathEnt.angles );
    	right = anglestoright( afermathEnt.angles );
    
    	PlayFX( level._effect[ "nuke_aftermath" ], afermathEnt.origin, up, right );
    }
    
    nukeSlowMo()
    {
    	level endon ( "nuke_cancelled" );
    
    	//SetSlowMotion( <startTimescale>, <endTimescale>, <deltaTime> )
    	SetSlowMotion( 1.0, 0.25, 0.5 );
    	level waittill( "nuke_death" );
    	SetSlowMotion( 0.25, 1, 2.0 );
    }
    
    nukeVision()
    {
    	level endon ( "nuke_cancelled" );
    
    	level.nukeVisionInProgress = true;
    	VisionSetNaked( "mpnuke", 3 );
    
    	level waittill( "nuke_death" );
    
    	VisionSetNaked( level.nukeVisionSet, 5 );
    	VisionSetPain( level.nukeVisionSet );
    }
    
    nukeDeath()
    {
    	level endon ( "nuke_cancelled" );
    
    	level notify( "nuke_death" );
    	
    	maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
    	
    	AmbientStop(1);
    
    	foreach( player in level.players )
    	{
    		// don't kill teammates
    		if( level.teambased )
    		{
    			if( IsDefined( level.nukeInfo.team ) && player.team == level.nukeInfo.team )
    				continue;
    		}
    		// ffa, don't kill the player who called it
    		else
    		{
    			if( IsDefined( level.nukeInfo.player ) && player == level.nukeInfo.player )
    				continue;
    		}
    
    		player.nuked = true;	
    		if ( isAlive( player ) )
    			player thread maps\mp\gametypes\_damage::finishPlayerDamageWrapper( level.nukeInfo.player, level.nukeInfo.player, 999999, 0, "MOD_EXPLOSIVE", "nuke_mp", player.origin, player.origin, "none", 0, 0 );
    	}
    
    	//level.postRoundTime = 10;
    
    	//nukeEndsGame = true;
    
    	//if ( level.teamBased )
    	//	thread maps\mp\gametypes\_gamelogic::endGame( level.nukeInfo.team, game["strings"]["nuclear_strike"], true );
    	//else
    	//{
    	//	if ( isDefined( level.nukeInfo.player ) )
    	//		thread maps\mp\gametypes\_gamelogic::endGame( level.nukeInfo.player, game["strings"]["nuclear_strike"], true );
    	//	else
    	//		thread maps\mp\gametypes\_gamelogic::endGame( level.nukeInfo, game["strings"]["nuclear_strike"], true );
    	//}
    
    	// emp jam them after death, if we do before then the timing is off
    	level thread nuke_EMPJam();
    
    	// since the nuke death happened, the nuke is no longer incoming
    	level.nukeIncoming = undefined;
    }
    
    nukeEarthquake()
    {
    	level endon ( "nuke_cancelled" );
    
    	level waittill( "nuke_death" );
    
    	// TODO: need to get a different position to call this on
    	//earthquake( 0.6, 10, nukepos, 100000 );
    
    	//foreach( player in level.players )
    		//player PlayRumbleOnEntity( "damage_heavy" );
    }
    
    
    //waitForNukeCancel()
    //{
    //	self waittill( "cancel_location" );
    //	self setblurforplayer( 0, 0.3 );
    //}
    //
    //endSelectionOn( waitfor )
    //{
    //	self endon( "stop_location_selection" );
    //	self waittill( waitfor );
    //	self thread stopNukeLocationSelection( (waitfor == "disconnect") );
    //}
    //
    //endSelectionOnGameEnd()
    //{
    //	self endon( "stop_location_selection" );
    //	level waittill( "game_ended" );
    //	self thread stopNukeLocationSelection( false );
    //}
    //
    //stopNukeLocationSelection( disconnected )
    //{
    //	if ( !disconnected )
    //	{
    //		self setblurforplayer( 0, 0.3 );
    //		self endLocationSelection();
    //		self.selectingLocation = undefined;
    //	}
    //	self notify( "stop_location_selection" );
    //}
    
    nuke_EMPJam()
    {
    	level endon ( "game_ended" );
    
    	level maps\mp\killstreaks\_emp::destroyActiveVehicles( level.nukeInfo.player, getOtherTeam( level.nukeInfo.team ) );
    
    	// since nukes do emp damage, might as well emp jam for a little while also
    
    	// end emp threads
    	if( level.teambased )
    	{
    		level notify( "EMP_JamTeam" + "axis" );
    		level notify( "EMP_JamTeam" + "allies" );
    	}
    	else
    	{
    		level notify( "EMP_JamPlayers" );
    	}
    
    	// set this up to end itself if called again
    	level notify( "nuke_EMPJam" );
    	level endon( "nuke_EMPJam" );
    
    	if( level.teambased )
    	{
    		level.teamNukeEMPed[ getOtherTeam( level.nukeInfo.team ) ] = true;
    	}
    	else
    	{
    		level.teamNukeEMPed[ level.nukeInfo.team ] = true;
    		level.teamNukeEMPed[ getOtherTeam( level.nukeInfo.team ) ] = true;
    	}
    
    	level notify( "nuke_emp_update" );
    
    /#
    	level.nukeEmpTimeout = GetDvarFloat( "scr_nuke_empTimeout" );
    #/
    	level thread keepNukeEMPTimeRemaining();
    	maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( level.nukeEmpTimeout );
    
    	if( level.teambased )
    	{
    		level.teamNukeEMPed[ getOtherTeam( level.nukeInfo.team ) ] = false;
    	}
    	else
    	{
    		level.teamNukeEMPed[ level.nukeInfo.team ] = false;
    		level.teamNukeEMPed[ getOtherTeam( level.nukeInfo.team ) ] = false;
    	}
    
    	foreach( player in level.players )
    	{
    		if( level.teambased && player.team == level.nukeInfo.team )
    			continue;
    
    		player.nuked = undefined;
    	}
    
    	// we want the nuke vision to last the rest of this match, leaving here in case we change our minds :)
    	//level.nukeVisionInProgress = undefined;
    	//VisionSetNaked( "", 5.0 ); // go to default visionset
    
    	level notify( "nuke_emp_update" );
    	level notify ( "nuke_emp_ended" );
    }
    
    keepNukeEMPTimeRemaining()
    {
    	level notify( "keepNukeEMPTimeRemaining" );
    	level endon( "keepNukeEMPTimeRemaining" );
    
    	level endon( "nuke_emp_ended" );
    
    	// we need to know how much time is left for the unavailable string
    	level.nukeEmpTimeRemaining = int( level.nukeEmpTimeout );
    	while( level.nukeEmpTimeRemaining )
    	{
    		wait( 1.0 );
    		level.nukeEmpTimeRemaining--;
    	}
    }
    
    nuke_EMPTeamTracker()
    {
    	level endon ( "game_ended" );
    
    	for ( ;; )
    	{
    		level waittill_either ( "joined_team", "nuke_emp_update" );
    
    		foreach ( player in level.players )
    		{
    			if ( player.team == "spectator" )
    				continue;
    
    			if( level.teambased )
    			{
    				if( IsDefined( level.nukeInfo.team ) && player.team == level.nukeInfo.team )
    					continue;
    			}
    			else
    			{
    				if( IsDefined( level.nukeInfo.player ) && player == level.nukeInfo.player )
    					continue;
    			}
    
    			player SetEMPJammed( level.teamNukeEMPed[ player.team ] );
    		}
    	}
    }
    
    onPlayerConnect()
    {
    	for(;;)
    	{
    		level waittill("connected", player);
    		player thread onPlayerSpawned();
    	}
    }
    
    onPlayerSpawned()
    {
    	self endon("disconnect");
    
    	for(;;)
    	{
    		self waittill( "spawned_player" );
    
    		if( level.teamNukeEMPed[ self.team ] )
    		{
    			if( level.teambased )
    				self SetEMPJammed( true );
    			else
    			{
    				if( !IsDefined( level.nukeInfo.player ) || ( IsDefined( level.nukeInfo.player ) && self != level.nukeInfo.player ) )
    					self SetEMPJammed( true );
    			}
    		}
    
    		// make sure the vision set stays on between deaths
    		if( IsDefined( level.nukeDetonated ) )
    			self VisionSetNakedForPlayer( level.nukeVisionSet, 0 );
    	}
    }
    
    update_ui_timers()
    {
    	level endon ( "game_ended" );
    	level endon ( "disconnect" );
    	level endon ( "nuke_cancelled" );
    	level endon ( "nuke_death" );
    
    	nukeEndMilliseconds = (level.nukeTimer * 1000) + gettime();
    	SetDvar( "ui_nuke_end_milliseconds", nukeEndMilliseconds );
    
    	level waittill( "host_migration_begin" );
    
    	timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
    
    	if ( timePassed > 0 )
    	{
    		SetDvar( "ui_nuke_end_milliseconds", nukeEndMilliseconds + timePassed );
    	}
    }
    
    

  • Make model solid
    S3VDITOundefined S3VDITO
    Jun 5, 2020, 7:38 PM

    Alas, because of the Fields bug you cannot do this.

    Moreover, you make models wrong

    // Here is correct code snippet
    // but it dosn't work
    // entity.get("target") => exception
    
    global _airdropCollision;
    
    level.onNotify("prematch_done", fun(args) {
    	var entity = gsc.getEnt("care_package", "targetname");
            // ERROR
            _airdropCollision = gsc.getEnt(entity.get("target"), "targetname");
    	
    	
    	var solidPackage = gsc.spawn("script_model", [0,0,0]);
    	solidPackage.setModel("com_plasticcase_enemy");
    	solidPackage.clonebrushmodeltoscriptmodel(_airdropCollision);
    });
    
    

    On the expanses of GitHub there is an interesting source, the Chai parser for the game is implemented there, if you have a lot of free time you can implement solid models in C ++ (the addresses for calling in-game functions coincide with plutonium)

    fields and their number (this can be used to implement getfield in C++)
    "target" => 5
    "targetname" => 6


  • A request for a mw3 survival mod / improvments
    S3VDITOundefined S3VDITO
    Aug 8, 2020, 11:39 AM

    Recker247 i once tried to make a survival mode (throw layouts, make small menu weapon shop(fail) and make bots movement(fail)), but stopped at bots and did not advance

    It is unlikely that someone else is working on it ...


  • Storing players data with chaiscript
    S3VDITOundefined S3VDITO
    Jun 12, 2020, 12:20 PM

    Diavolo
    I may not answer all questions, but I think it can help you

    in GSC scripts of the game, players are stored in an array(it was also done in the InfinityScript, it uses the List<T>, and steam addon), players can also be found through GetEntArray(but Chai does not support array returns from GSC functions).

    If you want to update your Huds, then you have to move them outside the method

    level.onNotify("connected", fun(arguments) {
            // you can make new var
    
        var player = arguments[0];
    	var hud_text = gsc.newClientHudElem(arguments[0]);
    	hud_text.set("x", 540); //Approx middle of the screen
    	hud_text.set("y", 0);
    	hud_text.set("font", "hudbig");
    	hud_text.set("fontscale", 0.65);
    	hud_text.setText("^1Killstreak: 0");
            player.set("your_field_name", hud_text);
    });
    
    def onPlayerKilled(ePlayer, eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitloc, iTimeOffset, iDeathAnimDuration)
    {
     // WARN: frequent access to fields may cause exceptions
     eAttacker.get("your_field_name").setText("^1Killstreak: " + eAttacker.get("kills"));
    // OR
    // eAttacker.get("your_field_name").setText("^1Killstreak: " + eAttacker.GetPlayerData("killstreaksState", "count"));
     ePlayer.get("your_field_name").setText("^1Killstreak: 0");
    }
    
    add_callback_player_killed(onPlayerKilled); //Copied this line from the pluto framework github
    

    I can’t check it, but in theory it should work, but you can modify the code yourself if necessary.

    the game already has some player data stores implemented

    var info = player.get("FIELD NAME");
    // FIELDS NAMES FOR ENTITY
    
    code_classname
    classname
    origin
    model
    spawnflags
    target
    targetname
    count
    health
    dmg 
    angles 
    birthtime
    script_linkname
    slidevelocity
    name
    sessionteam
    sessionstate
    maxhealth
    score 
    deaths
    statusicon 
    headicon 
    headiconteam 
    kills 
    assists 
    hasradar
    isradarblocked
    radarstrength 
    radarshowenemydirection
    radarmode 
    forcespectatorclient
    killcamentity
    killcamentitylookat
    archivetime
    psoffsettime
    pers
    veh_speed
    veh_pathspeed
    veh_transmission
    veh_pathdir
    veh_pathtype
    veh_topspeed
    veh_brake
    veh_throttle
    script_linkname
    script_noteworthy
    speed
    lookahead
    
    // FIELDS NAMES FOR HUDS
    x
    y
    z
    fontscale
    font
    alignx
    aligny
    horzalign
    vertalign
    color
    alpha
    label
    sort
    foreground
    lowresbackground
    hidewhendead
    hidewheninmenu
    glowcolor
    glowalpha
    archived
    hidein3rdperson
    

    if you do not need kills(killsrteaks only), you can use GetPlayerData

    var killsCount = player.GetPlayerData("killstreaksState", "count");
    
  • 1 / 1
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Donate