BaH_Warn |
Дата: Понедельник, 25.05.2015, 07:10 | Сообщение # 1
|
Боец
Сообщений: 69
Статус: Offline
|
Приветствую! Сегодня я постараюсь вам рассказать, как можно сделать солидную системку при использовании не сложных, а самое главное понятных алгоритмов. Система позволяет вам проколоть колесо машины и тем самым помочь отыграть РП ситуацию. Также можно произвести небольшие изменения в системе и заставить систему уже не ломать колёса, а чинить! Тем самым Вы прекрасно преобразите работу механика на своём проекте.
Небольшое вступление:
Разработчики сделали эту систему в виде двоичного числа: у нас 4 колеса и следовательно у нас 2^4 комбинаций, а из школьного курса информатики мы знаем, что в комбинациях от 0b0000 до 0b1111 ровно 16 комбинаций. Как вы уже должны догадываться, что 4 числа у нас не просто так. Каждое число соответствует своему колесу. Например, если мы запишем в переменную с колёсами число 0b0001, то это будет обозначать, что проколото заднее правое колесо (от водителя): Пояснение: тут "х" - проколотое колесо
И следовательно алгоритм действий очень прост: нам нужно разложить число на "0" и "1" и просто проверить. Если "0", то проколоть, иначе - сказать об неверном действии игроку (пользвателю). Реализация алгоритма представлена ниже Код команды: Код CMD:useneedle(playerid, params[]) { if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, COLOR_GREY, "Вы не можете сделать это из машины"); new vehicleid = GetVehicleByPlayer(playerid); if(vehicleid == -1) return SendClientMessage(playerid, COLOR_GREY, "Вы не рядом с машиной"); new tire = GetTireByPlayer(playerid, vehicleid); if(tire == -1) return SendClientMessage(playerid, COLOR_GREY, "Вы не у колеса"); new Panel, Door, Light, Tires; if(Tires != 0) return SendClientMessage(playerid, COLOR_GREY, "У этой машины уже проколото колесо"); GetVehicleDamageStatus(vehicleid, Panel, Door, Light, Tires); //Получаем информацию о состоянии деталей машины new bool:tirestatus[4]; // Создаём переменные со статусом new Tires_temp = Tires; //Нужна переменная для перевода её в двоичную систему for(new i = 0; i < 4; i++) // цикл для перевода в двоичную систему смотреть [I]пометку 1[/I] ниже { if(Tires_temp % 2 == 1) tirestatus[i] = true; Tires_temp = Tires_temp / 2; } switch (tire) //Смотри пометку 2 ниже { case 4: { if(tirestatus[0]) return SendClientMessage(playerid, COLOR_GREY, "Колесо уже проколото"); Tires += 0b1000; } case 3: { if(tirestatus[1]) return SendClientMessage(playerid, COLOR_GREY, "Колесо уже проколото"); Tires += 0b0100; } case 2: { if(tirestatus[2]) return SendClientMessage(playerid, COLOR_GREY, "Колесо уже проколото"); Tires += 0b0010; } case 1: { if(tirestatus[3]) return SendClientMessage(playerid, COLOR_GREY, "Колесо уже проколото"); Tires += 0b0001; } } UpdateVehicleDamageStatus(vehicleid, Panel, Door, Light, Tires); // Сохраняем статус авто return 1; } Коды функций: Код //Нам нужна машина ближайшая к игроку stock GetVehicleByPlayer(playerid) //вернёт ид авто в радиусе 2.5, если авто нет, то вернёт -1 { new vehicleid = -1; new Float:carX, Float:carY, Float:carZ; for(new i = 0; i < MAX_VEHICLES; i++) { GetVehiclePos(i, carX, carY, carZ); if(IsPlayerInRangeOfPoint(playerid, 2.4, carX, carY,carZ)) { vehicleid = i; break; } } return vehicleid; } Помимо машины, нам нужно и колесо. Высчитывал на среднем значении нескольких, разных по размеру машин. Код stock GetTireByPlayer(playerid, vehicleid) { new Float:x, Float:y, Float:z, Float:carX, Float:carY, Float:carZ; GetPlayerPos(playerid, x, y, z); GetVehiclePos(vehicleid, carX, carY, carZ); new totalX; totalX = floatround(x - carX, floatround_floor); new totalY; totalY = floatround(y- carY, floatround_floor); //более точный вариант /*if ((1.45 <= totalX <= 1.5) && (-2.0 <= totalY <= -1.95)) return 1; // 1 else if ((1.52 <= totalX <= 1.57) && (1.56 <= totalY <= 1.61)) return 2; //2 else if ((-1.56 <= totalX <= -1.51) && (-173 <= totalY <= -1.68)) return 3; //3 else if ((-1.46 <= totalX <= -1.41) && (1.87 <= totalY <= 1.92)) return 4; //4 else return -1;*/
//логически ужасный вариант, но работает. Его надо просто принять таким. if ((totalX >= 1) && (totalY <= -1)) return 1; // 1 else if ((totalX >= 1) && (totalY >= 1)) return 2; //2 else if ((totalX <= -1) && (totalY <= -1)) return 3; //3 else if ((totalX <= -1) && (totalY >= 1)) return 4; //4 else return -1; } Пометка [1]:
Делим число на основание системы счисления и записываем остатки - вот так переводится число из десятичной в любую. Тут мы делим число на 2 и проверяем на остатки. Так как в 2ой системе есть 0 и 1, а т.е. либо делится нацело (без остатка), либо остаток 1, который будет обозначать, что оно занято.
Пометка [2]:
Тут мы уже знаем колесо, с которым работает игрок и просто прибавляем число в двоичной системе! Т.е. 0b0101 + 0b1010 = 1111 проще говоря "производим наложение" Кстати. Проверка перед сложением позволяет избежать наложения 1 на 1, что в результате будет давать 0. Подведём итоги:
Если что-то не понятно, то приношу свои искренние извинения, так как старался объяснить всё примитивно и понятно. Для спецов: Коллеги, прошу не обращать внимания на чересчур примитивный код. Данный код подстраивался под начинающего кодера и несёт в себе исключительно типизированные конструкции.
|
|
|
|
[CM]Enrique |
Дата: Четверг, 28.05.2015, 12:29 | Сообщение # 2
|
Любитель
Сообщений: 42
Статус: Offline
|
Спасибо)
|
|
|
|