Call of Duty 4: Vending Machine: Difference between revisions
(improvements and fixes) |
m (This is nicer) |
||
Line 79: | Line 79: | ||
Key: hintstring | Key: hintstring | ||
Value: Press [^ | Value: Press^3 [{+activate}] ^7to have a drink | ||
Key: targetname | Key: targetname |
Revision as of 13:53, 23 February 2012
By Kill3r
This tutorial will show you how to add a vending machine that when used heals you and a bottle pops out of it like in (or will be in) the rat_house_v2 map.
REMEMBER: Anywhere that says "yourmapname" change to what your map is called, like mp_funny_bunny
Adding the vending machine model
First off, open the map you want to add the vending machine to. Add a vending machine prefab by right clicking on the 2D area of Radiant > misc > prefab
Go the the misc_models folder, and look for "com_vending_xxx.map" were xxx is which type you want,
but its best to use one that has an opening at the bottom.
Creating the trigger
Next we need the trigger, create a brush surrounding the front of the vending machine and texture it with tools > trigger
Also create a small 8x8x8 brush, the center of this brush is where the bottles will spawn (the origin of the bottles is at the bottom)
to help position the smaller brush add a misc_model by right clicking on the 2D area of Radiant > misc > model and navigate to your raw/xmodel folder
then insert com_bottle1. Also set the angles of the bottle so they lay flat as they would when coming out of the vending machine.
We will be needing the com_bottle1 model again later so dont delete it just yet :P
Unselect everything then select the trigger brush and the small brush, right click in the 2D area of radiant > trigger > (type you want here)
Types of triggers:
- damage - Shoot the trigger to trigger it
- disk - a round trigger, cant change the height
- friendlychain - Used for SP only
- hurt - Hurts the player... dont use this one lol xD
- lookat - Look at the trigger to trigger it
- multiple - Triggered when touched by a player
- once - Triggered only once
- radius - like disk but can change the height
- use - Press the USE button to trigger
- use_touch - Player must be touching the trigger and press the USE button to trigger it
I recommended to use trigger_use_touch or trigger_use
Unselect everything then texture the small brush with tools > origin.
Press N to open the entity box, and type the following in:
Key: hintstring Value: Press^3 [{+activate}] ^7to have a drink
Key: targetname Value: heal
Adding where the impact will come from
Next we need to set where the impact is going to come from to force the bottle out of the vending machine (and also set the angle of the bottle when it spawns). To do this we need to pace a script_origin by right clicking on the 2D area of Radiant > script > origin then a red box should appear. Place this corresponding to where you what the impact to come from.
Now use the com_bottle1 model that you used before when adding the trigger, make sure that the angles are as if it was coming out of the vending machine. Now press N to open the entitys box for the bottle and look at the angles, then select the script_origin and set the same angles for that. Now you can delete the com_bottle1 model.
Make sure nothing is selected by pressing Esc few times, now select the trigger THEN the script_origin and press W.
A red line should appear from the center of the large or smaller trigger brushes connecting to the script_origin.
The .csv files
(ff .csv and sound .csv)
OK, thats the Radiant part done, now for the .csvs
- Go to CoD4\zone_source and look for yourmapname.csv
Open that with notepad and add these lines somewhere (xmodel, lines only requierd if the model is not already used in your map)
xmodel,com_bottle1 xmodel,com_bottle2 xmodel,com_bottle3 xmodel,com_bottle4 sound,yourmapname,,,
- Save and close
- Now go to CoD4\raw\soundaliases, make a new .csv called yourmapname.csv (a .txt renamed to .csv)
Open it with notepad and add the following:
vender,,level/ac_unit_window_loop.wav,0.7,0.7,max,1,1,150,300,auto,streamed,,looping vender_drop,1,yourmapname/vender_drop1.wav,0.7,0.8,max,0.9,1,150,300,auto,,, vender_drop,2,yourmapname/vender_drop2.wav,0.7,0.8,max,0.9,1,150,300,auto,,,
Save and close again
Go to CoD4\raw\sound and make a new folder called yourmapname, in there place the 2 .wav sounds that can be downloaded (link at the bottom)
The Scripts
OK then, now the scripty part
New commands that are added with these scripts are:
set yourmapname_allow_vender "1" set yourmapname_health_wait "10"
yourmapname depends what your map is called, like if your map is mp_funny_bunny then the new commands would be:
set mp_funny_bunny_allow_vender "1" set mp_funny_bunny_health_wait "10"
Add this part somewhere in the main() function of your map .gsc
precache(); // Call the precache function venders = getentarray("heal","targetname"); // Get all the entitys that have "heal" for their "targetname" for(i=0;i<venders.size;i++) venders[i] thread vender();
So it should look something like this:
main() { level.tweakfile = true; setdvar("scr_fog_disable", 0); VisionSetNaked("mp_vending", 0); mapsmp_load::main(); mapsmp_compass::setupMiniMap("compass_map_mp_vending"); ambientPlay("ambient_pipeline"); game["allies"] = "marines"; game["axis"] = "opfor"; game["attackers"] = "axis"; game["defenders"] = "allies"; game["allies_soldiertype"] = "desert"; game["axis_soldiertype"] = "desert"; setdvar("r_specularcolorscale", "1" ); setdvar("r_glowbloomintensity0",".1"); setdvar("r_glowbloomintensity1",".1"); setdvar("r_glowskybleedintensity0",".1"); setdvar("compassmaxrange","2048"); precache(); // Call the precache function venders = getentarray("heal","targetname"); // Get all the entitys that have "heal" for their "targetname" for(i=0;i<venders.size;i++) venders[i] thread vender(); }
Add this code UNDER the main() function
precache() { if(getDvar(getDvar("mapname") + "_allow_vender") == "") setDvar(getDvar("mapname") + "_allow_vender", 1); // This creates the dvar to enable the vending machines if(getDvar(getDvar("mapname") + "_health_wait") == "") setDvar(getDvar("mapname") + "_health_wait", 10); // This creates the dvar to set the time between being able to get health again level.allow_vender = int(getDvar(getDvar("mapname") + "_allow_vender")); level.vender_wait = int(getDvar(getDvar("mapname") + "_health_wait")); for(i=1;i<5;i++) precacheModel("com_bottle" + i); // Precache (load) the com_bottle1, com_bottle2, com_bottle3 and com_bottle4 models level.venderbottles = []; level.venderbottlescurrent = 0; level.venderbottlesmax = 24; // Max bottles in the map at one time, try not to have this too high as it can cause lag and somtimes crash the server } vender() { self.targetname = undefined; dir = getent(self.target,"targetname"); if(isDefined(dir)) { temp = spawnStruct(); temp.origin = dir.origin; temp.angles = dir.angles; // Spawn a struct which doesnt count as an entity, record the script_origin's origin and angles then delete the script_origin dir delete(); dir = temp; } self.target = undefined; randomMessages = []; // List of random messages when player has had a bottle recently, you can have as many of them as you want. randomMessages[0] = "^2When was the last time you saw a fat rat?"; randomMessages[1] = "^1Careful! You'll break it!"; randomMessages[2] = "^3Oh no! There's none left!"; randomMessages[3] = "^4You're hungry ain't ya?"; randomMessages[4] = "^5Woof"; self playLoopSound("vender"); // Make the trigger play a loop sound for(;;) { self waittill("trigger", player); // Wait until its triggered if(player.sessionstate != "playing")// Make sure the player is playing continue; if(!level.allow_vender)// If vending machines are not allowed then say a message { player iPrintlnBold("^2Sorry, fat rats are not allowed on this server"); continue; } if(isDefined(dir))// If the script_origin is placed correctly in the map, then make a bottle pop out { self playSound("vender_drop");// Play the bottle drop sound if(isDefined(level.venderbottles[level.venderbottlescurrent])) level.venderbottles[level.venderbottlescurrent] delete();// If we have gone over the limit for max bottle in the map, delete the oldest one level.venderbottles[level.venderbottlescurrent] = spawn("script_model",self.origin);// Spawn the bottle level.venderbottles[level.venderbottlescurrent].angles = dir.angles; // Set the angles of the bottle level.venderbottles[level.venderbottlescurrent] setModel("com_bottle" + (randomInt(4) + 1)); // Set random bottle model point = dir.origin; origin = level.venderbottles[level.venderbottlescurrent].origin + maps\mp\_utility::vector_Scale(anglestoup(level.venderbottles[level.venderbottlescurrent].angles),4 + randomFloat(1)); velocity = VectorNormalize(origin - point);// Calculate velocity and direction of the impact velocity = maps\mp\_utility::vector_Scale(velocity,10000 + randomInt(5000)); level.venderbottles[level.venderbottlescurrent] physicsLaunch(point, velocity); // Make the bottle fly! level.venderbottlescurrent++; if(level.venderbottlescurrent >= level.venderbottlesmax) level.venderbottlescurrent = 0; } if(isDefined(player.healthwait))// If the player has already used the vending machine then... { player iPrintlnBold(randomMessages[randomInt(randomMessages.size)]); // display one of the rather insulting messages to the player. continue; } player.healthwait = true; if(player.health < player.maxhealth)// If the players health is not at the max { player.health = player.maxhealth;// Set the players health to the max player iPrintlnBold("^2mmm... ^1y^2u^3m^4m^5y^6!");// Say these messages if the player was healed player iPrintlnBold("^1Health Restored!"); } else player iPrintlnBold("^2You already have full health, but ^1y^2u^3m^4m^5y^6! ^2anyway!"); // If the player already has full health then say this message player thread healthwait(); } } healthwait() { self endon("disconnect"); // Kill the thread if the player disconnects wait level.vender_wait; // Wait how long level.vender_wait is self.healthwait = undefined; // Make self.healthwait undefined }
So, with all the code it should look like this:
main() { level.tweakfile = true; setdvar("scr_fog_disable", 0); VisionSetNaked("mp_vending", 0); mapsmp_load::main(); mapsmp_compass::setupMiniMap("compass_map_mp_vending"); ambientPlay("ambient_pipeline"); game["allies"] = "marines"; game["axis"] = "opfor"; game["attackers"] = "axis"; game["defenders"] = "allies"; game["allies_soldiertype"] = "desert"; game["axis_soldiertype"] = "desert"; setdvar("r_specularcolorscale", "1" ); setdvar("r_glowbloomintensity0",".1"); setdvar("r_glowbloomintensity1",".1"); setdvar("r_glowskybleedintensity0",".1"); setdvar("compassmaxrange","2048"); precache(); // Call the precache function venders = getentarray("heal","targetname"); // Get all the entitys that have "heal" for their "targetname" for(i=0;i<venders.size;i++) venders[i] thread vender(); } precache() { if(getDvar(getDvar("mapname") + "_allow_vender") == "") setDvar(getDvar("mapname") + "_allow_vender", 1); // This creates the dvar to enable the vending machines if(getDvar(getDvar("mapname") + "_health_wait") == "") setDvar(getDvar("mapname") + "_health_wait", 10); // This creates the dvar to set the time between being able to get health again level.allow_vender = int(getDvar(getDvar("mapname") + "_allow_vender")); level.vender_wait = int(getDvar(getDvar("mapname") + "_health_wait")); for(i=1;i<5;i++) precacheModel("com_bottle" + i); // Precache (load) the com_bottle1, com_bottle2, com_bottle3 and com_bottle4 models level.venderbottles = []; level.venderbottlescurrent = 0; level.venderbottlesmax = 24; // Max bottles in the map at one time, try not to have this too high as it can cause lag and somtimes crash the server } vender() { self.targetname = undefined; dir = getent(self.target,"targetname"); if(isDefined(dir)) { temp = spawnStruct(); temp.origin = dir.origin; temp.angles = dir.angles; // Spawn a struct which doesnt count as an entity, record the script_origin's origin and angles then delete the script_origin dir delete(); dir = temp; } self.target = undefined; randomMessages = []; // List of random messages when player has had a bottle recently, you can have as many of them as you want. randomMessages[0] = "^2When was the last time you saw a fat rat?"; randomMessages[1] = "^1Careful! You'll break it!"; randomMessages[2] = "^3Oh no! There's none left!"; randomMessages[3] = "^4You're hungry ain't ya?"; randomMessages[4] = "^5Woof"; self playLoopSound("vender"); // Make the trigger play a loop sound for(;;) { self waittill("trigger", player); // Wait until its triggered if(player.sessionstate != "playing")// Make sure the player is playing continue; if(!level.allow_vender)// If vending machines are not allowed then say a message { player iPrintlnBold("^2Sorry, fat rats are not allowed on this server"); continue; } if(isDefined(dir))// If the script_origin is placed correctly in the map, then make a bottle pop out { self playSound("vender_drop");// Play the bottle drop sound if(isDefined(level.venderbottles[level.venderbottlescurrent])) level.venderbottles[level.venderbottlescurrent] delete();// If we have gone over the limit for max bottle in the map, delete the oldest one level.venderbottles[level.venderbottlescurrent] = spawn("script_model",self.origin);// Spawn the bottle level.venderbottles[level.venderbottlescurrent].angles = dir.angles; // Set the angles of the bottle level.venderbottles[level.venderbottlescurrent] setModel("com_bottle" + (randomInt(4) + 1)); // Set random bottle model point = dir.origin; origin = level.venderbottles[level.venderbottlescurrent].origin + maps\mp\_utility::vector_Scale(anglestoup(level.venderbottles[level.venderbottlescurrent].angles),4 + randomFloat(1)); velocity = VectorNormalize(origin - point);// Calculate velocity and direction of the impact velocity = maps\mp\_utility::vector_Scale(velocity,10000 + randomInt(5000)); level.venderbottles[level.venderbottlescurrent] physicsLaunch(point, velocity); // Make the bottle fly! level.venderbottlescurrent++; if(level.venderbottlescurrent >= level.venderbottlesmax) level.venderbottlescurrent = 0; } if(isDefined(player.healthwait))// If the player has already used the vending machine then... { player iPrintlnBold(randomMessages[randomInt(randomMessages.size)]); // display one of the rather insulting messages to the player. continue; } player.healthwait = true; if(player.health < player.maxhealth)// If the players health is not at the max { player.health = player.maxhealth;// Set the players health to the max player iPrintlnBold("^2mmm... ^1y^2u^3m^4m^5y^6!");// Say these messages if the player was healed player iPrintlnBold("^1Health Restored!"); } else player iPrintlnBold("^2You already have full health, but ^1y^2u^3m^4m^5y^6! ^2anyway!"); // If the player already has full health then say this message player thread healthwait(); } } healthwait() { self endon("disconnect"); // Kill the thread if the player disconnects wait level.vender_wait; // Wait how long level.vender_wait is self.healthwait = undefined; // Make self.healthwait undefined }
Prefabs, scripts, sounds and example map with .map can be downloaded here