anchor.diff:                         end;
                        end;
     ct_AINoBuild:      begin
  -                       fPlayers.Player[CurrentPlayerIndex].AI.Autobuild := false;
  +                       fPlayers.Player[fCurrentPlayerIndex].AI.Autobuild := false;
                        end;
     ct_AIStartPosition:begin
  -                       fPlayers.Player[CurrentPlayerIndex].AI.StartPosition := KMPointX1Y1(ParamList[0],ParamList[1]);
  +                       fPlayers.Player[fCurrentPlayerIndex].AI.StartPosition := KMPointX1Y1(ParamList[0],ParamList[1]);
                        end;
     ct_SetAlliance:    begin
                          if ParamList[1] = 1 then
  -                         fPlayers.Player[CurrentPlayerIndex].Alliances[ParamList[0]] := at_Ally
  +                         fPlayers.Player[fCurrentPlayerIndex].Alliances[ParamList[0]] := at_Ally
                          else
  -                         fPlayers.Player[CurrentPlayerIndex].Alliances[ParamList[0]] := at_Enemy;
  +                         fPlayers.Player[fCurrentPlayerIndex].Alliances[ParamList[0]] := at_Enemy;
                        end;
     ct_AttackPosition: begin
                          //If target is building: Attack building
                          //If target is unit: Chase/attack unit
                          //If target is nothing: move to position
                          //However, because the unit/house target may not have been created yet, this must be processed after everything else
  -                       if LastTroop <> nil then
  +                       if fLastTroop <> nil then
                          begin
  -                         inc(AttackPositionsCount);
  -                         SetLength(AttackPositions, AttackPositionsCount+1);
  -                         AttackPositions[AttackPositionsCount-1].Warrior := LastTroop;
  -                         AttackPositions[AttackPositionsCount-1].Target := KMPointX1Y1(ParamList[0],ParamList[1]);
  -                       end;
  +                         inc(fAttackPositionsCount);
  +                         SetLength(fAttackPositions, fAttackPositionsCount+1);
  +                         fAttackPositions[fAttackPositionsCount-1].Warrior := fLastTroop;
  +                         fAttackPositions[fAttackPositionsCount-1].Target := KMPointX1Y1(ParamList[0],ParamList[1]);
  +                       end
  +                       else
  +                         DebugScriptError('ct_AttackPosition without prior declaration of Troop');
                        end;
     ct_AddGoal:        begin
                          //If the condition is time then ParamList[3] is the time, else it is player ID
                          if TGoalCondition(ParamList[0]) = gc_Time then
  -                         fPlayers.Player[CurrentPlayerIndex].Goals.AddGoal(glt_Victory,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),ParamList[3],ParamList[2],play_none)
  +                         fPlayers.Player[fCurrentPlayerIndex].Goals.AddGoal(glt_Victory,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),ParamList[3],ParamList[2],play_none)
                          else begin
                            if ParamList[3] > fPlayers.Count-1 then begin
                              DebugScriptError('Add_Goal for non existing player');
                              exit;
                            end;
  -                         fPlayers.Player[CurrentPlayerIndex].Goals.AddGoal(glt_Victory,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),0,ParamList[2],TPlayerID(ParamList[3]));
  +                         fPlayers.Player[fCurrentPlayerIndex].Goals.AddGoal(glt_Victory,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),0,ParamList[2],TPlayerID(ParamList[3]));
                          end;
                        end;
     ct_AddLostGoal:    begin
                          //If the condition is time then ParamList[3] is the time, else it is player ID
                          if TGoalCondition(ParamList[0]) = gc_Time then
  -                         fPlayers.Player[CurrentPlayerIndex].Goals.AddGoal(glt_Survive,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),ParamList[3],ParamList[2],play_none)
  +                         fPlayers.Player[fCurrentPlayerIndex].Goals.AddGoal(glt_Survive,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),ParamList[3],ParamList[2],play_none)
                          else begin
                            if ParamList[3] > fPlayers.Count-1 then begin
                              DebugScriptError('Add_LostGoal for non existing player');
                              exit;
                            end;
  -                         fPlayers.Player[CurrentPlayerIndex].Goals.AddGoal(glt_Survive,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),0,ParamList[2],TPlayerID(ParamList[3]));
  +                         fPlayers.Player[fCurrentPlayerIndex].Goals.AddGoal(glt_Survive,TGoalCondition(ParamList[0]),TGoalStatus(ParamList[1]),0,ParamList[2],TPlayerID(ParamList[3]));
                          end;
                        end;
     ct_AIDefence:      begin
  -                       fPlayers.Player[CurrentPlayerIndex].AI.AddDefencePosition(KMPointDir(KMPointX1Y1(ParamList[0],ParamList[1]),ParamList[2]),TGroupType(ParamList[3]+1),ParamList[4],TAIDefencePosType(ParamList[5]));
  +                       fPlayers.Player[fCurrentPlayerIndex].AI.AddDefencePosition(KMPointDir(KMPointX1Y1(ParamList[0],ParamList[1]),ParamList[2]),TGroupType(ParamList[3]+1),ParamList[4],TAIDefencePosType(ParamList[5]));
                        end;
     ct_SetMapColor:    begin
                          //For now simply use the minimap color for all color, it is too hard to load all 8 shades from ct_SetNewRemap
  -                       fPlayers.Player[CurrentPlayerIndex].FlagColor := fResource.GetColor32(ParamList[0], DEF_PAL);
  +                       fPlayers.Player[fCurrentPlayerIndex].FlagColor := fResource.GetColor32(ParamList[0], DEF_PAL);
                        end;
     ct_AIAttack:       begin
                          //Set up the attack command
                          if TextParam = PARAMVALUES[cpt_Type] then
                            case ParamList[1] of
  -                           0,2: AIAttack.AttackType := aat_Repeating; //Type 0 is like type 2 but it works in TSK and does not support some extra options. We handle them the same
  -                           1:   AIAttack.AttackType := aat_Once; //Type 1 is a once off attack, it happens after a time and does not repeat
  +                           0,2: fAIAttack.AttackType := aat_Repeating; //Type 0 is like type 2 but it works in TSK and does not support some extra options. We handle them the same
  +                           1:   fAIAttack.AttackType := aat_Once; //Type 1 is a once off attack, it happens after a time and does not repeat
                              else DebugScriptError('Unknown parameter at ct_AIAttack');
                            end;
                          if TextParam = PARAMVALUES[cpt_TotalAmount] then
  -                         AIAttack.TotalMen := ParamList[1];
  +                         fAIAttack.TotalMen := ParamList[1];
                          if TextParam = PARAMVALUES[cpt_Counter] then
  -                         AIAttack.Delay := ParamList[1];
  +                         fAIAttack.Delay := ParamList[1];
                          if TextParam = PARAMVALUES[cpt_Range] then
  -                         AIAttack.Range := ParamList[1];
  +                         fAIAttack.Range := ParamList[1];
                          if TextParam = PARAMVALUES[cpt_TroopAmount] then
  -                         AIAttack.GroupAmounts[TGroupType(ParamList[1]+1)] := ParamList[2];
  +                         fAIAttack.GroupAmounts[TGroupType(ParamList[1]+1)] := ParamList[2];
                          if TextParam = PARAMVALUES[cpt_Target] then
  -                         AIAttack.Target := TAIAttackTarget(ParamList[1]);
  +                         fAIAttack.Target := TAIAttackTarget(ParamList[1]);
                          if TextParam = PARAMVALUES[cpt_Position] then
  -                         AIAttack.CustomPosition := KMPointX1Y1(ParamList[1],ParamList[2]);
  +                         fAIAttack.CustomPosition := KMPointX1Y1(ParamList[1],ParamList[2]);
                          if TextParam = PARAMVALUES[cpt_TakeAll] then
  -                         AIAttack.TakeAll := true;
  +                         fAIAttack.TakeAll := true;
                        end;
     ct_CopyAIAttack:   begin
                          //Save the attack to the AI assets
  -                       fPlayers.Player[CurrentPlayerIndex].AI.AddAttack(AIAttack);
  +                       fPlayers.Player[fCurrentPlayerIndex].AI.AddAttack(fAIAttack);
                        end;
     ct_EnablePlayer:   begin
                          //Serves no real purpose, all players have this command anyway
  
positive.code:       inc(k);
    until (k>=length(FileText));
    //Apparently it's faster to parse till file end than check if all details are filled
  
    //todo: Count existing players
    {ExistingPlayers := 0;
    for i:=1 to fPlayers.PlayerCount do begin
      with fPlayers.Player[i] do
      if (GetHouses.Count + GetUnits.Count > 0) then
        inc(ExistingPlayers);
    end;}
  end;
  
  
  
negative.code:   KM_Houses, KM_Units, KM_Units_Warrior;
  
  type
    TMissionParsingMode = (mpm_Game, mpm_Editor);
  
    TKMCommandType = (ct_Unknown=0,ct_SetMap,ct_SetMaxPlayer,ct_SetCurrPlayer,ct_SetHumanPlayer,ct_SetHouse,
                      ct_SetTactic,ct_AIPlayer,ct_EnablePlayer,ct_SetNewRemap,ct_SetMapColor,ct_CenterScreen,
  