HowToAddMapsServerStendhal: Difference between revisions

From Arianne
Jump to navigation Jump to search
Content deleted Content added
imported>Chad3f
imported>Hendrik Brummermann
No edit summary
Line 62: Line 62:
Level 0/forest/river_se.tmx -> .../maps/forest/RiverSE_OL0_FishermanNPC.java
Level 0/forest/river_se.tmx -> .../maps/forest/RiverSE_OL0_FishermanNPC.java
Level 0/forest/river_sw.tmx -> .../maps/forest/RiverSW_OL0_CamperNPC.java
Level 0/forest/river_sw.tmx -> .../maps/forest/RiverSW_OL0_CamperNPC.java

::: Please provide some real examples. This looks reall strange but i am not sure whether i understood it correctly. Does this realy mean that all forest are combined ignoring the location (nalwor, orril)? --[[User:Hendrik Brummermann|Hendrik Brummermann]] 05:09, 31 March 2007 (PDT)


Open the file and make sure that it looks like this:
Open the file and make sure that it looks like this:

Revision as of 12:09, 31 March 2007

Of course you have already read:

Ok, and I assume that you can write or at least read Java.

Modify map TMX file

The maps files are just XML files with special tags, open your maps and make sure that you set x,y position of your map on the world. Semos village is right now (500000,500000) so use something near yours to set correctly the map position.

Now you need to create the stend map files. There are two options:

  • Generate it using tiled ( Save as xstend )
  • Run at stendhal folder: ant convertmaps

The later is prefered as it will also update world.tmx graphics.

Modify world.tmx

Now make sure if your map is new that world.tmx shows it by adding a new tileset with your map image. This step is just for your mental wellness. Stendhal don't use world.tmx.

Create a map file

If you are adding a zone for a new major area, create the file data/conf/zones/<area>.xml with the following:

<?xml version="1.0" encoding="UTF-8"?>
<zones>
 <!--
   ** Load zones. Written from left to right and from top to bottom.
   ** Please respect it!
   -->

</zones>

Then edit the file data/conf/zones.xml and add a relavent entry (in alphabetical order for normal areas):

 <zone-group uri="zones/<area>.xml"/>

To enable a zone in the server, edit the file data/conf/zones/<area>.xml and add an entry (in the appropriete level/top-down/left-right order), giving it the zone name and converted map filename to use:

 <zone name="int_myarea_mylocation" file="int_myarea_mylocation.xstend"/>
 <zone name="0_myarea_mylocation" level="0" x="100000" y="200000" file="0_myarea_mylocation.xstend">

In the case of non-interior zones, the level and x/y coordinate should also be included in the <zone> element, as the settings in the tmx file will soon be deprecated. For interior zones, the level xml attribute should not be set (for now).

Most zones can be configured just using this xml file. However, there are currently some things, such as NPC's that need special handling. If you need to do custom zone configuration, create one or more new java source file(s) at src/games/stendhal/server/maps/<area>/<location>/<level>_<entity>.java. The <area>/<location> path would be the same as your .tmx file uses. Ideally this would be one file per independant entity created (so they can be enabled/disabled separately). The level is used as [I/U/O][L/SL]# where I=Inside, U=Underground, O=Outside, L=Level, SL=Sub-Level, and # for the level (or sub-level without the minus) number.

There is a proposed new naming convention:

This replaces the <location> package with a <Location>_ prefix on the java filename, where tmx file underscores are converted to camel case (upper case each first letter instead) for the prefix. As a result, the filename should always contain exactly two underscores. The previous remaining rules still apply.

Some new convention tmx path to java filename examples are:

Level 0/desert/oasis.tmx -> .../maps/desert/Oasis_OL0_NomadNPC.java
interiors/forest/old_cabin.tmx -> .../maps/forest/OldCabin_IL0_HermitNPC.java
Level -1/mountains/abandoned_cave.tmx -> .../maps/mountains/AbandonedCave_USL1_CaveinTrigger.java
Level 0/forest/river_se.tmx -> .../maps/forest/RiverSE_OL0_FishermanNPC.java
Level 0/forest/river_sw.tmx -> .../maps/forest/RiverSW_OL0_CamperNPC.java
Please provide some real examples. This looks reall strange but i am not sure whether i understood it correctly. Does this realy mean that all forest are combined ignoring the location (nalwor, orril)? --Hendrik Brummermann 05:09, 31 March 2007 (PDT)

Open the file and make sure that it looks like this:

package games.stendhal.server.maps.myarea.mylocation;

import java.util.Map;
import games.stendhal.server.StendhalRPZone;
import games.stendhal.server.maps.ZoneConfigurator;

public class IL0_MyEntity implements ZoneConfigurator
{
        /**
         * Configure a zone.
         *
         * @param       zone            The zone to be configured.
         * @param       attributes      Configuration attributes.
         */
        public void configureZone(StendhalRPZone zone, Map<String, String> attributes) {
                // Add/configure entity to "zone", using optional configuration "attributes"
        }
}

For each custom configuration code class, add appropriete "<configurator>" entries in your "<zone>" element, using the fully qualified package/class name of your java classes:

 <zone name="int_myarea_mylocation" file="int_myarea_mylocation.xstend">
  <configurator class-name="games.stendhal.server.maps.myarea.mylocation.IL0_MyEntity"/>
 </zone>

Now once it is added, test the result by starting server.

Populating zones

Now open again the MyEntity.java file and let's start adding code to configureZone(), or a method called by it. Most usual things we are going to add to a zone are NPC, and special items.

Adding Items

See How to add items to Stendhal and How to know graphics specifications

Adding Portals

A portal is a door to another place. It can be used to go up and down stairs, or to teleport player to other places or simply to enter a building. Whenever you encounter something that engine challenges you about how to do ( for example cross under a brigde or pass under a castle door ) you can solve it using portals.

There are several types of portals:

  • Portal
  • One way portal
  • Stairs portals
  • House Door portals.

A portal is just the generic portal. It works for almost everything you can imagine.

Portals are created by adding a entries to your zone in zones.xml. For example creating a portal to an internal building entrance might look like:

 <zone name="int_myarea_mylocation" file="int_myarea_mylocation.xstend">
    <portal x="10" y="15" ref="entrance">
     <destination zone="0_myarea_city" ref="mylocation_entrance"/>
    </portal>
 </zone>

 <zone name="0_myarea_city" file="0_myarea_city.xstend">
    <portal x="10" y="15" ref="mylocation_entrance">
     <destination zone="int_myarea_location" ref="entrance"/>
    </portal>
 </zone>

The ref attribute of a portal should be a name unique to the zone it is in (and meaningful). This value has a corresponding reference via the <destination> ref name. You are responsible for correctly assigning the ref names of each portal.

A one way portal is a portal that only exists as endpoint, so none can use the portal to move back to the origin. For one way portals, there is no <destination> sub-element, as they don't go anywhere. Also, you need to provide a non-default implementation:

  <portal x="11" y="44" ref="my_exit">
   <implementation class-name="games.stendhal.server.entity.portal.OneWayPortalDestination"/>
  </portal>

The House door portal is a special type of portal that automatically creates all the portals and areas needed to add a house to that zone with its entrance on point where the portal is.

Finally the stairs portals also automate the creation of stairs between two areas. It is very important that the portals ( both ends ) are exactly on the same position but on different levels. Position means absolute position. Also, due to current implementation, be careful not to place omni-directional stair portals at the same exact location between adjacent levels if they're not meant to be linked, as they might inadvertantly be linked. Directional stairs are safer and only link with the level they go toward.

Adding NPC

Usually we add NPC to make world more alive and to use them in Quests. It is because of that reason, that is so important that you add NPC on the zone they are.


npcs.add("name",new SpeakerNPC()...) creates a new NPC and adds it to a global list so next time you need to get the NPC for participating in a quest, or if you want to teleportto it, you can call it by its name using npcs.get(name)

NPC npc=npcs.add("name",new SpeakerNPC()
      {
    
      });

Notice that in this case, the name is especified first in NPC npc=npcs.add("name",...


In other words, new SpeakerNPC() creates just a new NPC of the class SpeakerNPC but with npcs.add("name",new SpeakerNPC()...) you are in fact extending SpeakerNPC to add new functionality.


In this case, let's suppose you plan on using our NPC later in a quest, so use something like:

    SpeakerNPC npc=npcs.add("Ilisa",new SpeakerNPC()
      {
      protected void createPath()
        {
        List<Path.Node> nodes=new LinkedList<Path.Node>();
        nodes.add(new Path.Node(9,5));
        nodes.add(new Path.Node(14,5));
        setPath(nodes,true);
        }

      protected void createDialog()
        {
        Behaviours.addGreeting(this);
        Behaviours.addJob(this, "I have healing abilities and I heal wounded players. I also sell potions and antidotes.");
        Behaviours.addHelp(this, "Ask me to #heal you and I will help you or ask me #offer and I will show my shop's stuff.");
        Behaviours.addSeller(this, new Behaviours.SellerBehaviour(shops.get("healing")));
        Behaviours.addHealer(this, 0);
        Behaviours.addGoodbye(this);
        }
      });
      
    zone.assignRPObjectID(npc);
    npc.put("class","welcomernpc");
    npc.set(9,5);
    npc.initHP(100);
    zone.add(npc);    

Use npcs.add() as this way the NPC is added to a list of NPC from where you can later obtain it for adding more dialogues for quests. Make sure the name you give to your NPC is unique.

Just after that it is a good idea to create a path that the NPC will follow on that area. And then create a dialog. Dialogs and such are explained in Quest sections.

Now simply assign an id to the npc, set its outfit either by:

  • setting its class to a PNG image that exists at data/sprites/npc
  • setting its outfit with setOutfit method.

See How to know player's outfits specifications

Finally set its initial position and its HP. Don't worry for your NPC. It can't be attacked nor killed.

Once that is done add the NPC to zone using zone.add() method.

Congrats you have populated your new zone.


Back to Stendhal main Wiki