Terraria лицензия, потому смещения и адреса на репаках могут отличатся.
Для начала, нам нужно найти все необходимые адреса, как это сделать думаю понятно, адрес игрока можно найти по здоровью и сделать указатель на него. У меня получился вот такой указатель:
Для вставки в скрипт: [[[Terraria.Main::DoDraw+375]]+08+[[Terraria.Main::DoDraw+37B]]*4]
Принцип такого указателя: В Terraria.Main::DoDraw+375 в коде вписан адрес структуры с игроками
Таким образом в Terraria.Main::DoDraw+37B записан адрес хранящий номер активного игрока
Далее идет прибавление +08 до первого элемента, потом номер игрока умножается на 4, так как 1 адрес занимает 4 байта, вот и получается адрес игрока.
Теперь необходимо найти структуру содержащую адреса существ, думаю это тоже понятно как найти, у меня вот такой адрес:
Для вставки в скрипт: [[Terraria.Main::UpdateAudio+4F7]], по такому же принципу как и 2 адреса сверху.
Теперь мы можем начать писать скрипт коллизии, суть скрипта в организации проверок координат касания углов персонажа и координат углов существа.
Вот примерная схема этого действа:
Желтым изображены виртуальные полигоны коллизии, то есть промежутки в которых скрипт делает проверку, попадает ли точка игрока в них.
Самый верхний желтый полигон используется для другой проверки, о которой будет сказано ниже.
Итак, у нас есть адрес игрока, и предположительно адрес существа, для проверки существ нужно сделать цикл, перебирающий их и проверяющий координаты каждого:
Как тут указано, тут так же проверяется совпадение адреса существа в цикле с адресом существа для которого делается коллизия, это сделано для того что бы не было самоколлизии, то есть столкновения существа с самим собой. Так же имеется проверка на активность, есть ли вообще этот объект, или он отсутствует или отключен.
Теперь, так как у нас имеется цикл перебора существ, мы можем сделать вычисление крайних точек существа.
Координаты существа в игре - это его крайняя левая нижняя точка. Так же у существа есть размер, и исходя из этих данных игра центрирует точку координат перед выводом существа на позицию в карте. Координаты в структуре существа отображают именно крайнюю левую нижнюю точку.
Делаем вычисления после цикла и записываем в метки координаты точек и расстояние:
Теперь можно написать проверки.
Данный код проверяет положение точек 1 существа, относительно другого, при этом проверяется как X так и Y, иначе коллизия будет размером во всю карту, а не только по размерам существа, из за этого в каждом блоке по 4 проверки. После проверок в метку записывается состояние персонажа, слева он, сверху, справа или снизу.
Следующий код делает проверку значения записанного в метку 1/2 1/2 и относительно этого выполняет действия с персонажем, убавляет его координаты или прибавляет на еденичку, создавая таким образом координатную коллизию, не пропускающую игрока сквозь существо.
После выполнения данного скрипта, мы получаем коллизию, с учетом того, что если существо выше персонажа или наоборот, то персонаж или существо не будут вдавливать друг друга в землю, а вот толкнуть вверх могут.
Теперь о том, зачем было использовать в скрипте полигон коллизии расположенный в самом верху. Если игрок попадает в тот полигон своей нижней стороной, то в таком случае делается проверка и в метку записывается значение:
Если сделать скрипт без этой проверки, то персонаж на существе стоять не будет, то есть он будет висеть на нем с анимацией падения, и при слезании получит огромный урон, так как считается что он падает. Что бы избежать такого недоразумения находим функцию проверяющую стоит игрок на земле или нет, и вот как раз тут и пригодится нам наш полигон коллизии. В функцию делаем инъекцию кода параллельно с основным:
Таким образом персонаж будет стоять на существе как на земле, и при слезании не получит огромный урон.
В скрипте так же имеются проверки на тип существа, и изменение его проверочного размера.
Вот такой вот получается скрипт целиком:
Этот скрипт должен на входе получить адрес структуры для проверки. Он выполняется 2 раза, 1 раз делает коллизию игроку, а 2 раз делает коллизию тому адрес чего получен дальше. В моём случае этот адрес - адрес существа. Этот скрипт вызывается другим скриптом с потоком:
Вот эти сложные махинации создают коллизию между игроком и существами, и между самими существами.
Картинки работы:
Скрипт работает - существа не могут пройти сквозь друг друга и игрока:
Скрипт отключён: