unit attack;

interface

uses
  sysutils, loadz, svet, expa, aData, voice;


procedure bitva(x, y: shortint);
function pricel(clx, cly: byte; LookMode: boolean = false): word;
function hasammo: boolean;
procedure ataka;


implementation
uses
  MyCRT;

function hasammo: boolean;
var
  i: word;
  item: TItem;
begin
  hasammo := true;
  iteminfo(data.r_hand, item);
  if (item.InOboyma > 0) and (data.InRozhok > 0) then
    exit;
  for i := 1 to MAXITEMS do
    if (data.inventory[i].number = item.AmmoType) then
      Exit;
  hasammo := false;
end;

procedure ataka;
var
  w: word;
  x, y: byte;
  j, k: integer;
  item: TItem;
  count: integer;
begin
  iteminfo(data.r_hand, item);
  if (item.IsShooting) then
  begin
    if not hasammo then
    begin
      hudmessage(STR_HAVENT_AMMO, MT_ERROR, false);
      exit;
    end
    else if (item.InOboyma > 0) and (data.InRozhok = 0) then
    begin
      hudmessage(STR_NEED_RELOAD, MT_ERROR, false);
      exit;
    end;
    x := wherex;
    y := wherey;
    w := pricel(wherex + 1, wherey);
    if (w = 0) or (w = 65535) then
      exit;
    j := w div 256;
    k := w mod 256;
    count := item.ShootsCount;
    for count := count downto 1 do
      if (data.InRozhok > 0) then
        BulletWay(x, y, j, k, aBulletColor(data.r_hand), aMayXplode(data.r_hand), true, (data.Accuracy * 2 + data.weapon) div 3, data.strength, data.r_hand);
    gotoxy(x, y);
    osv;
  end
  else
    hudmessage(STR_YOU_HAVENT_SHOOTING_AMMO_IN_HANDS, MT_ERROR, true, false);
end;

function FoundEnemy(var x, y: byte): boolean;
var
  i, j: byte;
begin
  FoundEnemy := true;
  for j := 1 to RESOLUTION_Y do
    for i := 1 to RESOLUTION_X do
      if (cur_lev.map[i, j].now <> #0) and (IsThisAMonster(i, j)) and (cur_lev.map[i, j].Monster.montype < FRIEND) then
      begin
        x := i;
        y := j;
        exit;
      end;
  FoundEnemy := false;
end;

procedure ClearHud;
var
  x, y: integer;
begin
  x := WhereX;
  y := WhereY;
  GoToXY(1, RESOLUTION_Y + 3);
  while (WhereX < RESOLUTION_X) do
    write(' ');
  GoToXY(x, y);
end;

procedure WriteIssl(x, y: byte);
var
  i: integer;
  s: string;
  col: byte;
  c: char;
  cx, cy: byte;
  enemy: TEnemy;
  item: TItem;
begin
  if (IsThisAMonster(x, y)) then
  begin
    mon_info(cur_lev.map[x, y].Monster.montype, enemy);
    s := enemy.name;
  end
  else if (cur_lev.map[x, y].item.number <> 0) then
  begin
    iteminfo(cur_lev.map[x, y].item.number, item);
    s := item.name;
    if (item.IsShooting) then
      s := s + ' [' + inttostr(cur_lev.map[x, y].item.ammo) + '/' + inttostr(item.InOboyma) + ']';
    if cur_lev.map[x, y].Item.count > 0 then
      s := s + ' (' + inttostr(cur_lev.map[x, y].Item.count) + ')';
  end
  else
  begin
    if (cur_lev.map[x, y].AnObject = #0) then
    begin
      c := cur_lev.map[x, y].lev;
      col := cur_lev.map[x, y].color;
    end
    else
    begin
      c := cur_lev.map[x, y].AnObject;
      col := cur_lev.map[x, y].AnObjectColor;
    end;
    s := '';
    for i := 1 to TypesCount do
      if (KletArr[i].c = c) and (KletArr[i].col = col) then
      begin
        s := KletArr[i].Help;
        break;
      end;
  end;
  cx := wherex;
  cy := wherey;
  gotoxy(1, RESOLUTION_Y + 3);
  textcolor(white);
  write(s);
  gotoxy(cx, cy);
end;

procedure MovePricel(dx, dy: shortint);
var
  cx, cy: integer;
begin
  cx := WhereX;
  cy := WhereY;
  if (not (cx + dx in [1..RESOLUTION_X]) or not (cy + dy in [1..RESOLUTION_Y])) then
    exit;
  if (cur_lev.map[cx + dx, cy + dy].now = #0) then
    exit;
  if (cx = data.posx) and (cy = data.posy) then
    DrawSymbol(cx, cy, HERO_CHAR, getPlayerColor())
  else
    osvkletka(cx, cy);
  gotoxy(cx + dx, cy + dy);
  DrawSymbol(cx + dx, cy + dy, '+', Yellow);
end;

function pricel(clx, cly: byte; LookMode: boolean = false): word;
var
  cx, cy: byte;
  zx, zy: byte;
  c1: char;
begin
  if (data.Fear > 0) and (not LookMode) then
  begin
    hudmessage(STR_YOU_FEARED_FIRE, MT_TEXT);
    pricel := 65535;
    exit;
  end;
  result := 0;
  cx := wherex;
  cy := wherey;
  if (not FoundEnemy(zx, zy)) or (LookMode) then
    gotoxy(cx, cy)
  else
    gotoxy(zx, zy);
  if (not LookMode) then
  begin
    DrawSymbol(WhereX, WhereY, '+', Yellow);
    repeat
      c1 := readkey;
      case c1 of
        KEY_UP: MovePricel(0, -1);
        KEY_DOWN: MovePricel(0, 1);
        KEY_LEFT: MovePricel(-1, 0);
        KEY_RIGHT: MovePricel(1, 0);
        KEY_LEFTUP: MovePricel(-1, -1);
        KEY_LEFTDOWN: MovePricel(-1, 1);
        KEY_RIGHTUP: MovePricel(1, -1);
        KEY_RIGHTDOWN: MovePricel(1, 1);
        KEY_SHOOT:
        begin
          if (WhereX = data.posx) and (WhereY = data.posy) then
          begin
            hudmessage(STR_SHOOT_MYSELF, MT_ERROR, true);
            pricel := 65535;
            gotoxy(data.posx, data.posy);
            DrawSymbol(cx, cy, HERO_CHAR, getPlayerColor);
            exit;
          end;
          if (cur_lev.map[wherex, wherey].Monster.montype >= FRIEND) then
          begin
            osvkletka(WhereX, WhereY);
            hudmessage(STR_I_WILL_NOT_SHOOT_AT_THEM, MT_ERROR, false);
            pricel := 65535;
            gotoxy(cx, cy);
            exit;
          end;
          pricel := wherex * 256 + wherey;
          osvkletka(wherex, wherey);
          gotoxy(cx, cy);
          exit;
        end;
      end;
    until (c1 = KEY_ESCAPE);
    if c1 = KEY_ESCAPE then
      pricel := 0;
  end
  else
  begin
    ClearHud;
    cx := wherex;
    cy := wherey;
    repeat
      PutSymbol(cx, cy, yellow, '+');
      ClearHud;
      WriteIssl(cx, cy);
      c1 := readkey;
      osvkletka(cx, cy);
      case c1 of
        KEY_LEFT:
          if (cx > 1) and (cur_lev.map[cx - 1, cy].now <> #0) then
            dec(cx);
        KEY_RIGHT:
          if (cx < RESOLUTION_x) and (cur_lev.map[cx + 1, cy].now <> #0) then
            inc(cx);
        KEY_UP:
          if (cy > 1) and (cur_lev.map[cx, cy - 1].now <> #0) then
            dec(cy);
        KEY_DOWN:
          if (cy < RESOLUTION_Y) and (cur_lev.map[cx, cy + 1].now <> #0) then
            inc(cy);
        KEY_LEFTDOWN:
          if (cx > 1) and (cy < RESOLUTION_Y) and (cur_lev.map[cx - 1, cy + 1].now <> #0) then
          begin
            dec(cx);
            inc(cy);
          end;
        KEY_LEFTUP:
          if (cx > 1) and (cy > 1) and (cur_lev.map[cx - 1, cy - 1].now <> #0) then
          begin
            dec(cx);
            dec(cy);
          end;
        KEY_RIGHTDOWN:
          if (cx < RESOLUTION_X) and (cy < RESOLUTION_Y) and (cur_lev.map[cx + 1, cy + 1].now <> #0) then
          begin
            inc(cx);
            inc(cy);
          end;
        KEY_RIGHTUP:
          if (cx < RESOLUTION_X) and (cy > 1) and (cur_lev.map[cx + 1, cy - 1].now <> #0) then
          begin
            inc(cx);
            dec(cy);
          end;
      end;
    until (c1 in [KEY_RETURN, KEY_SHOOT, KEY_ESCAPE]);
    pricel := 0;
    cx := clx;
    cy := cly;
  end;
  gotoxy(cx, cy);
  DrawSymbol(cx, cy, HERO_CHAR, getPlayerColor);
end;

procedure bitva(x, y: shortint);
var
  udar: integer;
  xv, yv: byte;
  mon_byte: byte;
  iubit: string;
  healthminus: word;
  cx, cy: byte;
  enemy: TEnemy;
  item: TItem;
  tired: integer;
begin
  healthminus := 0;
  iubit := '';
  xv := wherex;
  yv := wherey;
  if data.Fear > 0 then
  begin
    hudmessage(STR_YOU_FEARED, MT_TEXT);
    exit;
  end;
  iteminfo(data.r_hand, item);
  tired := (item.weight - data.strength) - (data.stamina div 2);
  mon_info(cur_lev.map[wherex + x, wherey + y].Monster.montype, enemy);
  gotoxy(data.posx, data.posy);

  mon_byte := random(2) + 1;
  if (mon_byte mod 2 = 0) and (not IsGluk(wherex + x, wherey + y)) and (enemy.Death <> DDisappear) then
    if IsForBlood(wherex + (x * 2), wherey + (y * 2)) then
      cur_lev.map[wherex + (x * 2), wherey + (y * 2)].attrz := cur_lev.map[wherex + (x * 2), wherey + (y * 2)].attrz or 8;
  healthminus := getmysila(cur_lev.map[wherex + x, wherey + y].Monster.montype);
  iubit := '';
  if (healthminus > 0) then
  begin
    if (healthminus > cur_lev.map[data.posx + x, data.posy + y].Monster.health) then
      iubit := STR_KILLED + SexSklon(enemy.sex);
    if IsGluk(xv + x, yv + y) then
    begin
      decmonhealth(xv + x, yv + y, cur_lev.map[xv + x, yv + y].Monster.health + 1);
      hudmessage(enemy.name + STR_GLUK_DISAPPEARED, MT_TEXT, false);
    end
    else
    begin
      case enemy.sex of
        Male: hudmessage(enemy.name + STR_RANEN_NA + IntToStr(healthminus) + STR_POINTS3 + PointsSklon(healthminus) + iubit, MT_INFO, true);
        Female: hudmessage(enemy.name + STR_RANENA_NA + IntToStr(healthminus) + STR_POINTS3 + PointsSklon(healthminus) + iubit, MT_INFO, true);
        Other: hudmessage(enemy.name + STR_RANENO_NA + IntToStr(healthminus) + STR_POINTS3 + PointsSklon(healthminus) + iubit, MT_INFO, true);
      end;
      if Assigned(item.OnAttack) then
        item.OnAttack(data.posx + x, data.posy + y);
      decmonhealth(xv + x, yv + y, healthminus);
    end;
  end
  else
  begin
    case enemy.sex of
      Male: hudmessage(enemy.name + STR_NOT_RANEN, MT_INFO);
      Female: hudmessage(enemy.name + STR_NOT_RANENA, MT_INFO);
      Other: hudmessage(enemy.name + STR_NOT_RANENO, MT_INFO);
    end;
  end;
  gotoxy(xv, yv);
end;

begin
end.