Zones v2

Preamble
You will note that the examples below dont sound that fun. I'd like to think its because my creative power went into building a good system, and now there is little left to put on examples. But I'm sure you will find interesting ways to use the mechanisms in here. My goal with this was to be able to have zones that could have different effect depending on who would use them. For example, having a fortress that team Blue could conquer, but only 2 of the players of team Red could actually defend. The other Red could still circle it and block the enemy, but they could not lower its value actively. Everything described here works. There are still glitches small and not so small. The code is in my private branch, but feel free to grab a local copy if you want to play with it.

The format is anything but closed. I'd like to hear your opinion on it too (yes it is a PITA to write, but if you have a constructive remark about that, I'd like to know it)

-ph

Most of this is from a forum post by philippeqc. I reworded some stuff and formatted a bit for the wiki. Some stuff might have gotten lost or reworded wrongly so cross refrence with the post if the wording gets hazy and/or just to double check @ http://forums.armagetronad.net/viewtopic.php?p=77491#77491. Some stuff might be in the wrong place. --Your mom 11:42, 30 July 2006 (CDT)

Zone element
Individual zones may have a name. Entering a name is optional, and re-using a name will be considered to mean "add/override with the following information". Dont rely on this behavior for anything, in other words Dont re-use the same name. All zones need a shape defined. At the moment only one shape exists, the ShapeCircle. More shapes are planned in the future and are ToDo

Ex:      

Rules and EffectGroups
A zone can have up to 4 different "rules" (need better name ToDo). Enter, Inside, Leave, Outside. It classifies when the held elements should be inspected. Inside each of the "rules", one can define EffectGroups. EffectGroup(s) are the fundamental building blocks of this new system. It associate owners with consequences. Note that ownership is part of effectGroup(s), NOT the zone. So a zone may have multiple effectGroup(s), each with unique or interlapping owners. There are 2 types of owners: owner (individuals) and ownerTeam (every member of a team). It is possible to define 0,1 or many for each items.

''HACK: ATM, only owner is supported, and it must be an exact match with a player's name to associated the effect. The real solution will translate the labels used to players based on some other logic depending on "game type". This is to be defined later.''

''HACK: It should be possible to associate individual with teams in some part of the map. In this text, I will user lowercase color name + number for individual, and uppercase color name for teams. So the individual red1, red7 and red90210 should be considered as players of the team RED. I will also allow myself to insert _description_ in names to help the reader when appropriate.''

Ex:   ...    ...   ...     ... </EffectGroup> </Leave> </Zone>

User element
Inside the EffectGroup, elements User are set. This element offers different readily made rules to determine if a player in the "rule" condition for the zone, is allowed to be considered a user. This is decided based from the following information: owner, ownerTeam and the player matching the rule. Two other conditions can be set for a player to be considered a valid user: positive and marked. These element are of type Triad. The possible values are true, false and ignore. We will come back to these later. If the current player is found to be valid, the processing will continue to the child elements. Otherwise, nothing happens. A valid user will be called triggerer from now on.

The following users are currently implemented:
 * all: Anybody can be considered a valid user,
 * owner: only a player direcly in the owner list can be considered a valid user,
 * ownerTeam: only a player member of a team mentionned in the ownerTeam list can be considered a valid user,
 * allButOwner only a player NOT mentioned in the owner list can be considered a valid user,
 * allButTeamOwner only a player NOT member of a team mentioned in the ownerTeam list can be considered a valid user, (TO COME, NOT IMPLEMENTED YET)
 * anotherTeammate only a player in the same team as one of the individual owner can be considered a valid user (TO COME, NOT IMPLEMENTED YET)

Ex:  <User user="all" > ...  </User> <User user="allButOwner" > ...  </User> </EffectGroup>  <User user="owner" > ...  </User> <User user="ownerTeam" > ...  </User> </EffectGroup>

Inside a User element, it is possible to make use of 3 different elements. Target, ZoneInfluence and MonitorInfluence.

Target
The Target element will take the information of the valid user, and calculate who will receive the effect of the zone. Depending on the described target rule to use and the state of the game, the calculated target can be from no players to everybody in game.

The currently implemented target rules are :

on the forum.
 * self : the triggerer himself
 * teammate : a randomly selected teammate of the triggerer
 * team : all the member of the team of the triggerer
 * all : everybody in the game
 * allButSelf : everybody in the game BUT the triggerer
 * another : a randomly selected player that is not the triggerer
 * ownerTeamTeammate : a randomly selected player member of one of the teams mentioned in the teamOwner list.
 * owner : all the players owning the effectGroup
 * ownerteam : all the players member of the team owning the effectGroup
 * ownerteamteammate : a single player member from a owning team
 * anydead : any single dead player
 * alldead : all the dead players
 * singledeadowner : one of the owners that is dead
 * anotherteammatedead : a single player member of the team of the triggerer that is dead
 * anothernotteammatedead : a single player that is not member of the team of the triggerer and that is dead
 * Much more are detailed in a document named zones.txt hidden somewhere

Once the targets are selected, they all are applied all the effects described under the Target element.

Nota: In a User element, it is possible to user any amount of Target, ZoneInfluence and MonitorInfluence.

Ex: <User user="ownerTeam" > <Target target="self"> ...  </Target> <Target target="another"> ...  </Target> </User>

Effect
The Effect element hold specific effects. The attribute count can limit the number of times a specific effect can be used. By default, the count is unlimited.

valid effect currently implemented are:
 * win : win the round
 * death : kill the target(s)
 * point : give points to the target(s)
 * spawnplayer : Respawns target(s)
 * brakerecharge : Refills target(s) cycle brake
 * rubberrecharge : Refills target(s) cycle rubber
 * acceleration: Accelerate the target(s) by this rate,
 * teleport: Instantly move target(s) to a random location (planned)
 * setting : has 2 attributes ; settingName & settingValue

new attribute for all effects: description Acceleration uses the rate stored in the attribute named value.

When the effect is triggered, the message is displayed on the console. Somehow I'm not able to do the "parsing" similar to when points are given (player x received y points because he is sooo leet). That should come.

When point is use, an attribute score will mention the amount of point to give.

<Target target="self"> <Effect effect="point" score="3" count="2"> ...  </Effect> <Effect ...> ... </Effect> </Target>

ex: <Effect effect="acceleration" value="20.0" /> Would make the target accelerate drastically.

<Effect effect="setting" settingName="cycle_speed" settingValue="100" /> Would change the base speed for all the players.

A reminder about manipulating settings from the map: This mechanism is quite raw and powerful. Use it with care. Not everything is manipulable during a round, nor make sense to manipulate. Reap the benefit but respect the limitations. Consider yourself warned.

ZoneInfluence
Inside the User element, the element ZoneInfluence and MonitorInfluence are use to affect back game element. ZoneInfluence allows to affect a zone in play. The name attribute must match exactly a zone's name elsewhere in the map.

The possible thing to affect on a zone are:
 * Rotation with attribute rotationAngle and rotationSpeed
 * Radius with attribute radius
 * Point with attribute x and y

Ex: <User user="all"> <ZoneInfluence name="redFortress"> <Rotation rotationAngle="0.3" rotationSpeed="0.5" /> <Radius radius="50"/> <Point x="100" y="100" /> </ZoneInfluence> <ZoneInfluence name="blueFortress"> <Radius radius="-1" /> </ZoneInfluence> </User>

MonitorInfluence
Monitors are simple variables that can be affected by interaction with different zones. The old "fortress" zone is to be considered as a zone where being inside slowly influence its monitor. Monitors are to be inserted in the map at the same level as Zone. Monitor have a name that is used to refer to from the MonitorInfluence, a initial value, and a drift, that slowly move the value, low and high, which clamp the monitor's value between their owns.

<Field> ... <Monitor name="monitorFortressRed" init="0.2" drift="-0.1" low="0.0" high="1.0"> ...  </Monitor> ... </Field>

The Monitor has different rules that can be used to inspect and react on its value. They are OnOver, OnUnder, InRange and OutsideRange. Any amount of rules can be used in a monitor.


 * OnOver has an attribute named value and will be used when the monitor's value exceed it,
 * OnUnder has an attribute named value and will be used when the monitor's value is under it,
 * InRange has attributes low and high and will be used when the monitor's value fall between both
 * OutRange has attributes low and high and will be used when the monitor's value is not falling between both

The monitors' rules are similar to the zone's rule in that they hold EffectGroups that are inspected when the rule conditions are met.

What differs a Monitor from a zone regarding to EffectGroup is who are considered players to be inspected as users. Anyone who contributed to a monitor during a game time step is registered, along with if the contribution was positive (conquering) or negative (defending), and if they where marked. This information is passed along up to the User element. There it can be used on additional tests to determine a valid user.

<Monitor name="monitorFortressRed" init="0.2" drift="-0.1" low="0.0" high="1.0"> <OnOver value="1.0">  <User user="..." positive="true" marked="ignore"> ...      </User> <User ...> ...     </User> </EffectGroup> </OnOver> </Monitor>

User
The User element always have these attributes, but outside of an EffectGroup from a Monitor, this is always ignored.

MonitorInfluence element is the one where one describe how to affect a monitor. It has an attribute name to point to the monitor to influence. It has a marked attribute which is a Triad, ie: allows for the value true, false or ignore. Players using this MonitorInfluence will carry this mark into their contribution to the monitor.

There are 3 ways to influence the value of a monitor:
 * 1 the attribute influenceSlide will affect the monitor's value in a fashion proportional to the time passed in the zone. This is how the classical fortress operates. This is the same as saying influenceSlide * duration of the current game time step.
 * 2 the attribute influenceAdd will affect the monitor's value by this amount. This is NOT affected by time.
 * 3 the attribute influenceSet will set the monitor's value immediatly to this value.

These can of course be used simulteanously. It is important here that attributes that are not desired should not be defined, rather than defined at a default value.

Ex: <User ...> ... <MonitorInfluence name="monitorFortressRed" marked="true" influenceSlide="0.5"/> <MonitorInfluence name="monitorFortressGreen" marked="true" influenceAdd="2"/> <MonitorInfluence name="monitorFortressBlue" influenceSet="0.0" /> </User>

Quiz
Respond on the forums after reading through this entire page with any ideas or questions of your own.(Optional)

1 Are you able to express some new ideas with it?

2 Do you see items that could be added, either now or as a later version that could improve its value?

3 Anything else?

-ph

Examples
An example might help you get through the mess of the description

Its blue vs red Each team has zones in opposing corners which are interconnected. As they get conquered, they jump toward the center.

For your convenience: MAP_FILE philippeqc/zone/DoubleZoneJumping-1.aamap.xml

Code: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE Resource SYSTEM "map-0.3.1-a.dtd"> <Resource type="aamap" name="DoubleZoneJumping" version="1" author="philippeqc" category="zone">

<Map version="2"> <World> <Field> <Spawn x="50"  y="245"  xdir="1"  ydir="0"  /> <Spawn x="450"  y="255"  xdir="-1"  ydir="0"  />

<Wall> <Point x="0"  y="0"  /> <Point x="0"  y="500"  /> <Point x="500"  y="500"  /> <Point x="500"  y="0"  /> <Point x="0"  y="0"  /> </Wall> <Zone name="zRed1"> <ShapeCircle radius="49" red="1.0" green="0.1" blue="0.1"> <Point x="50" y="50"/> </ShapeCircle> <Inside>  <User user="owner"> <MonitorInfluence name="mRed" influenceSlide="-0.25" marked="true"/> </User> </EffectGroup>  <User user="owner"> <MonitorInfluence name="mRed" influenceSlide="0.5" marked="true"/> </User> </EffectGroup> </Inside> </Zone>

<Zone name="zRed2"> <ShapeCircle radius="49" red="1.0" green="0.1" blue="0.1"> <Point x="450" y="450"/> </ShapeCircle> <Inside>  <User user="owner"> <MonitorInfluence name="mRed" influenceSlide="-0.25" marked="true"/> </User> </EffectGroup>  <User user="owner"> <MonitorInfluence name="mRed" influenceSlide="0.5" marked="true"/> </User> </EffectGroup> </Inside> </Zone>

<Monitor name="mRed" init="0.0" drift="-0.1" > <InRange low="0.0" high="0.30">  <User user="all"> <ZoneInfluence name="zRed1"> <Point x="100" y="100"/> <Radius radius="49"/> </ZoneInfluence> <ZoneInfluence name="zRed2"> <Point x="400" y="400"/> <Radius radius="49"/> </ZoneInfluence> </User> </EffectGroup> </InRange> <InRange low="0.4" high="0.60">  <User user="all"> <ZoneInfluence name="zRed1"> <Point x="150" y="150"/> <Radius radius="49"/> </ZoneInfluence> <ZoneInfluence name="zRed2"> <Point x="350" y="350"/> <Radius radius="49"/> </ZoneInfluence> </User> </EffectGroup> </InRange> <InRange low="0.7" high="1.0">  <User user="all"> <ZoneInfluence name="zRed1"> <Point x="200" y="200"/> <Radius radius="49"/> </ZoneInfluence> <ZoneInfluence name="zRed2"> <Point x="300" y="300"/> <Radius radius="49"/> </ZoneInfluence> </User> </EffectGroup> </InRange> <OnOver value="1">  <User user="owner"> <Target target="self"> <Effect effect="point" count="2" score="7"/> </Target> <ZoneInfluence name="zRed1"> <Radius radius="-1" /> </ZoneInfluence> <ZoneInfluence name="zRed2"> <Radius radius="-1" /> </ZoneInfluence> </User> </EffectGroup> </OnOver> </Monitor>

<Zone name="zBlue1"> <ShapeCircle radius="49" red="0.10" green="0.10" blue="1.0"> <Point x="50" y="450"/> </ShapeCircle> <Inside>  <User user="owner"> <MonitorInfluence name="mBlue" influenceSlide="0.3" marked="true"/> </User> </EffectGroup>  <User user="owner"> <MonitorInfluence name="mBlue" influenceSlide="-0.3" marked="true"/> </User> </EffectGroup> </Inside> </Zone>

<Zone name="zBlue2"> <ShapeCircle radius="49" red="0.10" green="0.10" blue="1.0"> <Point x="450" y="50"/> </ShapeCircle> <Inside>  <User user="owner"> <MonitorInfluence name="mBlue" influenceSlide="0.3" marked="true"/> </User> </EffectGroup>  <User user="owner"> <MonitorInfluence name="mBlue" influenceSlide="-0.3" marked="true"/> </User> </EffectGroup> </Inside> </Zone>

<Monitor name="mBlue" init="0.0" drift="-0.1" > <InRange low="0.0" high="0.30"> <EffectGroup owners="" teamOwners=""> <User user="all"> <ZoneInfluence name="zBlue1"> <Point x="100" y="400"/> <Radius radius="49"/> </ZoneInfluence> <ZoneInfluence name="zBlue2"> <Point x="400" y="100"/> <Radius radius="49"/> </ZoneInfluence> </User> </EffectGroup> </InRange> <InRange low="0.4" high="0.60"> <EffectGroup owners="" teamOwners=""> <User user="all"> <ZoneInfluence name="zBlue1"> <Point x="150" y="350"/> <Radius radius="49"/> </ZoneInfluence> <ZoneInfluence name="zBlue2"> <Point x="350" y="150"/> <Radius radius="49"/> </ZoneInfluence> </User> </EffectGroup> </InRange> <InRange low="0.7" high="1.0"> <EffectGroup owners="" teamOwners=""> <User user="all"> <ZoneInfluence name="zBlue1"> <Point x="200" y="300"/> <Radius radius="49"/> </ZoneInfluence> <ZoneInfluence name="zBlue2"> <Point x="300" y="200"/> <Radius radius="49"/> </ZoneInfluence> </User> </EffectGroup> </InRange> <OnOver value="1"> <EffectGroup owners="cerise,mauve,rust,sangria" teamOwners=""> <User user="owner"> <Target target="self"> <Effect effect="point" count="2" score="7"/> </Target> <ZoneInfluence name="zBlue1"> <Radius radius="-1" /> </ZoneInfluence> <ZoneInfluence name="zBlue2"> <Radius radius="-1" /> </ZoneInfluence> </User> </EffectGroup> </OnOver> </Monitor>

</Field> </World> </Map> </Resource>

Ex: Code:

<Zone name="redFortress"> <ShapeCircle radius="29" red="0.988" green="0.059" blue="0.753"/> <Point x="50" y="50"/> </ShapeCircle> ... </Zone>

is now

Code: <Zone name="redFortress"> <ShapeCircle radius="29" > <Color red="0.988" green="0.059" blue="0.753" alpha="0.0"/> <Point x="50" y="50"/> </ShapeCircle> ... </Zone>

Also added Color as a child of ZoneInfluence: Code: <ZoneInfluence name="blueFortress"> <Radius radius="-1" /> <Color red="0.988" green="0.059" blue="0.753" alpha="0.0"/> </ZoneInfluence>

This map has 4 zones that activate one another. Only one should be present, and when not there, they are put outside of the arena. They are activated in a crossed fashion.

Code: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE Resource SYSTEM "map.dtd"> <Resource type="aamap" name="zone" version="d" author="philippeqc" category="">

<Map version="2"> <World> <Field> <Spawn x="50"  y="245"  xdir="1"  ydir="0"  /> <Spawn x="450"  y="255"  xdir="-1"  ydir="0"  />

<Wall> <Point x="0"  y="0"  /> <Point x="0"  y="500"  /> <Point x="500"  y="500"  /> <Point x="500"  y="0"  /> <Point x="0"  y="0"  /> </Wall>

<Zone name="SW"> <ShapeCircle radius="29" > <Point x="50" y="50"/> <Color red="0.988" green="0.059" blue="0.753"> </ShapeCircle> <Enter> <EffectGroup owners="" teamOwners=""> <User user="all"> <Target target="self"> <Effect effect="point" score="2" /> </Target> <ZoneInfluence name="SW"> <Point x="-150" y="-150"/> <Radius radius="29"/> </ZoneInfluence> <ZoneInfluence name="NE"> <Point x="450" y="450"/> <Radius radius="29"/> </ZoneInfluence> </User> </EffectGroup> </Enter> </Zone>

<Zone name="NE"> <ShapeCircle radius="29"> <Point x="-150" y="-150"/> <Color red="0.988" green="0.059" blue="0.753"> </ShapeCircle> <Enter> <EffectGroup owners="" teamOwners=""> <User user="all"> <Target target="self"> <Effect effect="point" score="2" /> </Target> <ZoneInfluence name="NE"> <Point x="-150" y="-150"/> <Radius radius="29"/> </ZoneInfluence> <ZoneInfluence name="NW"> <Point x="50" y="450"/> <Radius radius="29"/> </ZoneInfluence> </User> </EffectGroup> </Enter> </Zone>

<Zone name="NW"> <ShapeCircle radius="29"> <Point x="-150" y="-150"/> <Color red="0.988" green="0.059" blue="0.753"> </ShapeCircle> <Enter> <EffectGroup owners="" teamOwners=""> <User user="all"> <Target target="self"> <Effect effect="point" score="2" /> </Target> <ZoneInfluence name="NW"> <Point x="-150" y="-150"/> <Radius radius="29"/> </ZoneInfluence> <ZoneInfluence name="SE"> <Point x="450" y="50"/> <Radius radius="29"/> </ZoneInfluence> </User> </EffectGroup> </Enter> </Zone>

<Zone name="SE"> <ShapeCircle radius="29"> <Point x="-150" y="-150"/> <Color red="0.988" green="0.059" blue="0.753"> </ShapeCircle> <Enter> <EffectGroup owners="" teamOwners=""> <User user="all"> <Target target="self"> <Effect effect="point" score="2" /> </Target> <ZoneInfluence name="SE"> <Point x="-150" y="-150"/> <Radius radius="29"/> </ZoneInfluence> <ZoneInfluence name="SW"> <Point x="50" y="50"/> <Radius radius="29"/> </ZoneInfluence> </User> </EffectGroup> </Enter> </Zone> </Field> </World> </Map> </Resource>

Its a really crude idea, that has been retaken in a much better way by wrt. But it show some things that can be done (influencing individual zones, and using ZoneInfluence from one zone to affect another).

Targets have a count: Code: The target has an attribute count that will limit the number of time it is called. Not having the attribute or setting it to -1 means infinite.

-ph