Map of the Whenever

Meltdown (beta2)
Meltdown (beta2) by Chris
Rated 8.5

Latest Articles

Want to write your own article? Please use the Submit Article page.


Latest Maps

Made an awesome map that you want to share with the rest of the world? Submit your own map to etqwmapping.com!

 

How to create a single objective map

November 24, 2007, by Tapir.

This tutorial should let you have a bare bones map with a GDF construction objective. The objective will be to construct a wall. Completing it will end the map.

Important Notes:


Firstly, create the following folders:
<savepath>/base/mapinfo
<savepath>/base/script/maps/<yourmap>
<savepath>/base/maps/<yourmap>


Secondly, create the following files (you can use Notepad but make sure you set the file extension correctly):
<savepath>/base/pakmeta.conf
<savepath>/base/mapinfo/<yourmap>.md
<savepath>/base/script/maps/<yourmap>.script


In the pakmeta.conf you need to paste the following:

// Map Data
mapMetaData maps/<yourmap>/<yourmap>
"pretty_name" "<whateveryourwant>"
"mapinfo" "<yourmap>"
"massive_zone_name" "<yourmap>"
"server_shot_thumb" "levelshots/thumbs/area22.tga"
"show_in_browser" "1"

In the <yourmap>.md file paste the following:

#include <mapinfo/mapinfo.include>

mapInfoDef <yourmap> {

    _default_mapinfo( "<yourmap>" )

    data {
        "mapLocation" "maps/<yourmap>/location"
        "script_entrypoint" "<yourmap>_MapScript"
        "mapBriefing" "maps/<yourmap>/briefing"
        "campaignDescription" "maps/<yourmap>/campaign"
        "numObjectives" "4"
        "mtr_serverShot" "levelshots/<yourmap>"
        "mtr_backdrop" "levelshots/campaigns/northamerica"
        "mapPosition" "311 140"
        "snd_music" "sounds/music/load1"
        "strogg_endgame_pause" "6.0"
        "gdf_endgame_pause" "5.0"
    }
}

Find where you installed the SDK and copy the file SDK 1.2 Beta/base/script/main.script into your <savepath>/base/script/ location. Edit it, scroll down 3/4 of the way until you see the following:

    // maps
    #include "script/maps/base.script"
    #include "script/maps/default.script"
    #include "script/maps/ark.script"
    ...

And add the following file at the end of this listing:

    // custom maps
    #include "script/maps/<yourmap>.script"

Okay, time to build the map. Start the SDK Launcher, and set editWorld to begin. Create an empty caulk box as shown in this tutorial. I suggest a size of 2048 x 2048 x 2048. Press Esc to deselect everything.

Now repeat it with a box with a size of 512 x 512 x 512 and add an atmosphere as shown here. Basically, you'll have two areas in the map, the outside which is the big box and the inside which is the smaller box. The box face which you applied the "outside_portal" texture acts as a gateway between the two areas. You'll now have visible explosions, etc. Press Esc to deselect everything.

Now place an "info_team_spawn_gdf" somewhere inside the big box. This is where the GDF will spawn. Now let's add a simple construct objective for the GDF to build. Press Esc to deselect everything.

Firstly add a "constructible_materials_gdf" entity onto your big box somewhere. With it selected, press N which will take you into the Properties Editor. Change the name to "construct_materials" and add the following key/value pairs:

    constructed wall
    construction wall_temp
    objective_index 0
    object_name maps/generic/bridge
    task_name maps/valley/task_bridge

You can also add sounds text and whatnot but for this bare-bones map this will be sufficient. Press Esc to deselect everything.

Now add another brush, say a 256 x 16 x 128 wall-like brush. With it selected, right click and select "constructible > constructible_base_etqwmap" and press N. Change its name to "wall" so that will be referenced by the constructions materials entity we edited previously. Press Esc to deselect everything.

Repeat the above but now name it "wall_temp".

In the Properties Editor select the "worldspawn" entity and add the following key/value pair:

    script_construct_entity construct_materials

Now save the map to <savepath>/base/maps/<yourmap>/<yourmap>.world and then compile it (Compile > Normal). Let's now edit our <savepath>/base/script/maps/<yourmap>.script file we had created at the start. I'm going to break this into sections so they're easier to follow but if you're not really that interested in the why just paste everything in order and find/replace <yourmap> there.

    #define OBJECTIVE_<yourmap_inCAPS>_BUILD_WALL 0

This will define the first objective (numbered 0) and assign it a name so it can be easily retrieved without having to know whether its the first or last objective. In our case we only have one objective so this is mainly for future maps.

object mapObject_<yourmap> : mapObject_Default {
    void InitObjectives();
    void CompleteObjective( float index, entity p );
    void StartFirstObjective();
    void OnWallBuilt();
    void OnTimeLimitHit();

    handle GetObjectiveMessage( float index );

    float mainObjectiveIndex;
    entity wallConstruction;
}

This piece of code lets the game know that your map has a couple of properties and custom methods that you're going to be using. Of interest here are the "OnWallBuilt()" and wallConstruction. The first is an "event" which will be fired once the construction objective (our wall) is built. The later is a temporary entity that will reference our map construction entity.

mapObject_Base <yourmap>_MapScript() {
    return new mapObject_<yourmap>;
}

This block is used internally to generate a new map script.

void mapObject_<yourmap>::InitObjectives() {
    gameRules.setWinningTeam( stroggTeam );
    gdfTeam.SetRespawnWait( 20 );
    stroggTeam.SetRespawnWait( 20 );
    CreateRespawnTimeThread( gdfTeam );

    wallConstruction = worldspawn.getEntityKey( "script_construct_entity" );

    mainObjectiveIndex = OBJECTIVE_<yourmap_inCAPS>_BUILD_WALL;

    thread StartFirstObjective();

    objManager.setNextObjective( gdfTeam, mainObjectiveIndex );
    objManager.setNextObjective( stroggTeam, mainObjectiveIndex );
}

This piece of code initialises the objective system. The first four lines tell the game which team is defending, and sets up the spawn timers. Now this is important: the "wallConstruction" variable that we declared right at the top of the script will be assigned the value that you gave the key/value pair of the worldspawn. So when the game runs "wallConstruction" will become the same as the "constructible_materials_gdf" entity we placed on the map.

Then the script fetches the objective number and sets it as the next objective for both teams. Meanwhile it also starts the first objective. Which is what the next block shows:

void mapObject_<yourmap>::StartFirstObjective() {
    sys.wait( 5.f );

    objManager.SetObjectiveEntity( wallConstruction, mainObjectiveIndex );

    CreateInitialTimedMission( wallConstruction );
    wallConstruction.vCreateMission();
    wallConstruction.vStartObjective();
}

Firstly the game will wait a bit and then set our wallConstruction entity as the first objective and say it has an index of 0. It will create the first mission (those missions on the top left of the screen), etc.

void mapObject_<yourmap>::CompleteObjective( float index, entity p ) {
      if ( index == OBJECTIVE_<yourmap_inCAPS>_BUILD_WALL ) {
            OnWallBuilt();
      }
}

handle mapObject_<yourmap>::GetObjectiveMessage( float index ) {
      if ( index == OBJECTIVE_<yourmap_inCAPS>_BUILD_WALL ) {
            return sys.localizeString( "maps/valley/obj_bridge" );
      }

      return g_locStr_BadObjective;
}

The first block will fire off the "OnWallBuilt" event we declared earlier, the second is just for printing some text so don't worry about that one.

void mapObject_<yourmap>::OnWallBuilt() {
    StopTimedMission();
    wallConstruction.vCompleteMission();

    wallConstruction.vFinishObjective();

    gameRules.setWinningTeam( gdfTeam );
    gameRules.endGame();

    wallConstruction.vCompleteMission();
}

Okay, this is the event that's fired when the wall is constructed. This is our only objective so after this we complete missions, objectives, set which team won the map and end the game. But what if the GDF can't construct this in the time limit?

void mapObject_<yourmap>::OnTimeLimitHit() {
    FinishTimedMission();
    objManager.SetObjectiveEntity( $null_entity, -1 );
}

Since in this map the Strogg are defending they automatically win so no need to set the winning team (as we had already set it near the top). The other lines simply clean up the objectives a bit (setting them to nothing).

With the SDK Launcher, start the game, bring down the console and type: "devmap <yourmap>/<yourmap>" and press Enter.

Done.

You can download everything from this tutorial here (130Kb). Uncompress to your <savepath>/base and use the SDK Engine to play it with "devmap tut1/tut1".


Comments

There is 1 comment for this article.

#1 by Tapir on November 24, 2007

This article was written by Mordenkainen on the ETQW Community Forums. It has been posted here with his permission. Thanks Mordenkainen!

 

You must be logged in to post comments.