Go Back   Steam Users' Forums > Steam Game Discussions > H - L > Left 4 Dead 2 > Custom Campaigns / Maps

Reply
 
Thread Tools Display Modes
Old 04-20-2012, 03:25 PM   #1
SuperSpiker
 
Join Date: Feb 2012
Reputation: 0
Posts: 12
Create Entitys in Vscript?

The only way I've figured out how to create an entity in vscript is to use SendToConsole via ent_create. This method isn't ideal as the console commands don't wait for the script. Timing becomes a major issue as a result. I could use timers to delay but that's far from ideal as well and in some cases wont work.

This is what I'm currently using:

Code:
SendToConsole("ent_create weapon_scavenge_item_spawn")
Is there a way to create an entity using vscript without using SendToConsole?
SuperSpiker is offline  
Reply With Quote
Old 04-20-2012, 04:10 PM   #2
shotgunefx
 
Join Date: Jan 2010
Reputation: 151
Posts: 2,407
Not in L4D2 solely with scripts, Portal 2 I believe can. They have a lot more functionality with vscripts.

SendToConsole is also going to respect cheat flags. It may help if you can give us more an idea of what you're trying to accomplish.

env_entity_maker's have additional scripting support, so that's how you would normally create entities with script, but seeing you're not just adding these to the map, I'm guessing it's a mutation type of deal?
shotgunefx is offline   Reply With Quote
Old 04-20-2012, 05:43 PM   #3
SuperSpiker
 
Join Date: Feb 2012
Reputation: 0
Posts: 12
Quote:
Originally Posted by shotgunefx View Post
...I'm guessing it's a mutation type of deal?
I guess you could call it a mutation... but not in the official capacity.

I am modifying a scavenge map (Mall Atrium) on the xbox 360. I'd like to add an additional generator for players to be able to fill gas cans. I'd also like to remove all the gas cans placed on the map by Valve then create new ones and place them in new locations.

I have (most of) this already working by putting a vscript in scripts/vscripts. L4D2 will run a MapScript as long as the nut file is named the same as the map (c1m4_atrium.nut)

Because this is all targeted at xbox gameplay I am unable to use hammer to do anything. Therefore I am having to do everything via console commands and vscript... I don't think there is any other way to do it.

So I have been painfully piecing the below vscript together and testing by trial and error. The syntax is my biggest unknown. If anyone knows of a better way of doing what I am attempting I am all ears


Code:
// Timer Flags
thirtiethsOfASecondTimer <- 0
entCreationDelayInThirtieths <- 3
entCreationTimerStartTime <- 0

// PreStage Flags
preStage <- 1
preStageTwoFirstTimeFlag <- 1
preStageThreeStartTime <- 0

// Phase Flags
phase <- 0
phaseOne <- 0
phaseTwoNumCansCreated <- 0


posX <- 0.0
posY <- 0.0
posZ <- 0.0
angX <- 0.0
angY <- 0.0
angZ <- 0.0

// New Scavenge Cans Orgin and Angles
scavCansPlacement <-
[
	[ -3965, -4248.14, 547.719, 0, 314, 0 ],
	[ -3930, -4248.14, 547.719, 0, 314, 0 ],
	[ -2969.12, -4211.3, 291.719, 0, 0, 0 ],
	[ -2930.27, -4249.96, 291.719, 0, 206, 0 ],
	[ -2966, -4430.71, 292.219, 0, 30, 0 ],
	[ -3835.71, -4434.21, 455.719, 0, 299, 0 ],
	[ -3819.37, -4437.12, 455.719, 0, 57, 0 ],
	[ -3807.98, -4430.94, 455.719, 0, 169, 0 ],
	[ -4949.15, -4247.01, 291.719, 0, 310, 0 ],
	[ -5776.49, -3071.39, 291.719, 0, 179, 0 ],
	[ -5778.05, -3235.49, 291.719, 0, 33, 0 ],
	[ -5779.84, -3221.33, 291.719, 0, 53, 0 ],
	[ -3509.42, -3544.65, 291.719, 0, 219, 0 ],
	[ -4072.38, -4471.76, 291.719, 0, 161, 0 ],
	[ -4061.4, -4473.13, 291.719, 0, 164, 0 ],
	[ -4051.47, -4474.47, 291.719, 0, 298, 0 ],
	[ -3965, -4248.14, 547.719, 0, 314, 0 ],
]

function Update()
{
	thirtiethsOfASecondTimer++
	
	if(Director.GetGameMode() == "scavenge")
	{
		if(preStage == 1)
		{
		//	THIS PHASE RUNS IMMEDIATELY!! THIS MEANS NOW! VERY FAST. AND PRETTY MUCH NOTHING WILL WORK HERE. SO DON'T TRY.
		//	YOU CAN SEND A MESSAGE TO THE CONSOLE TO TELL THAT THE SCRIPT IS RUNNING, BUT THAT'S ABOUT IT.

			Msg("DOING PRESTAGE 1: INITIATING CUSTOM SCRIPT" + "\n")
		
			preStage = 2
		}

		if(preStage == 2)
		{
		//	THIS PHASE RUNS OVER AND OVER AND OVER UNTIL A COMMON ZOMBIE NECK MODEL CAN BE CREATED

			if(preStageTwoFirstTimeFlag == 1)
			{
				Msg("DOING PRESTAGE 2: WAITING TILL CAN CREATE A ZOMBIE NECK MODEL" + "\n")
			
				preStageTwoFirstTimeFlag <- 0
			}
			
			SendToConsole("sv_cheats 1")

			SendToConsole("sb_all_bot_game 1")
			
			SendToConsole("prop_dynamic_create infected/common_fem_infected_w_neck.mdl")

			placeholderEnt <- null
		
			while((placeholderEnt <- Entities.FindByModel(placeholderEnt,"models/infected/common_fem_infected_w_neck.mdl")) != null)
			{
				preStage = 3

				preStageThreeStartTime <- thirtiethsOfASecondTimer + 15
			}
		}

		if(preStage == 3)
		{
			if(thirtiethsOfASecondTimer >= preStageThreeStartTime)
			{
			//	THIS PHASE WAITS FOR A BIT TO GIVE THE MODELS A CHANCE TO SPAWN (THEY LOAD SLOW OR SOMETHING)
				
				Msg("DOING PRESTAGE 3: CREATING ZOMBIE NECK MODELS" + "\n")

				placeholderEntTwo <- null
			
				while((placeholderEntTwo <- Entities.FindByModel(placeholderEntTwo,"models/infected/common_fem_infected_w_neck.mdl")) != null)
				{
					placeholderEntTwo.__KeyValueFromString("targetname", "ZombieNecks")				
				}
				
				preStage = 5
				phaseOne = 1
				phase <- 1
			}
		}

		if(phaseOne == 1)
		{
		//	YOU CAN DO PRETTY MUCH ANYTHING HERE
	
			if(phase == 1)
			{
				Msg("DOING PHASE 1: REMOVE ZOMBIE NECK MODELS AND DOING CUSTOMIZATIONS" + "\n")
							

			//	DO THIS FIRST
				SendToConsole("ent_remove_all ZombieNecks")

				SendToConsole("ent_remove_all weapon_scavenge_item_spawn")
				
				SendToConsole("prop_dynamic_create props_vehicles/radio_generator.mdl")
				
				gasIndex <- 0
				
				while(gasIndex < scavCansPlacement.len())
				{
					SendToConsole("ent_create weapon_scavenge_item_spawn")
				
					gasIndex++
				}
				
				SendToConsole("ent_create point_prop_use_target")
				
				Msg("\nStarting Timer\n")
					
				entCreationTimerStartTime <- thirtiethsOfASecondTimer
				
				phase++
			}
			
			if(phase == 2)
			{
				Msg("DOING YOUR PHASE 2: SPAWN AND POSITION GENERATOR MODEL, POINT_PROP_USE_TARGET & GAS CANS" + "\n")

				if(thirtiethsOfASecondTimer - entCreationTimerStartTime == entCreationDelayInThirtieths)
				{
					Msg("\nNaming and moving generator\n")
					
					gennyEnt <- Entities.FindByModel(null, "models/props_vehicles/radio_generator.mdl")

					if(gennyEnt)
					{
						gennyEnt.__KeyValueFromString("targetname", "genny")
					
						gennyEnt.SetOrigin(Vector(-4453.427246,-3974.960205,136.031250))
						
						gennyEnt.SetForwardVector(Vector(0.0,84.455269,0.000000))
					}
					else
					{
						Msg("CANT FIND GENNY MODEL")
					}

					Msg("\nDone Naming and moving generator\n")

					Msg("\nNaming and moving point_prop_use_target\n")

					phil <- null
					
					while((phil <- Entities.FindByClassname(phil, "point_prop_use_target")) != null)
					{
						if(phil)
						{
							philName <- phil.GetName()

							if(philName.len() == 0)
							{
								phil.__KeyValueFromString("targetname", "phil")
								phil.__KeyValueFromInt("spawnflags", 2)
								
								phil.SetOrigin(Vector(-4399.12, -3971.36, 192.61))
								phil.SetForwardVector(Vector(0 0 0))
							}
						}
					}
						
					Msg("\nDone Naming and moving point_prop_use_target\n")
					
					Msg("\nNaming and moving Gas Cans\n")

					ScvCan <- null
					
					while((ScvCan <- Entities.FindByClassname(ScvCan, "weapon_scavenge_item_spawn")) != null)
					{
						if(ScvCan)
						{
							ScvCanName <- ScvCan.GetName()

							if(ScvCanName.len() == 0)
							{
								ScvCan.__KeyValueFromString("targetname", "ScvCan")
					            ScvCan.__KeyValueFromInt("spawnflags", 2)
								
								posX <- scavCansPlacement[phaseTwoNumCansCreated][0]
								posY <- scavCansPlacement[phaseTwoNumCansCreated][1]
								posZ <- scavCansPlacement[phaseTwoNumCansCreated][2]
					
								angX <- scavCansPlacement[phaseTwoNumCansCreated][3]
								angY <- scavCansPlacement[phaseTwoNumCansCreated][4]
								angZ <- scavCansPlacement[phaseTwoNumCansCreated][5]
								
								ScvCan.SetOrigin(Vector(posX, posY, posZ))
						
								ScvCan.SetForwardVector(Vector(angX, angY, angZ))
								
								phaseTwoNumCansCreated++
							}
						}
						else
						{
							Msg("CANT FIND SCVCAN")
						}
					}
					
					Msg("\nDone Naming and moving Gas Cans\n")

					phase++
				}
			}
		}
	}
}
SuperSpiker is offline   Reply With Quote
Old 04-20-2012, 05:58 PM   #4
shotgunefx
 
Join Date: Jan 2010
Reputation: 151
Posts: 2,407
Quote:
Originally Posted by SuperSpiker View Post
I guess you could call it a mutation... but not in the official capacity.

I am modifying a scavenge map (Mall Atrium) on the xbox 360. I'd like to add an additional generator for players to be able to fill gas cans. I'd also like to remove all the gas cans placed on the map by Valve then create new ones and place them in new locations.

I have (most of) this already working by putting a vscript in scripts/vscripts. L4D2 will run a MapScript as long as the nut file is named the same as the map (c1m4_atrium.nut)

Because this is all targeted at xbox gameplay I am unable to use hammer to do anything. Therefore I am having to do everything via console commands and vscript... I don't think there is any other way to do it.

So I have been painfully piecing the below vscript together and testing by trial and error. The syntax is my biggest unknown. If anyone knows of a better way of doing what I am attempting I am all ears
Hmmm xbox...

Well here's a suggestion. Instead of trying to create new spawns and remove the old ones, just move them to the new locations using ent.SetOrigin(), it takes a vector, not numbers so you'd want it like

can.SetOrigin(Vector(11,22,33))

You could store those Vector declarations in your array instead of numbers


I think for the angles, can.SetForwardVector would do it

Can you override the commentary txt file or no? If so, you could add entities to that
shotgunefx is offline   Reply With Quote
Old 04-20-2012, 06:15 PM   #5
shotgunefx
 
Join Date: Jan 2010
Reputation: 151
Posts: 2,407
And as far as editing the commentary file...
If there's not already a Entity section, it looks like this
Code:
"Entities"
{


entity
{
    "id" "48530"
    "classname" "point_viewcontrol"
    "acceleration" "500"
    "angles" "0 0 0"
    "deceleration" "500"
    "fov" "40"
    "fov_rate" "1.0"
    "spawnflags" "136"
    
    "target" "!bill"
    "targetattachment" "eyes"
    "targetname" "poster_cam"
    "wait" "10"
    "origin" "6899 2077 55"
    "vscripts" "lbcam.nut"
    "thinkfunction" "Think"
    "mapupdate" "1"
}
}
The mapupdate key is important. Some things won't work right, prop_physics don't seem to wake up, also dynamic ents parented to them (car+glass for instance) get goofy as well
shotgunefx is offline   Reply With Quote
Old 04-20-2012, 07:55 PM   #6
SuperSpiker
 
Join Date: Feb 2012
Reputation: 0
Posts: 12
Quote:
Originally Posted by shotgunefx View Post
And as far as editing the commentary file...
There doesn't seem to be a commentary.txt file for c1m4_atrium.

There are commentary.txt files for other maps such as c1m2_streets_commentary.txt so I guess I'll just create one for c1m4_atrium_commentary.txt and see what happens...
SuperSpiker is offline   Reply With Quote
Old 04-20-2012, 08:09 PM   #7
shotgunefx
 
Join Date: Jan 2010
Reputation: 151
Posts: 2,407
Quote:
Originally Posted by SuperSpiker View Post
There doesn't seem to be a commentary.txt file for c1m4_atrium.

There are commentary.txt files for other maps such as c1m2_streets_commentary.txt so I guess I'll just create one for c1m4_atrium_commentary.txt and see what happens...
If you can do that, you should have a lot more flexibility
shotgunefx is offline   Reply With Quote
Old 04-27-2012, 02:49 PM   #8
SuperSpiker
 
Join Date: Feb 2012
Reputation: 0
Posts: 12
So I was able to use the commentary file to create a few gas cans on the map! Nice! But... can you elaborate more about what entities don't work in the commentary file? The reason I ask is because I am unable to get a simple static_prop into the map using the commentary file.

This is what I have (the gas cans spawn but the static_prop kitchen table does not)

Code:
"Entities"
{
 "entity"
 {
	"classname" "weapon_scavenge_item_spawn"
	"angles" "90 -120 0"
	"body" "0"
	"disableshadows" "1"
	"glowstate" "3"
	"model" "models/props_junk/gascan001a.mdl"
	"skin" "0"
	"solid" "0"
	"spawnflags" "2"
	"targetname" "scavcan"
	connections
	{
		"OnItemPickedUp" "@director:runscriptcode:DirectorScript.MapScript.LocalScript.GasCanTouched():0:-1"
	}
	"origin" "-4648.000 -3712.000 62.031"
	editor
	{
		"color" "0 0 200"
		"visgroupid" "2"
		"visgroupshown" "1"
		"visgroupautoshown" "1"
		"logicalpos" "[5000 4000]"
    }
	"mapupdate" "1" 
 }
 "entity"
 {
	"classname" "weapon_scavenge_item_spawn"
	"angles" "90 -120 0"
	"body" "0"
	"disableshadows" "1"
	"glowstate" "3"
	"model" "models/props_junk/gascan001a.mdl"
	"skin" "0"
	"solid" "0"
	"spawnflags" "2"
	"targetname" "scavcan"
	connections
	{
		"OnItemPickedUp" "@director:runscriptcode:DirectorScript.MapScript.LocalScript.GasCanTouched():0:-1"
	}
	"origin" "-4648.000 -3712.000 62.031"
	editor
	{
		"color" "0 0 200"
		"visgroupid" "2"
		"visgroupshown" "1"
		"visgroupautoshown" "1"
		"logicalpos" "[5000 4000]"
    }
	"mapupdate" "1" 
 }
 "entity"
 {
	"classname" "prop_static"
	"angles" "0 0 0"
	"disableselfshadowing" "1"
	"disablevertexlighting" "1"
	"fademindist" "-1"
	"fadescale" "1"
	"model" "models/props_interiors/table_kitchen.mdl"
	"renderamt" "255"
	"rendercolor" "255 255 255"
	"skin" "0"
	"solid" "6"
	"origin" "-3987.69 -3665.84 1"
	editor
	{
		"color" "255 255 0"
		"visgroupshown" "1"
		"visgroupautoshown" "1"
		"logicalpos" "[0 1500]"
	}
	"mapupdate" "1"
 }
}
Can you notice any reason why the commentary file wont spawn the static_prop?

Thanks again.
SuperSpiker is offline   Reply With Quote
Old 04-27-2012, 03:02 PM   #9
shotgunefx
 
Join Date: Jan 2010
Reputation: 151
Posts: 2,407
Quote:
Originally Posted by SuperSpiker View Post
So I was able to use the commentary file to create a few gas cans on the map! Nice! But... can you elaborate more about what entities don't work in the commentary file? The reason I ask is because I am unable to get a simple static_prop into the map using the commentary file.

This is what I have (the gas cans spawn but the static_prop kitchen table does not)

...

Can you notice any reason why the commentary file wont spawn the static_prop?

Thanks again.
Glad that worked. I would guess static props don't work as they aren't really an entity


prop_dynamic I believe works, though I don't know if that will work with that particular model. If not probably could use a prop_dynamic_override or something.

As far as what doesn't work, I've only tried a few things. I don't think brush triggers work, but I can't remember a 100%, prop_physics don't seem to wake up on their own on map load. You could probably specify it's location exactly and then just wake it up via script.

Other than that, you'll probably have to just figure it out by trial and error
shotgunefx is offline   Reply With Quote
Old 04-27-2012, 06:34 PM   #10
Tabbernaut
 
Join Date: Feb 2011
Reputation: 516
Posts: 764
I'm pretty sure the limitations will be similar to Stripper:source's add function. prop_physics_override will work, for instance, but no brush entities will be added at all.

I don't expect the commentary.txt to offer possibilities to remove or modify existing entities, so stripper is usually the better choice, if you have server control (but I guess that's exactly the point of this alternative).
Tabbernaut is offline   Reply With Quote
Old 04-27-2012, 09:45 PM   #11
SuperSpiker
 
Join Date: Feb 2012
Reputation: 0
Posts: 12
Quote:
Originally Posted by Tabbernaut View Post
I'm pretty sure the limitations will be similar to Stripper:source's add function. prop_physics_override will work, for instance, but no brush entities will be added at all.

I don't expect the commentary.txt to offer possibilities to remove or modify existing entities, so stripper is usually the better choice, if you have server control (but I guess that's exactly the point of this alternative).
Keep in mind that I am modifying existing maps on the xbox 360. So the options are extremely limited. Stripper would be awesome but it obviously wont run on the 360.

What would be REALLY nice is if I was able to convert PC bsp files to 360 bsp map files. I'm not sure if this has already been done yet but in theory it seems like all you would need to do is take a PC bsp file and convert it from little-endian to big-endian and then compress it using LMZA. I think the compression and the endianess are the only differences between xbox bsp files and PC bsp files. Can anyone confirm this? I'm considering writing some tools to attempt these conversions. Seems odd that nobody has attempted this yet...

The VMEX based bspsource tool can decompile xbox 360 compressed and big-endian encoded maps. It does the reverse of what I'm looking to do... I really wish it was able to recompile the xbox 360 compressed/big-endian maps.

If I had the ability to convert PC bsp files to xbox formatted bsp files I could use Hammer (like all the PC users already can!!!) to modify existing 360 maps... therefore solving all my current problems and I wouldn't have to resort to all of these hackish tactics (commentary.txt & vscript) to change 360 maps.
SuperSpiker is offline   Reply With Quote
Reply

Go Back   Steam Users' Forums > Steam Game Discussions > H - L > Left 4 Dead 2 > Custom Campaigns / Maps


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT -7. The time now is 10:51 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2013, vBulletin Solutions, Inc.
Site Content Copyright Valve Corporation 1998-2012, All Rights Reserved.