Полет стрелы. Серверная часть.

В принципе реализации дальней атаки (артиллерии) нет ничего сложного, все тоже самое что и обычный удар, кроме а) проверки наличия снарядов(стрел) и возможности стрельбы б) проверки на возможность полета стрелы.

Проверка на наличие снарядов и возможности стрельбы – очень простая: проверяется, что оружие в правой руке – тип артиллерия (TW_RANGE), наличие снарядов, что в правой есть предмет с типом снарядов (TW_ARROW), далее проверяется количество снарядов (прочность предмета).

Проверка на возможность полета стрелы, сложнее, т.к. нужно проверить видимость противника, и учесть то, что стрела летит только по прямой (относительно X-Y координат) и не перелетает сквозь стены.

Если какие-то координаты (X или Y) совпадают с игроком, то расчет очень простой – просто проверяем все клетки между игроком и целью, изменяя другую, отличающую координату.
В случае отличающихся обеих координат, приходится вспоминать школьный курс, и что уравнение прямой y = k*x + b, у нас есть две точки (координаты игрока и координаты цели), по которым легко можно вычислить k ((sy-dy)/(sx-dx)) и b ( sy-k*sx).

Далее рассчитываем минимальную координату (выбираем меньшее из sx и dx) и по циклу узнаем координату Y, по уравнению, затем узнаем есть ли на этой точки любое существо, и если есть возвращаем его как цель.
Считаем, что стрела не может пролететь через существо, если то стоит на его пути, т.е. одно, может закрыть другое

Проверка на видимость цели – попроще, воспользуемся уже готовой функцией makeSignMap, которая получает видимую карту и узнаем значение в нужной нам точке (dx,dy) – если точка видима, то, как цель она подходит.

При выстреле уменьшается прочность предмета (количество стрел) c->inventory[INV_LHAND]--.

Конечно, все такие проверки будут и в клиентской части (количество стрел, видимость цели), однако дополнительные проверки никому не помещают, особенно для «самых умных».