hedgewars/uAIActions.pas
changeset 6580 6155187bf599
parent 6535 51a7e71ad317
child 6700 e04da46ee43c
equal deleted inserted replaced
6579:fc52f7c22c9b 6580:6155187bf599
    21 unit uAIActions;
    21 unit uAIActions;
    22 interface
    22 interface
    23 uses uFloat, uTypes;
    23 uses uFloat, uTypes;
    24 
    24 
    25 const MAXACTIONS     = 96;
    25 const MAXACTIONS     = 96;
    26       aia_none       = 0;
    26     aia_none       = 0;
    27       aia_Left       = 1;
    27     aia_Left       = 1;
    28       aia_Right      = 2;
    28     aia_Right      = 2;
    29       aia_Timer      = 3;
    29     aia_Timer      = 3;
    30       aia_attack     = 4;
    30     aia_attack     = 4;
    31       aia_Up         = 5;
    31     aia_Up         = 5;
    32       aia_Down       = 6;
    32     aia_Down       = 6;
    33       aia_Switch     = 7;
    33     aia_Switch     = 7;
    34 
    34 
    35       aia_Weapon     = $8000;
    35     aia_Weapon     = $8000;
    36       aia_WaitXL     = $8001;
    36     aia_WaitXL     = $8001;
    37       aia_WaitXR     = $8002;
    37     aia_WaitXR     = $8002;
    38       aia_LookLeft   = $8003;
    38     aia_LookLeft   = $8003;
    39       aia_LookRight  = $8004;
    39     aia_LookRight  = $8004;
    40       aia_AwareExpl  = $8005;
    40     aia_AwareExpl  = $8005;
    41       aia_HJump      = $8006;
    41     aia_HJump      = $8006;
    42       aia_LJump      = $8007;
    42     aia_LJump      = $8007;
    43       aia_Skip       = $8008;
    43     aia_Skip       = $8008;
    44       aia_Wait       = $8009;
    44     aia_Wait       = $8009;
    45       aia_Put        = $800A;
    45     aia_Put        = $800A;
    46 
    46     
    47       aim_push       = $8000;
    47     aim_push       = $8000;
    48       aim_release    = $8001;
    48     aim_release    = $8001;
    49       ai_specmask    = $8000;
    49     ai_specmask    = $8000;
    50 
    50 
    51 type TAction = record
    51 type TAction = record
    52                Action: Longword;
    52         Action: Longword;
    53                X, Y, Param: LongInt;
    53         X, Y, Param: LongInt;
    54                Time: Longword;
    54         Time: Longword;
    55                end;
    55         end;
    56      TActions = record
    56         
    57                 Count, Pos: Longword;
    57     TActions = record
    58                 actions: array[0..Pred(MAXACTIONS)] of TAction;
    58         Count, Pos: Longword;
    59                 Score: LongInt;
    59         actions: array[0..Pred(MAXACTIONS)] of TAction;
    60                 isWalkingToABetterPlace: boolean;
    60         Score: LongInt;
    61                 end;
    61         isWalkingToABetterPlace: boolean;
       
    62         end;
    62 
    63 
    63 procedure AddAction(var Actions: TActions; Action: Longword; Param: LongInt; TimeDelta: Longword; X, Y: LongInt);
    64 procedure AddAction(var Actions: TActions; Action: Longword; Param: LongInt; TimeDelta: Longword; X, Y: LongInt);
    64 procedure ProcessAction(var Actions: TActions; Me: PGear);
    65 procedure ProcessAction(var Actions: TActions; Me: PGear);
    65 
    66 
    66 implementation
    67 implementation
    92 );
    93 );
    93 
    94 
    94 procedure DumpAction(Action: TAction; Me: PGear);
    95 procedure DumpAction(Action: TAction; Me: PGear);
    95 begin
    96 begin
    96 if (Action.Action and ai_specmask) = 0 then
    97 if (Action.Action and ai_specmask) = 0 then
    97    WriteLnToConsole('AI action: '+ActionIdToStr[Action.Action])
    98     WriteLnToConsole('AI action: '+ActionIdToStr[Action.Action])
    98 else begin
    99 else
    99    WriteLnToConsole('AI action: '+SpecActionIdToStr[Action.Action]);
   100     begin
   100    if (Action.Action = aia_WaitXL) or (Action.Action = aia_WaitXR) then
   101     WriteLnToConsole('AI action: '+SpecActionIdToStr[Action.Action]);
   101       WriteLnToConsole('AI action Wait X = '+IntToStr(Action.Param)+', current X = '+IntToStr(hwRound(Me^.X)))
   102     if (Action.Action = aia_WaitXL) or (Action.Action = aia_WaitXR) then
   102    else if (Action.Action = aia_AwareExpl) then WriteLnToConsole('Aware X = ' + IntToStr(Action.X) + ', Y = ' + IntToStr(Action.Y));
   103         WriteLnToConsole('AI action Wait X = '+IntToStr(Action.Param)+', current X = '+IntToStr(hwRound(Me^.X)))
   103    end
   104         
       
   105     else if (Action.Action = aia_AwareExpl) then
       
   106         WriteLnToConsole('Aware X = ' + IntToStr(Action.X) + ', Y = ' + IntToStr(Action.Y));
       
   107     end
   104 end;
   108 end;
   105 {$ENDIF}
   109 {$ENDIF}
   106 
   110 
   107 procedure AddAction(var Actions: TActions; Action: Longword; Param: LongInt; TimeDelta: Longword; X, Y: LongInt);
   111 procedure AddAction(var Actions: TActions; Action: Longword; Param: LongInt; TimeDelta: Longword; X, Y: LongInt);
   108 begin
   112 begin
   109 with Actions do
   113 with Actions do
   110      begin
   114     begin
   111      actions[Count].Action:= Action;
   115     actions[Count].Action:= Action;
   112      actions[Count].Param:= Param;
   116     actions[Count].Param:= Param;
   113      actions[Count].X:= X;
   117     actions[Count].X:= X;
   114      actions[Count].Y:= Y;
   118     actions[Count].Y:= Y;
   115      if Count > 0 then actions[Count].Time:= TimeDelta
   119     if Count > 0 then
   116                   else actions[Count].Time:= GameTicks + TimeDelta;
   120         actions[Count].Time:= TimeDelta
   117      inc(Count);
   121     else
   118      TryDo(Count < MAXACTIONS, 'AI: actions overflow', true);
   122         actions[Count].Time:= GameTicks + TimeDelta;
   119      end
   123     inc(Count);
       
   124     TryDo(Count < MAXACTIONS, 'AI: actions overflow', true);
       
   125     end
   120 end;
   126 end;
   121 
   127 
   122 procedure CheckHang(Me: PGear);
   128 procedure CheckHang(Me: PGear);
   123 const PrevX: LongInt = 0;
   129 const PrevX: LongInt = 0;
   124       timedelta: Longword = 0;
   130       timedelta: Longword = 0;
   125 begin
   131 begin
   126 if hwRound(Me^.X) <> PrevX then
   132 if hwRound(Me^.X) <> PrevX then
   127    begin
   133     begin
   128    PrevX:= hwRound(Me^.X);
   134     PrevX:= hwRound(Me^.X);
   129    timedelta:= 0
   135     timedelta:= 0
   130    end else
   136     end else
   131    begin
   137         begin
   132    inc(timedelta);
   138         inc(timedelta);
   133    if timedelta > 1700 then
   139         if timedelta > 1700 then
   134       begin
   140             begin
   135       timedelta:= 0;
   141             timedelta:= 0;
   136       FreeActionsList
   142             FreeActionsList
   137       end
   143             end
   138    end
   144         end
   139 end;
   145 end;
   140 
   146 
   141 procedure ProcessAction(var Actions: TActions; Me: PGear);
   147 procedure ProcessAction(var Actions: TActions; Me: PGear);
   142 var s: shortstring;
   148 var s: shortstring;
   143 begin
   149 begin
   144 repeat
   150 repeat
   145 if Actions.Pos >= Actions.Count then exit;
   151 if Actions.Pos >= Actions.Count then exit;
   146 with Actions.actions[Actions.Pos] do
   152 with Actions.actions[Actions.Pos] do
   147      begin
   153     begin
   148      if Time > GameTicks then exit;
   154     if Time > GameTicks then
   149      {$IFDEF TRACEAIACTIONS}
   155         exit;
   150      DumpAction(Actions.actions[Actions.Pos], Me);
   156     {$IFDEF TRACEAIACTIONS}
   151      {$ENDIF}
   157     DumpAction(Actions.actions[Actions.Pos], Me);
   152      if (Action and ai_specmask) <> 0 then
   158     {$ENDIF}
       
   159     if (Action and ai_specmask) <> 0 then
   153         case Action of
   160         case Action of
   154            aia_Weapon: SetWeapon(TAmmoType(Param));
   161             aia_Weapon: 
   155            aia_WaitXL: if hwRound(Me^.X) = Param then
   162             SetWeapon(TAmmoType(Param));
   156                           begin
   163             
   157                           Action:= aia_LookLeft;
   164             aia_WaitXL: 
   158                           Time:= GameTicks;
   165             if hwRound(Me^.X) = Param then
   159                           exit
   166                 begin
   160                           end
   167                 Action:= aia_LookLeft;
   161                           else if hwRound(Me^.X) < Param then
   168                 Time:= GameTicks;
   162                                begin
   169                 exit
   163                                //OutError('AI: WaitXL assert (' + IntToStr(hwRound(Me^.X)) + ' < ' + IntToStr(Param) + ')', false);
   170                 end
   164                                FreeActionsList;
   171                 else if hwRound(Me^.X) < Param then
   165                                exit
   172                     begin
   166                                end
   173                     //OutError('AI: WaitXL assert (' + IntToStr(hwRound(Me^.X)) + ' < ' + IntToStr(Param) + ')', false);
   167                           else begin CheckHang(Me); exit end;
   174                     FreeActionsList;
   168            aia_WaitXR: if hwRound(Me^.X) = Param then
   175                     exit
   169                           begin
   176                     end
   170                           Action:= aia_LookRight;
   177                 else
   171                           Time:= GameTicks;
   178                     begin CheckHang(Me);
   172                           exit
   179                     exit
   173                           end
   180                     end;
   174                           else if hwRound(Me^.X) > Param then
   181                             
   175                                begin
   182             aia_WaitXR: 
   176                                //OutError('AI: WaitXR assert (' + IntToStr(hwRound(Me^.X)) + ' > ' + IntToStr(Param) + ')', false);
   183             if hwRound(Me^.X) = Param then
   177                                FreeActionsList;
   184                 begin
   178                                exit
   185                 Action:= aia_LookRight;
   179                                end
   186                 Time:= GameTicks;
   180                           else begin CheckHang(Me); exit end;
   187                 exit
   181          aia_LookLeft: if not Me^.dX.isNegative then
   188                 end
   182                           begin
   189                 else if hwRound(Me^.X) > Param then
   183                           ParseCommand('+left', true);
   190                     begin
   184                           exit
   191                     //OutError('AI: WaitXR assert (' + IntToStr(hwRound(Me^.X)) + ' > ' + IntToStr(Param) + ')', false);
   185                           end else ParseCommand('-left', true);
   192                     FreeActionsList;
   186         aia_LookRight: if Me^.dX.isNegative then
   193                     exit
   187                           begin
   194                     end
   188                           ParseCommand('+right', true);
   195                 else
   189                           exit
   196                     begin CheckHang(Me);
   190                           end else ParseCommand('-right', true);
   197                     exit
   191         aia_AwareExpl: AwareOfExplosion(X, Y, Param);
   198                     end;
   192             aia_HJump: ParseCommand('hjump', true);
   199             aia_LookLeft:
   193             aia_LJump: ParseCommand('ljump', true);
   200             if not Me^.dX.isNegative then
   194              aia_Skip: ParseCommand('skip', true);
   201                 begin
   195               aia_Put: doPut(X, Y, true);
   202                 ParseCommand('+left', true);
   196              end else
   203                 exit
   197         begin
   204                 end
   198         s:= ActionIdToStr[Action];
   205             else
   199         if (Param and ai_specmask) <> 0 then
   206                 ParseCommand('-left', true);
   200            case Param of
   207             aia_LookRight:
   201              aim_push: s:= '+' + s;
   208             if Me^.dX.isNegative then
   202           aim_release: s:= '-' + s;
   209                 begin
   203              end
   210                 ParseCommand('+right', true);
   204           else if Param <> 0 then s:= s + ' ' + IntToStr(Param);
   211                 exit
       
   212                 end
       
   213             else ParseCommand('-right', true);
       
   214             aia_AwareExpl:
       
   215             AwareOfExplosion(X, Y, Param);
       
   216             
       
   217             aia_HJump:
       
   218             ParseCommand('hjump', true);
       
   219             
       
   220             aia_LJump:
       
   221             ParseCommand('ljump', true);
       
   222             
       
   223             aia_Skip:
       
   224             ParseCommand('skip', true);
       
   225             
       
   226             aia_Put:
       
   227             doPut(X, Y, true);
       
   228             end
       
   229         else
       
   230             begin
       
   231             s:= ActionIdToStr[Action];
       
   232             if (Param and ai_specmask) <> 0 then
       
   233                 case Param of
       
   234                 aim_push:
       
   235                 s:= '+' + s;
       
   236                 
       
   237                 aim_release:
       
   238                 s:= '-' + s;
       
   239             end
       
   240         else if Param <> 0 then
       
   241             s:= s + ' ' + IntToStr(Param);
   205         ParseCommand(s, true)
   242         ParseCommand(s, true)
   206         end
   243         end
   207      end;
   244     end;
   208 inc(Actions.Pos);
   245 inc(Actions.Pos);
   209 if Actions.Pos <= Actions.Count then
   246 if Actions.Pos <= Actions.Count then
   210    inc(Actions.actions[Actions.Pos].Time, GameTicks);
   247     inc(Actions.actions[Actions.Pos].Time, GameTicks);
   211 until false
   248 until false
   212 end;
   249 end;
   213 
   250 
   214 end.
   251 end.