;
;  Message Parser Definition for PCC2
;
;  WARNING AHEAD: The syntax is not yet set in stone, and I will probably change a
;  bit here and there. In particular, we need a way to generate multiple object
;  types from a single template (especially markers), and I'd like to make some
;  match tasks a little less verbose.
;
;  Each section has the form
;    objectType,nameOfTemplate
;      request=param
;      request=param
;  The objectType is the type of information this message produces, one of
;    Alliance (since 1.99.23)
;    Base
;    Circle (since 2.41)
;    Configuration
;    Explosion
;    ExtraMinefield (since 2.41)
;    ExtraPlanet (since 2.41)
;    ExtraShip (since 2.41)
;    IonStorm
;    Line (since 2.41)
;    Marker (since 2.41)
;    Minefield
;    Planet
;    PlayerScore
;    Rectangle (since 2.41)
;    Ship
;    Ufo (since 2.41)
;    Wormhole (since 2.40.9)
;  The nameOfTemplate can contain a brief identification of the message; it is used
;  in error messages. ExtraShip etc. operate like Ship etc. but do not associate
;  the message with the object.
;
;  The requests describe how to identify the message and extract values.
;    kind = k           match if "kind" character is k ('k' in heading "(-k9123)")
;    subid = n          match if "sub-id" character is n ('9' in heading "(-k9123)")
;    check = [pos,]str  check for presence of a string, fail template if not found
;    fail = [pos,]str   check for absence of string, fail template if found
;    find = [pos,]str   check for presence of string, produce "1" if found, "0" if not
;    parse = [pos,]str  check for presence of string, parse wildcards
;    array = [pos,]str  like parse, but matches multiple lines to produce an array
;    values = v,v,v     produce constant values
;    assign = v,v,v     assign values to results
;    continue = y/n     continue with other templates?
;
;  All matching is case-insensitive.
;
;  Strings for "parse" and "array" can contain '$' as place-holder for values.
;  The message is split using the "maximum-munch" rule: if there are multiple
;  ways to split a line, PCC2 chooses the one which makes the first item longest.
;  However, a placeholder will never match an empty string. Each '$' placeholder
;  produces one value.
;
;  All strings can contain "%-X" and "%X" to be replaced with race names, just
;  as in mission and fcode names. This is used to search for race names (in
;  contrast to matching racenames, see below).
;
;  Requests "find", "parse", "array", "values" produce values. Those must be
;  assigned to results using "assign". By convention, every request producing
;  values is followed by an "assign" request consuming the values, but that's
;  not currently required (but might be in the future).
;
;  "array" requests match multiple times, and match results for each '$' are
;  concatenated. As a special case, if one item is assigned the name "INDEX",
;  that column should produce integers from 1..11 (player numbers), allowing
;  re-ordering of values.
;
;  For "fail", "check", "find", "parse", "array", the match string may be
;  preceded by a location specifier:
;     =n                check only line n (counting starts at 1)
;     +n                check nth line after previous match
;     -n                check nth line before previous match
;  If no location is given, the whole message is searched. The "previous match"
;  is the line where the last successful "check"/"find"/"parse"/"array" left off.
;
;  The "values" request accepts the special keywords:
;     Player            receiver of message, integer
;     Id                Id from message header, '123' in "(-k9123)"
;     SubId             Sub-Id from message header, as integer, '9'  in "(-k9123)"
;     BigId             Sub-Id and Id, '9123' in "(-k9123)"
;
;  The "assign" request lists variable names to assign the values to. The
;  set of variables depends upon the objectType. Each variable name may be
;  optionally followed by a type modifier.
;     nnn:x10           Parse float, multiply by 10 to get integer (i.e. "3.5" yields integer 35)
;     nnn:x100          Parse float, multiply by 100 to get integer
;     nnn:x1000         Parse float, multiply by 1000 to get integer
;     nnn:race.adj      It's a race adjective, convert to player number
;     nnn:race.short    It's a race short name
;     nnn:race          It's a race long name
;     nnn:hull          It's a hull name
;     nnn:<type>+allies It's a <type> as above, followed by an alliance flag ("!", "+", for Tim-Host allies)
;     nnn:a/b/c...      Enumeration, a converts to 0, b converts to 1, ...
;  Default is integer or bool. A name can be "_" to ignore that item.
;  A name can be prefixed with "+" or "-" to add to/subtract from a previous
;  value.
;
;  The values produced by a template depend on the template type.
;  - Alliance: this is mostly ad-hockery to parse Tim's alliances.
;    . Name: alliance level name
;    . From, To: "strong" alliance offers
;    . Flags: "+", "!" flags
;  - Configuration: names are PConfig keys
;  - Explosion, Minefield, Planet, Base, Ship: object properties
;
;  For tons of examples, see below :)
;

; (-l0001)<<< Sub Space Message >>>
;
; From: C.C.S.S. Excelsior
; We have converted our
; torpedoes into web mines
; and laid them in a field centered
; at ( 1391 ,  2411 )
;  931 mines were laid
; Mine field ID#  1 now contains
;  931 mine units and is
;  30 light years in radius

minefield,Lay Mines
  kind    = l
  parse   = at ($,$)
  assign  = X, Y
  parse   = $ mine units
  assign  = Units
  find    = into web mines
  assign  = Type
  values  = Player, Id, 1(Laid)
  assign  = Owner, Id, Reason


; (-m0019)<<< Sub Space Message >>>
;
; From: C.S.S. TradeHs01
; We are scanning for mines
; Enemy Mine field detected!
; AT ( 2282 , 2545 )
; They are Spectrum style mines.
; We are 172 light years
; from the outside edge of the field.
; There are  69 mine units.
; Mine field ID Number :  19
; The field is  16 light years across.
; We must be  167LY closer to
; target mines with beam weapons.
;  69 mines remain.

minefield,Scan Mines
  kind    = m
  check   = Sub Space Message
  check   = Enemy Mine Field
  parse   = at ($,$)
  assign  = X, Y
  parse   = $ mines remain
  assign  = Units
  parse   = they are $ style
  assign  = Owner:Race.Adj
  find    = +0,style web mines
  assign  = Type
  values  = Id, 3(scanned)
  assign  = Id, Reason

; NewEnglish:
; (-m0006)<<< Sub Space Message >>>
;
; Enemy Web mine field detected
; at (2645, 2903)!
; They are Crystalline style web mines.
;
; There are 3118 mine units.
; Mine field ID Number: #6
; The field is 110 light years across.

minefield,Scan Web Mines
  kind    = m
  check   = Sub Space Message
  check   = Enemy Web mine field
  parse   = at ($,$)
  assign  = X, Y
  parse   = There are $ mine units
  assign  = Units
  parse   = they are $ style web mines
  assign  = Owner:Race.Adj
  values  = Id, 1, 3(scanned)
  assign  = Id, Type, Reason



; (-m0@5%U)<<< Sub Space Message >>>
;
; From: @1%S
; We are scanning our mines
; at ( @2%u ,  @3%u )
; Mine field contains  @4%l mines.
; Mine field ID Number :  @5%u
; We are in the mine field.
; We have gathered up  @6%l mines.
;[ ( Web Style Mines )]
; We have made  @7%u new torpedoes
; Fcode Planet: @8%u

minefield,Scoop Own Mines
  kind   = m
  check  = We are scanning our mines
  parse  = at ($,$)
  assign = X, Y
  parse  = Mine field contains $ mines
  assign = Units
  parse  = We have gathered up $ mines
  assign = -Units
  find   = Web style mine
  assign = Type
  values = Id, Player, 3(Scanned)
  assign = Id, Owner, Reason


; (-m0033)<<< Sub Space Message >>>
;
; From: Bonehead sOn
; We are scanning our mines
; at ( 2136 ,  2141 )
; Mine field contains  6171 mines.
; Mine field ID Number :  33
;[It is a web style mine field.]
; We are  120 LY to outside edge
; Local Fcode Planet: ID#  424

minefield,Scan Own Mines
  kind   = m
  check  = We are scanning our mines
  parse  = at ($,$)
  assign = X, Y
  parse  = Mine field contains $ mines
  assign = Units
  find   = Web style mine
  assign = Type
  values = Id, Player, 3(Scanned)
  assign = Id, Owner, Reason


; (-z0474)<<< SENSOR SWEEP >>>
; FROM: JSC Lagosi Brektal 3
; Sensor sweep shows
;
; heavy industrial activity
; On : Hudrak-12
; Planet ID#  474
; Sensors show there to be
; >>> Robotic style <<<
; machines on the planet

planet,Sensor Sweep
  kind   = z
  check  = Sensor Sweep
  parse  = $ industrial activity
  assign = Industry:minimal/light/moderate/substantial/heavy
  parse  = >>> $ style <<<
  assign = Owner:Race.Adj
  values = Id
  assign = Id


; (-z0300)<<< Sub Space Message >>>
;
; From: King Condor 500
; At:Muendella
; Temp:  64 ( Temperate - warm )
; There are enemy colonists
; living on this planet.
; The colonists are part of the
; Cylon race.
; Sensors show that there are
;  626 enemy clans.

planet,Exploration
  kind   = z
  check  = Sub Space
  check  = part of the
  parse  = +1,$ race
  assign = Owner:Race.Adj
  parse  = Temp: $
  assign = Temp
  parse  = $ enemy clans
  assign = Colonists
  find   = They have a starbase
  assign = Base
  value  = Id
  assign = Id

; (-z0300)<<< Sub Space Message >>>
;
; From: King Condor 500
; At:Muendella
; The planet has 0 megacredits
;  217 mineral mines
;  122 factories
;  73 defense outposts
; The planetary friendly code is : UeR
;  Minerals on/in planet
; N: 15 M: 24 T: 32 D: 8
;   Supplies : 228

planet,Super Spy
  kind   = z
  check  = Sub space
  parse  = $ mineral mine
  assign = Mines
  parse  = $ factor
  assign = Factories
  parse  = $ defense outpost
  assign = Defense
  check  = planetary friendly code
  parse  = +0,: $
  assign = FCode
  check  = Minerals on
  parse  = +1,N: $
  assign = Total.N
  parse  = +0,T: $
  assign = Total.T
  parse  = +0,D: $
  assign = Total.D
  parse  = +0,M: $
  assign = Total.M
  parse  = Supplies : $
  assign = Supplies
  parse  = planet has $ megacredits
  assign = Money
  values = Id
  assign = Id


;      IF Pos('SUB SPACE',EditText[1])<>0 THEN BEGIN
;        IF GrabSpyMinerals(post) THEN Crea:=FALSE;
;
;        { super spy }
;        S := GetEditLine('SUPPLIES :');
;        IF S<>'' THEN BEGIN
;          TurnMc := Gen.TurnNr;
;          star.Supplies := Eval(S);
;          Crea := FALSE;
;        END;
;
;        { super spy or dark sense }
;        S := GetEditLine('MEGACREDITS');
;        j := 1;
;        WHILE (j <= Length(S)) AND ((S[j]<'0') OR (S[j]>'9')) DO Inc(j);
;        IF j < Length(S) THEN BEGIN
;          TurnMc := Gen.TurnNr;
;          star.Megacredits := GrabNum(S, j-1);
;          Crea := FALSE;
;        END;
;
;        { super spy }
;        L := GrabNum(GetEditLine('MINERAL MINES'),1);
;        IF L >= 0 THEN BEGIN star.MineCnt := L; Crea := FALSE; END;
;        L := GrabNum(GetEditLine('FACTORIES'),1);
;        IF L >= 0 THEN BEGIN star.FactCnt := L; Crea := FALSE; END;
;        L := GrabNum(GetEditLine('DEFENSE OUTPOSTS'),1);
;        IF L >= 0 THEN BEGIN star.DefenseCnt := L; Crea := FALSE; END;
;
;        S := GetEditLine('THE PLANETARY FRIENDLY CODE');
;        IF S<>'' THEN BEGIN
;          Delete(S, 1, Length(S) - 3);
;          Move(S[1], star.friendlycode, 3);
;          Crea := FALSE;
;        END;
;      END ELSE IF Pos('BIO SCAN',EditText[1])<>0 THEN BEGIN
;        S:=GetEditLine('CLIMATE');
;        IF S<>'' THEN BEGIN
;          star.Temp:=100-Eval(S);
;          Crea:=FALSE;
;        END;
;        IF GetEditLine('BIO SCANNERS SHOW')<>'' THEN BEGIN
;          S:=Copy(EditText[LastLine+1],1,5);
;          k:=-1;
;          cc:=0;
;          FOR j:=1 TO 9 DO IF Copy(Global.Natives[j],1,5)=S THEN k:=j;
;          IF S='No Na' THEN k:=0;
;          IF k>=0 THEN BEGIN
;            S:=GetEditLine('LIFEFORMS');
;            IF (k<>0) AND (S<>'') THEN BEGIN
;              Strip1(S);
;              j:=Pos(' ',S);
;              IF j>0 THEN S[0]:=Chr(j-1);
;              Val(S,cc,j);
;            END ELSE j:=0;
;            IF j=0 THEN BEGIN
;              TurnNat:=Gen.TurnNr;
;              star.NatRace:=k;
;              star.Natives:=cc DIV 100;
;              IF star.NatGov<=0 THEN star.NatGov:=-1;
;            END;
;          END;
;        END;
;      END;
;    END;
;    IF Crea THEN BEGIN
;      DestroyObject(Stars^[id].HOld2);
;      Stars^[id].HOld2:=NIL;
;    END ELSE BEGIN
;      Unlock(Stars^[id].HOld2);
;   END;

;    {--- Bang ---}
;    IF (Category='x') THEN BEGIN
;      j:=-1;
;      FOR k:=10 DOWNTO 2 DO IF Pos('(',EditText[k])<>0 THEN j:=k;
;      IF j<>-1 THEN BEGIN
;        GetXY(EditText[j],X,Y);
;        PP := BangAt(X,Y);
;        IF PP<>NIL THEN BEGIN
;          IF (GetEditLine('THE NAME OF THE SHIP')<>'') OR (GetEditLine('IT WAS SHIP')<>'')
;           THEN PP^.Info := NewStr('Explosion of the ' + EditText[Succ(LastLine)]);
;          PP^.Tag := pt_MessageTag - i;
;        END;
;      END;
;    END ELSE

explosion,THost
  kind   = x
  parse  = ($,$)
  assign = X, Y
  check  = The name of the ship
  parse  = +1,$
  assign = Name

explosion,PHost
  kind   = x
  parse  = ($,$)
  assign = X, Y
  check  = It was ship
  parse  = +1,$
  assign = Name

explosion,Nameless
  kind   = x
  parse  = ($,$)
  assign = X, Y


;    {--- Mine ---}
;    IF (Category='e') THEN BEGIN
;      IF GetEditLine('HAS STRUCK A MINE')<>'' THEN BEGIN
;        S:=GetEditLine('ID #');
;        IF S<>'' THEN id := Eval(S) ELSE id := 0;
;        IF (id<>0) AND (Ships^[id].HUser=NIL) THEN BEGIN
;          j:=LastLine;
;          S:=GetEditLine('AT:');
;          GetXY(S,X,Y);
;          PP := BangAt(X,Y);
;          IF PP<>NIL THEN BEGIN
;            PP^.Info := NewStr(EditText[j-1] + ' hit a mine');
;            PP^.Tag := pt_MessageTag - i;
;          END;
;        END;
;      END;
;    END ELSE

explosion,Mine Hit
  ; FIXME: add "hit a mine" text
  kind     = e
  parse    = Has struck a mine
  check    = ID #
  parse    = -1,$
  assign   = Name
  parse    = At: ($,$)
  assign   = X, Y
  continue = y

explosion,Mine Hit (Enemy)
  ; FIXME: add "hit a mine" text
  kind     = n
  parse    = Has struck a mine
  check    = ID #
  parse    = -1,$
  assign   = Name
  parse    = At: ($,$)
  assign   = X, Y
  continue = y

ship,Mine Hit
  ; Match the same things again, but this time produce a ship,
  ; not an explosion.
  kind     = e
  parse    = Has struck a mine
  parse    = ID #$
  assign   = Id
  parse    = -1,$
  assign   = Name
  parse    = At: ($,$)
  assign   = X, Y
  parse    = Damage is at $
  assign   = Damage

ship,Mine Hit (Enemy)
  ; Match the same things again, but this time produce a ship,
  ; not an explosion.
  kind     = n
  parse    = Has struck a mine
  parse    = ID #$
  assign   = Id
  parse    = -1,$
  assign   = Name
  parse    = At: ($,$)
  assign   = X, Y
  parse    = Damage is at $
  assign   = Damage

ship,Web Mine Hit
  kind     = e
  parse    = Has struck a WEB mine
  parse    = ID #$
  assign   = Id
  parse    = -1,$
  assign   = Name
  parse    = Damage is at $
  assign   = Damage

ship,Web Mine Hit (Enemy)
  kind     = n
  parse    = Has struck a WEB mine
  parse    = ID #$
  assign   = Id
  parse    = -1,$
  assign   = Name
  parse    = Damage is at $
  assign   = Damage

;    {--- Meteor ---}
;    IF (Category='y') AND (GetEditLine('METEOR IMPACT')<>'') THEN BEGIN
;      post := OldPlanet(id);
;      WITH post^ DO BEGIN
;        TurnMin:=Gen.TurnNr;
;        L := GrabNum(GetEditLine('NEUTRONIUM'),1);
;        IF L>=0 THEN BEGIN star.GndN := L; star.DensN := -1; END;
;        L := GrabNum(GetEditLine('TRITANIUM'),1);
;        IF L>=0 THEN BEGIN star.GndT := L; star.DensT := -1; END;
;        L := GrabNum(GetEditLine('DURANIUM'),1);
;        IF L>=0 THEN BEGIN star.GndD := L; star.DensD := -1; END;
;        L := GrabNum(GetEditLine('MOLYBDENUM'),1);
;        IF L>=0 THEN BEGIN star.GndM := L; star.DensM := -1; END;
;      END;
;      Unlock(Stars^[id].HOld2);
;      PP := BangAt(Stars^[id].X, Stars^[id].Y);
;      IF PP<>NIL THEN BEGIN
;        PP^.Info := NewStr('Meteor');
;        PP^.Tag := pt_MessageTag - i;
;      END;
;    END ELSE

planet,Meteor Hit
  kind     = y
  values   = Id
  assign   = Id
  parse    = $ kt Neutronium
  assign   = Total.N
  parse    = $ kt Tritanium
  assign   = Total.T
  parse    = $ kt Duranium
  assign   = Total.D
  parse    = $ kt Molybdenum
  assign   = Total.M
  continue = y
  ; FIXME: add explosion marker -- how?

;    {--- Zerst”rung ---}
;    IF Category='f' THEN BEGIN
;      j:=0;
;      R:=0;
;      IF GetEditLine('HAS DESTROYED THE')<>'' THEN j:=LastLine+2 ELSE
;      IF GetEditLine('HAS BEEN DESTROYED BY THE')<>'' THEN j:=Pred(LastLine) ELSE BEGIN
;        r:=1;
;        IF GetEditLine('HAS BEEN CAPTURED BY THE')<>'' THEN j:=Pred(LastLine) ELSE
;        IF GetEditLine('HAS CAPTURED THE')<>'' THEN j:=LastLine+2;
;      END;
;      IF j<>0 THEN BEGIN
;        L:=0;
;        FOR k:=2 TO 10 DO IF Pos('(',EditText[k])<>0 THEN L:=k;
;        IF L<>0 THEN BEGIN
;          GetXY(EditText[L],X,Y);
;          PP:=BangAt(X,Y);
;          IF PP<>NIL THEN BEGIN
;            PP^.Tag := pt_MessageTag - i;
;            S:=EditText[j];
;            k:=Length(S);
;            WHILE (k>1) AND (Copy(S,k,4)<>'ID #') DO Dec(k);
;            IF (k>1) THEN S[0]:=Chr(k-1);
;            Strip1(S);
;            IF r=1 THEN PP^.Info := NewStr(S + ' captured')
;            ELSE PP^.Info := NewStr('Explosion of the ' + S);
;          END;
;        END;
;      END;
;    END ELSE
;    {--- PBPs ---}

; (-c0000)<<< Priority Points >>>
; (For Ship Build Queue)
; Southern   :    16
; Freihaendler    15
; Atari   :       20
; FLOPPIECE   :   19
; Spectrum   :    20
; Cyborg   :      2
; Crystalline   : 7
; J rginistisc !  19
; Robotic+! :     15
; CHEMNI+! :      5
; Northern   :    13
; HOST Version 3.22.020
; Compiled: Nov 26, 1997

playerscore,PBPs
  kind   = c
  check  = Priority Points
  check  = Build Queue
  array  = +1,$ $
  assign = Index:Race.Adj+Allies, Score
  values = 2
  assign = Id
  continue = y

; The "Flags" item will produce a list of just the indexes ("Robotic+!")
; which is figured into the correct order by PCC2.
alliance,Classic allies
  kind   = c
  check  = Priority Points
  check  = Build Queue
  array  = +1,$ $
  assign = Flags, _
  values = thost.ally
  assign = Name

; (-g0000)FF / ff Allies:
; Race:  4 yes / yes
; Race:  7 yes / yes

alliance,Strong allies
  kind   = g
  check  = FF allies
  array  = +1,Race: $ $ / $
  assign = Index, ToFF, FromFF
  values = thost.ff
  assign = Name


; (-90306)<<< Captain's Log >>>
; (using the dark sense)
; I have a feeling that
; there are Orion
; colonists living on
; Neinmen
; Planet ID#  306
;  Minerals on/in planet
; N: 880 M: 862 T: 829 D: 876
;   Megacredits :  0

planet,Dark Sense
  kind   = 9
  check  = dark sense
  parse  = there are $
  assign = Owner:Race.Adj
  check  = Minerals on
  parse  = +1,N: $
  assign = Total.N
  parse  = +0,T: $
  assign = Total.T
  parse  = +0,D: $
  assign = Total.D
  parse  = +0,M: $
  assign = Total.M
  parse  = Megacredits : $
  assign = Money
  find   = They have a starbase
  assign = Base
  value  = Id
  assign = Id

; The above fails to match NewEnglish.
; The following stub will match and associate the message with the target planet.
; Data will come from util.dat.
;
; (-90363)<<< Captain's Log >>>
;
; I have a feeling that
; there are Klingon
; colonists living on
; Rambo 3 (planet Id #363)
;
; Minerals on/in planet
; N: 1234 M: 567 T: 8910 D: 11
; Megacredits: 14

planet,Dark Sense (2)
  kind   = 9
  check  = I have a feeling that
  check  = there are
  check  = Minerals on
  value  = Id
  assign = Id


; (-i0021)<<< ION Advisory >>>
; Ion Disturbance
; ID Number:  21
; Centered At: (  2468, 2639)
; West of Regula
; Planet ID Number  45
;  31 LY from planet
; Voltage : 105
; Heading : 197
; Speed   :  Warp 6
; Radius  : 167
; Class :  Level 3
;   Strong
; System is growing

ionstorm,Ion Storm Warning
  kind   = i
  values = Id
  assign = Id
  parse  = Centered at: ($,$)
  assign = X, Y
  parse  = Voltage : $
  assign = Voltage
  parse  = Heading : $
  assign = Heading
  parse  = Speed $ Warp $
  assign = _, Speed
  parse  = Radius  : $
  assign = Radius
  parse  = System is $
  assign = Status:weakening/growing

; (-e011)<<< ION Storm >>>
; From: GCS Iron Will
; Ship ID Number:  11
; Our ship is caught in
; Ion Storm: Roxana
; Ion Storm ID # 22
; We have been pulled
;  27 LY off course.
; Damage Taken:  0
; Crew Killed :  0
; Shields are down.

ship,Ion Storm Effect
  kind   = e
  check  = Our ship is caught
  check  = We have been pulled
  values = Id
  assign = Id


;;
;;  HCONFIG
;;

; (-g0000)< Message from your Host >
;
; I have set the following:
;
; Colonize recycle rate :  80 %
;  ^ ( minerals recovered from hull )
;
; Odds of a meteor  4 %
; Antiship space mines  YES
; Alchemy ships         YES
; Delete Old Messages   NO
; Disable Passwords     NO
; Rebel Build fighters in space YES
; Colonial Build fighters in space YES
; Divan Build fighters in space YES
; Odds of cloak failure  2 %
; Outlaw rob cloaked ships NO
; Dragoner Dark Sense range  200

config,RecycleRate
  kind     = g
  parse    = Colonize recycle rate : $
  assign   = RecycleRate
  continue = y
config,RandomMeteorRate
  kind     = g
  parse    = Odds of a meteor $
  assign   = RandomMeteorRate
  continue = y
config,AllowMinefields
  kind     = g
  parse    = Antiship space mines $
  assign   = AllowMinefields
  continue = y
config,AllowAlchemy
  kind     = g
  parse    = Alchemy ships $
  assign   = AllowAlchemy
  continue = y
config,DeleteOldMessages
  kind     = g
  parse    = Delete Old Messages $
  assign   = DeleteOldMessages
  continue = y
config,DisablePasswords
  kind     = g
  parse    = Disable Passwords $
  assign   = DisablePasswords
  continue = y
config,RebelsBuildFighters
  kind     = g
  parse    = %-a Build fighters in space $
  assign   = RebelsBuildFighters
  continue = y
config,ColoniesBuildFighters
  kind     = g
  parse    = %-b Build fighters in space $
  assign   = ColoniesBuildFighters
  continue = y
config,RobotsBuildFighters
  kind     = g
  parse    = %-9 Build fighters in space $
  assign   = RobotsBuildFighters
  continue = y
config,CloakFailureRate
  kind     = g
  parse    = Odds of cloak failure $
  assign   = CloakFailureRate
  continue = y
config,RobCloakedShips
  kind     = g
  parse    = %-5 rob cloaked ships $
  assign   = RobCloakedShips
  continue = y
config,DarkSenseRange
  kind     = g
  parse    = %-8 Dark Sense range $
  assign   = DarkSenseRange
  continue = y

; (-g0000)< Message from your Host >
; Ground Attack Kill Ratio
;   Transexual   1  : 1
;   Lizard       20 : 1
;   Bird Man     1  : 1
;   Brahma       10 : 1
;   Outlaw       1  : 1
;   Cyborg       1  : 1
;   Crystalline  1  : 1
;   Dragoner     1  : 1
;   Divan        1  : 1
;   Rebel        1  : 1
;   Colonial     1  : 1
; Ships are visible at  300
; Lizard hiss mission  YES
; Rebel ground attack  YES
; Transexual super refit  YES
; Web mines  YES

config,GroundKillFactor
  kind     = g
  check    = Ground Attack Kill Ratio
  array    = +1,$ $ : 1
  assign   = Index:Race.Adj, GroundKillFactor
  continue = y

config,ScanRange
  kind     = g
  parse    = Ships are visible at $
  assign   = ScanRange
  continue = y

config,AllowHiss
  kind     = g
  parse    = %-2 hiss mission $
  assign   = AllowHiss
  continue = y

config,AllowRebelGroundAttack
  kind     = g
  parse    = %-a ground attack $
  assign   = AllowRebelGroundAttack
  continue = y

config,AllowSuperRefit
  kind     = g
  parse    = %-1 super refit $
  assign   = AllowSuperRefit
  continue = y

config,AllowWebMines
  kind     = g
  parse    = Web mines $
  assign   = AllowWebMines
  continue = y

; (-g0000)< Message from your Host >
; Ground Defense Kill Ratio
;   Transexual   1  : 1
;   Lizard       10 : 1
;   Bird Man     1  : 1
;   Brahma       5  : 1
;   Outlaw       1  : 1
;   Cyborg       1  : 1
;   Crystalline  1  : 1
;   Dragoner     1  : 1
;   Divan        1  : 1
;   Rebel        1  : 1
;   Colonial     1  : 1
; Cloak fuel burn per 100kt  5
; Range of sensors      200
; New Natives           YES
; Planets attack ships  YES
; Assimilation rate     90 %

config,GroundDefenseFactor
  kind     = g
  check    = Ground Defense Kill Ratio
  array    = +1,$ $ : 1
  assign   = Index:Race.Adj, GroundDefenseFactor
  continue = y
config,CloakFuelBurn
  kind     = g
  parse    = Cloak fuel burn per 100kt $
  assign   = CloakFuelBurn
  continue = y
config,SensorRange
  kind     = g
  parse    = Range of sensors $
  assign   = SensorRange
  continue = y
config,AllowNewNatives
  kind     = g
  parse    = New Natives $
  assign   = AllowNewNatives
  continue = y
config,AllowPlanetAttacks
  kind     = g
  parse    = Planets attack ships $
  assign   = AllowPlanetAttacks
  continue = y
config,BorgAssimilationRate
  kind     = g
  parse    = Assimilation rate $
  assign   = BorgAssimilationRate
  continue = y

; (-g0000)< Message from your Host >
;  Free fighters at starbases
;   Transexual   0
;   Lizard       0
;   Bird Man     0
;   Brahma       0
;   Outlaw       0
;   Cyborg       0
;   Crystalline  0
;   Dragoner     1
;   Divan        0
;   Rebel        0
;   Colonial     0
; web mine decay   4 %
; mine decay       4 %
; max mine radius  150
; isotope TUDR     5
; structure decay  1

config,FreeFighters
  kind     = g
  check    = Free fighters at starbases
  array    = +1,$ $
  assign   = Index:Race.Adj, FreeFighters
  continue = y
config,WebMineDecayRate
  kind     = g
  parse    = web mine decay $
  assign   = WebMineDecayRate
  continue = y
config,MineDecayRate
  kind     = g
  parse    = mine decay $
  assign   = MineDecayRate
  continue = y
config,MaximumMinefieldRadius
  kind     = g
  parse    = max mine radius $
  assign   = MaximumMinefieldRadius
  continue = y
config,TransuraniumDecayRate
  kind     = g
  parse    = isotope TUDR $
  assign   = TransuraniumDecayRate
  continue = y
config,StructureDecayPerTurn
  kind     = g
  parse    = structure decay $
  assign   = StructureDecayPerTurn
  parse    = structure decay $
  assign   = StructureDecayOnUnowned
  continue = y

; (-g0000)< Message from your Host >
;  Mining rates
;   Transexual   70
;   Lizard       200
;   Bird Man     100
;   Brahma       100
;   Outlaw       100
;   Cyborg       100
;   Crystalline  100
;   Dragoner     100
;   Divan        100
;   Rebel        100
;   Colonial     100
; Eat supplies?       NO
; 0 Fuel ships move?  YES
; Mine odds per LY    1 %
; Web odds per LY     5 %
; Detect mine range   200

config,RaceMiningRate
  kind     = g
  check    = Mining rates
  array    = +1,$ $
  assign   = Index:Race.Adj, RaceMiningRate
  continue = y
config,AllowEatingSupplies
  kind     = g
  parse    = Eat supplies? $
  assign   = AllowEatingSupplies
  continue = y
config,AllowNoFuelMovement
  kind     = g
  parse    = 0 Fuel ships move? $
  assign   = AllowNoFuelMovement
  continue = y
config,MineHitOdds
  kind     = g
  parse    = Mine odds per LY $
  assign   = MineHitOdds
  continue = y
config,WebMineHitOdds
  kind     = g
  parse    = Web odds per LY $
  assign   = WebMineHitOdds
  continue = y
config,MineScanRange
  kind     = g
  parse    = Detect mine range $
  assign   = MineScanRange
  continue = y

; (-g0000)< Message from your Host >
;  Tax rates
;   Transexual   200
;   Lizard       100
;   Bird Man     100
;   Brahma       100
;   Outlaw       100
;   Cyborg       100
;   Crystalline  100
;   Dragoner     100
;   Divan        100
;   Rebel        100
;   Colonial     100
; Mines destroy mines  YES
; Engine-Shield bonus  YES
; E-S Bonus rate       25 %

config,ColonistTaxRate
  kind     = g
  check    = Tax rates
  array    = +1,$ $
  assign   = Index:Race.Adj, ColonistTaxRate
  continue = y
config,AllowMinesDestroyMines
  kind     = g
  parse    = Mines destroy mines $
  assign   = AllowMinesDestroyMines
  continue = y
config,AllowEngineShieldBonus
  kind     = g
  parse    = Engine-Shield bonus $
  assign   = AllowEngineShieldBonus
  continue = y
config,EngineShieldBonusRate
  kind     = g
  parse    = E-S Bonus rate $
  assign   = EngineShieldBonusRate
  continue = y

; (-g0000)< Message from your Host >
; Col Fgtr Mine sweep  20
; Col Fgtr Web  sweep  NO
; Mine Sweep Rate      4
; Web Sweep Rate       3
; Hiss effect per ship 5
; Rob fail rate        1
; ATT/NUK attack Reb   NO
; ATT/NUK attack Fas   NO
; Mine Sweep Range     5
; Web Sweep Range      0
; Science Missions     YES
; Cloaked Mine Odds    .5 %
; Cloak Prevent Damage 1 %
; Fed Crew Bonus       YES
config,ColonialFighterSweepRate
  kind     = g
  parse    = Col Fgtr Mine Sweep $
  assign   = ColonialFighterSweepRate
  continue = y
config,AllowColoniesSweepWebs
  kind     = g
  parse    = Col Fgtr Web  sweep $
  assign   = AllowColoniesSweepWebs
  continue = y
config,MineSweepRate
  kind     = g
  parse    = Mine Sweep Rate $
  assign   = MineSweepRate
  continue = y
config,WebMineSweepRate
  kind     = g
  parse    = Web Sweep Rate $
  assign   = WebMineSweepRate
  continue = y
config,HissEffectRate
  kind     = g
  parse    = Hiss effect per ship $
  assign   = HissEffectRate
  continue = y
config,RobFailureOdds
  kind     = g
  parse    = Rob fail rate $
  assign   = RobFailureOdds
  continue = y
config,PlanetsAttackRebels
  kind     = g
  parse    = ATT/NUK attack Reb $
  assign   = PlanetsAttackRebels
  continue = y
config,PlanetsAttackKlingons
  kind     = g
  parse    = ATT/NUK attack Fas $
  assign   = PlanetsAttackKlingons
  continue = y
config,MineSweepRange
  kind     = g
  parse    = Mine Sweep Range $
  assign   = MineSweepRange
  continue = y
config,WebMineSweepRange
  kind     = g
  parse    = Web Sweep Range $
  assign   = WebMineSweepRange
  continue = y
config,AllowScienceMissions
  kind     = g
  parse    = Science Missions $
  assign   = AllowScienceMissions
  continue = y
config,MineHitOddsWhenCloakedX10
  kind     = g
  parse    = Cloaked Mine Odds $
  assign   = MineHitOddsWhenCloakedX10:X10
  continue = y
config,DamageLevelForCloakFail
  kind     = g
  parse    = Cloak Prevent Damage $
  assign   = DamageLevelForCloakFail
  continue = y
config,AllowFedCombatBonus
  kind     = g
  parse    = Fed Crew Bonus $
  assign   = AllowFedCombatBonus
  continue = y

; (-g0000)< Message from your Host >
;
; One engine ships tow  NO
; Hyper drive ships     YES
; Climate Death Rate    8 %
; Gravity wells         YES
; Crystal desert advant YES
; Mines destroy webs    NO
; Climate limits pop    YES

config,AllowOneEngineTowing
  kind     = g
  parse    = One engine ships tow $
  assign   = AllowOneEngineTowing
  continue = y
config,AllowHyperWarps
  kind     = g
  parse    = Hyper drive ships $
  assign   = AllowHyperWarps
  continue = y
config,ClimateDeathRate
  kind     = g
  parse    = Climate Death Rate $
  assign   = ClimateDeathRate
  continue = y
config,AllowGravityWells
  kind     = g
  parse    = Gravity wells $
  assign   = AllowGravityWells
  continue = y
config,CrystalsPreferDeserts
  kind     = g
  parse    = Crystal desert advant $
  assign   = CrystalsPreferDeserts
  continue = y
config,AllowMinesDestroyWebs
  kind     = g
  parse    = Mines destroy webs $
  assign   = AllowMinesDestroyWebs
  continue = y
config,ClimateLimitsPopulation
  kind     = g
  parse    = Climate limits pop $
  assign   = ClimateLimitsPopulation
  continue = y

; (-g0000)< Message from your Host >
;
; Max income per planet 5000 mc
; Ion Storms            5
; Firecloud Chunnel     YES
; Super-Spy Deluxe      YES
; Ion Storms hide mines YES
; Fascist Glory Device  YES
; Loki anti-cloak       NO
; Lady Royal Gambling   YES
; Cloaked ships attack  YES
; Ship cloning          YES
; Crys/Priv Boarding    YES
; Imperial Assault       YES

config,MaxPlanetaryIncome
  kind     = g
  parse    = Max income per planet $
  assign   = MaxPlanetaryIncome
  continue = y
config,IonStormActivity
  kind     = g
  parse    = Ion Storms $
  assign   = IonStormActivity
  continue = y
config,AllowChunneling
  kind     = g
  parse    = Firecloud Chunnel $
  assign   = AllowChunneling
  continue = y
config,AllowDeluxeSuperSpy
  kind     = g
  parse    = Super-Spy Deluxe $
  assign   = AllowDeluxeSuperSpy
  continue = y
config,IonStormsHideMines
  kind     = g
  parse    = Ion Storms hide mines $
  assign   = IonStormsHideMines
  continue = y
config,AllowGloryDevice
  kind     = g
  parse    = Fascist Glory Device $
  assign   = AllowGloryDevice
  continue = y
config,AllowAntiCloakShips
  kind     = g
  parse    = Loki anti-cloak $
  assign   = AllowAntiCloakShips
  continue = y
config,AllowGamblingShips
  kind     = g
  parse    = Lady Royal Gambling $
  assign   = AllowGamblingShips
  continue = y
config,AllowCloakedShipsAttack
  kind     = g
  parse    = Cloaked ships attack $
  assign   = AllowCloakedShipsAttack
  continue = y
config,AllowShipCloning
  kind     = g
  parse    = Ship cloning $
  assign   = AllowShipCloning
  continue = y
config,AllowBoardingParties
  kind     = g
  parse    = Crys/Priv Boarding $
  assign   = AllowBoardingParties
  continue = y
config,AllowImperialAssault
  kind     = g
  parse    = Imperial Assault $
  assign   = AllowImperialAssault
  continue = y

; (-g0000)< Message from your Host >
;
; Cobol fuel per LY     2 kt
; Hull tech mine slow   7
; Aries makes fuel      YES
; Bioscanners           YES
config,RamScoopFuelPerLY
  kind     = g
  parse    = Cobol fuel per LY $ kt
  assign   = RamScoopFuelPerLY
  continue = y
config,HullTechNotSlowedByMines
  kind     = g
  parse    = Hull tech mine slow $
  assign   = HullTechNotSlowedByMines
  continue = y
config,AllowAdvancedRefinery
  kind     = g
  parse    = Aries makes fuel $
  assign   = AllowAdvancedRefinery
  continue = y
config,AllowBioscanners
  kind     = g
  parse    = Bioscanners $
  assign   = AllowBioscanners
  continue = y
; This one cannot currently be done correctly:
; config,AllowLokiDecloaksBirds
;   kind     = g
;   parse    = Loki Decloaks Birds $
;   assign   = AllowLokiDecloaksBirds
;   continue = y
config,AllowVPAFeatures
  kind     = g
  parse    = VPA Extra Features $
  assign   = AllowVPAFeatures
  continue = y

;;
;;  Scores
;;
playerscore,Tons (PHCC)
  kind   = h
  bigid  = 125
  check  = Ship tonnage sunk
  array  = +2,$: $ kt
  assign = Index:Race.Short, Score
  values = Ship tonnage sunk
  assign = Name

playerscore,PTScore Used
  ; This parses a complete PTScore score message.
  ; This format is/was used on PlanetsServer.
  ;
  ; The 'Array' pattern exercises our matching rules to the extreme.
  ; Because each '$' must match a word, but we still have maximum munch
  ; parsing, a line such as
  ;   5 The Orions    15321  15   3  10
  ; is broken up as
  ;   5 The
  ;   Orions
  ;   15321
  ;   15
  ;   3
  ;   10
  ; The important thing is that the scores are split up correctly. The
  ; race name is mangled by the matcher, but fortunately we don't need
  ; it. "5 The" is parsed as number 5 by PCC2.
  check  = Turn:
  check  = Race
  check  = ptscore
  check  = used plan base cap
  array  = +2,$ $ $ $ $ $
  assign = Index, _, Score, _, _, _
  values = PTScore Used
  assign = Name

playerscore,PTScore Used
  ; This parses a PTScore score message containing only the "used" score
  ; This format is used on PlanetsCentral.
  check  = Turn:
  check  = ptscore
  check  = Race
  check  = +0,used
  fail   = +0,plan
  fail   = +0,base
  fail   = +0,cap
  array  = +2,$ $ $
  assign = Index, _, Score
  values = PTScore Used
  assign = Name

;;
;;  Assign objects to remaining messages
;;
; FIXME: (-uXXXX)

ship,Rob
  kind   = 9
  check  = We have robbed
  values = Id
  assign = Id

planet,Hiss
  kind = 9
  check  = Hissss
  values = Id
  assign = Id

ship,Other Race Special
  kind = 9
  values = Id
  assign = Id

planet,Planet message
  kind   = p
  values = Id
  assign = Id

planet,Terraform
  kind = t
  values = Id
  assign = Id

planet,Meteor Shower
  kind = y
  values = Id
  assign = Id

planet,Sensor Sweep
  kind = z
  values = Id
  assign = Id

base,Base Construction
  kind = d
  values = Id
  assign = Id

;;ship,Fleet Message
;;    'F':IF pconf<>NIL THEN BEGIN
;;      emt_Screen:=1;
;;      emt_X:=id;
;;    END ELSE IF msg > 0 THEN BEGIN
;;      { Suche in VCR-Datenbank }
;;      i := FindVCRNumber(msg);
;;      IF (i<>0) AND (ObjOkay(VCRs^[i], Left) OR ObjOkay(VCRs^[i], Right)) THEN BEGIN
;;      END ELSE BEGIN
;;        emt_X:=id;
;;        IF GetEditLine('PLANET')<>'' THEN emt_Screen:=2 ELSE emt_Screen:=1;
;;      END;
;;    END;

ship,Ship Message
  kind = s
  values = Id
  assign = Id

ship,Web Drain
  kind = w
  values = Id
  assign = Id

;;    'N','E':BEGIN
;;      IF (GetEditLine('IS PLUNDERING')<>'') OR (GetEditLine('LANDED SABOTEURS')<>'')
;;       THEN emt_Screen:=2
;;       ELSE emt_Screen:=1;
;;      emt_X:=id;
;;    END;

ionstorm,Ion Storm
  kind = i
  values = Id
  assign = Id

mine,Lay Mines
  kind = l
  values = Id
  assign = Id

mine,Mine Sweep
  kind = m
  values = Id
  assign = Id

; Local Variables:
; mode: ccspec
; ccspec-param-indent: 2
; End:
