Not enough ratings
Modifying Stock Maps Using Copy As Script
By Kamek
Easily add your content into stock maps without having to distribute replacement stock maps!
Rate  
Favorite
Favorited
Unfavorite
Introduction
So you've made your own awesome custom content. Great! It might be a new weapon, powerup, or some type of powerful NPC. Now you just need a way to get it in the game somehow.

This guide will show you how to use the "Copy as Script" function to add your content into the game's stock maps using a P2GameMod, causing the game to act like it was there to begin with!

You don't necessarily need any knowledge of UnrealScript to make use of Copy As Script -- it's fairly easy to put together a P2GameMod just by dropping in actors. You don't necessarily even have to have made any custom content at all -- you could just make a mod that adds a bunch of crack pipes to the Dude's tool shed or something (but that wouldn't be very creative!)
Step 1: Modify the stock map
First of all, open the map you want to modify in POSTed.

Immediately save the map under a different name. Preferably you'll want to keep it separate from any other stock-map-modifications you're doing, so you don't get your mods mixed up. For example, if your mod adds a BFG to the game and you want to place one in ToraBora, you could save your map as "ToraBora-BFG".

Anyway, you now have a working copy of the map. Go ahead and find a suitable spot for your custom content, and add it in like you would any other actor. (If you're adding custom actors, you will need to use the Actor Class Browser and find your actor there, then right-click in the world and pick "Add (actor name) Here".)

In this example, I've added three Holy Hand Grenades to Suburbs-3 as an example (don't bother looking, you won't find the actual Holy Hand Grenades there in my Holy Hand Grenade Workshop item!)

Go ahead and save your map, and then exit POSTed for now. We need to do some prep work.
Step 2: Prepare your UnrealScript package
Next, we're going to get your UnrealScript package set up. This part of the tutorial assumes you have no prior knowledge of setting up UnrealScript. If you already know how to make new script packages, you can skim this section for the relevant info (and remember that you can include the P2GameMod in the same package as your weapon, powerup, or other custom content, they don't have to be in separate packages)

Open up the POSTed Local Files (Right click POSted --> Properties --> Local Files --> Browse Local Files), and create a new folder. Call it "MyPackage" for now (you'll be able to give it a more meaningful name later). Open up that new folder, and inside create a new folder called "Classes". Open THAT up, and create a new text document called "MyReplacer.uc" (again, you can give it a better name later, this is what we're going with for now).

You now have an empty script file. Open it up with your favorite text editor, and paste in the following:

///////////////////////////////////////////////////////////////////////////////
// MyReplacer
// My awesome game mod that adds my awesome actors into stock maps
///////////////////////////////////////////////////////////////////////////////
class MyReplacer extends P2GameMod;

///////////////////////////////////////////////////////////////////////////////
// PostTravel
// Called after the player spawns on a new map.
// We're overriding this function to drop in new items based on the map name.
///////////////////////////////////////////////////////////////////////////////
function PostTravel(P2Pawn PlayerPawn)
{
local string CurrentMap;

Super.PostTravel(PlayerPawn);

CurrentMap = P2GameInfo(Level.Game).ParseLevelName(Level.GetLocalURL());

if (CurrentMap ~= "Suburbs-3")
{
// STUB
}
}

///////////////////////////////////////////////////////////////////////////////
// Default properties required by all P2GameMods.
///////////////////////////////////////////////////////////////////////////////
defaultproperties
{
// GroupName - any Game Mods with the same GroupName will be considered incompatible, and only one will be allowed to run.
// Use this if you make mods that are not designed to run alongside each other.
GroupName=""
// FriendlyName - the name of your Game Mod, displayed in the game mod menu.
FriendlyName="My Replacer"
// Description - optional short description of your Game Mod
Description="My awesome replacer that adds my awesome actors that are mine."
}

What we've done here is created a basic P2GameMod, which is one of two ways to get custom content into POSTAL 2 (the other being creating your own maps). Right now, it checks after every level change to see if the map is Suburbs-3. If it is, it does nothing. We'll make it do something later.

Go ahead and save, then back out to your POSTAL2Editor folder. From here, go into System, and create another new file: MyReplacer.int. It's going to look like this:

[Public]
Object=(Name=MyReplacer.MyReplacer,Class=Class,MetaClass=Postal2Game.P2GameMod)

This file tells POSTAL 2's Workshop Browser that we have a P2GameMod located at MyReplacer.MyReplacer. Without it, the game wouldn't know where to find our replacer. Save changes and exit.

We need to do one more thing: compile our script package. Open Postal2.ini with a text editor, and find this section:

[Editor.EditorEngine]
UseSound=True
CacheSizeMegs=32
GridEnabled=True
SnapVertices=False
SnapDistance=10.000000

Scroll down until you see a bunch of lines that start with "EditPackage=", until you find a blank space. At the bottom, put in:

EditPackages=MyReplacer

Save changes and exit. Launch the file called "UCC_Make.bat" to compile your new script package. If you've done everything right, a text window should pop up like this:

Analyzing...
Parsing MyReplacer
Compiling MyReplacer
Success - 0 error(s), 0 warnings
Press any key to continue . . .

If you didn't get this result, double-check all of your steps and try again. Press any key to dismiss the window.

We now have an UnrealScript package! Launch Postal2.exe directly from the Explorer window, and go to the Workshop Browser to verify that "My Replacer" appears in the Available Mods column. Go ahead and exit POSTAL 2, we're ready to move on.
Step 3: Copy as Script
Now that you have a working code package, re-open your map in POSTed. Select all the actors you placed, right-click, and from the "Edit" submenu, choose "Copy as Script". Open up MyReplacer.uc, and where we put in the "// STUB" earlier, overwrite that with the contents of the clipboard. Your script should look similar to this:

///////////////////////////////////////////////////////////////////////////////
// MyReplacer
// My awesome game mod that adds my awesome actors into stock maps
///////////////////////////////////////////////////////////////////////////////
class MyReplacer extends P2GameMod;

///////////////////////////////////////////////////////////////////////////////
// PostTravel
// Called after the player spawns on a new map.
// We're overriding this function to drop in new items based on the map name.
///////////////////////////////////////////////////////////////////////////////
function PostTravel(P2Pawn PlayerPawn)
{
local string CurrentMap;

Super.PostTravel(PlayerPawn);

CurrentMap = P2GameInfo(Level.Game).ParseLevelName(Level.GetLocalURL());

if (CurrentMap ~= "Suburbs-3")
{
// Editor-generated code follows. Paste into script as needed.
AddSpawnProperty("Tag","HolyPickup");
Spawn(class'HolyPickup',,,vect(-422.782318,-12641.483398,-4247.576660),rot(0,0,0),,true);
AddSpawnProperty("Tag","HolyPickup");
Spawn(class'HolyPickup',,,vect(-384.163849,-12640.237305,-4247.576660),rot(0,0,0),,true);
AddSpawnProperty("Tag","HolyPickup");
Spawn(class'HolyPickup',,,vect(-343.578674,-12641.785156,-4247.576660),rot(0,0,0),,true);
// Editor-generated code ends.
}
}

///////////////////////////////////////////////////////////////////////////////
// Default properties required by all P2GameMods.
///////////////////////////////////////////////////////////////////////////////
defaultproperties
{
// GroupName - any Game Mods with the same GroupName will be considered incompatible, and only one will be allowed to run.
// Use this if you make mods that are not designed to run alongside each other.
GroupName=""
// FriendlyName - the name of your Game Mod, displayed in the game mod menu.
FriendlyName="My Replacer"
// Description - optional short description of your Game Mod
Description="My awesome replacer that adds my awesome actors that are mine."
}

All that crap we pasted in simply tells the game "hey, spawn these actors with these properties at the locations I placed them originally". Before we compile and try out our new script, we need to make sure that the actors get spawned into the correct map. Find this line:

if (CurrentMap ~= "Suburbs-3")

Replace "Suburbs-3" with the ORIGINAL filename of the map you modified. Using the example of Tora Bora, your line would look like.

if (CurrentMap ~= "ToraBora")

You can do multiple maps in this manner! Simply copy the "if CurrentMap" block, including the curly braces for as many maps as you need to do. Set the name of the map for each block and then do "Copy as Script" for the items in that map, then paste them in to its respective block.

Once you're all done, save and exit, and return to POSTAL2Editor\System. Delete your existing MyReplacer.u and re-run UCC_Make.bat to recompile.
Step 4: Profit!
Launch POSTAL 2 and test out your new replacer. If everything worked properly, you should be able to visit the modified maps and see your new weapons, pickups, or whatever the hell it was you added, sitting in the map exactly where you placed them. Congratulations! You have successfully modified a stock map. You can now distribute your INT and U file as a Workshop item for others to play with. Make sure to give them a more meaningful name besides "MyReplacer", though.
Caveats (i.e., things you CANNOT do)
While "Copy as Script" is a powerful tool, there are some things it can't do. If you need to do any of the following, consider making a replacement map instead, or working around the issue with UnrealScript.

  • BSP alterations, Volumes, or anything related to Brushes.
  • Non-dynamic lights.
  • NavigationPoints requiring a path rebuild.
  • Pretty much anything that would normally require a rebuild of BSP, lights, or paths.
  • Changing existing actors. If you need to do this, consider something like CheckReplacement.
  • Emitters, Scripted Sequences, or pretty much anything containing sub-objects.
  • Deleting actors instead of adding them. (If you need to destroy a specific actor, you can do so by doing a ForEach of that actor class, then checking each one against the Name of the actor you want to destroy)

There may be other situations that Copy As Script won't work in -- if you find any please let me know in the comments so I can update the guide accordingly.

Good luck, and have fun modifying the world of Paradise to your heart's content!