Поиск сообщества
Показаны результаты для тегов 'neotemple'.
Найдено: 1 результат
-
[sRC] Демонические монстры Все играли в Diablo 2 надеюсь... История изменений 2015.09.4: - Обновлено для версии сервера 2015.08.10: исправления, улучшения - Переработан баланс награды, опыта и усилений монстров - Исправлены критические ошибки, которые могли вызывать вылет клиента 2013.02.21: - Значительно усилены и доработаны параметры демонического монстра - Улучшены и доработаны вознаграждения по опыту и предметам Описание Демонические монстры — это обычные монстры, но усиленные и озлобленные на игрока. На карте они генерятся из уже существующих с выбранным вами шансом (настраивается скриптами). За их убийство вы получаете больше опыта и шанс выпадения предметов из них значительно выше. Скриншот Установка В src править придётся несколько файлов. Начнём с src/map/mob.h, находим: unsigned int size : 2; Добавляем перед: unsigned int demonic; /* NeoTemple Extra Demonic Mob */ Это дополнительный статус отвечающий то, что монстр Демонический (на самом деле в этой переменной мы будем хранить разницу между оригинальным уровнем моба и демоническим). Теперь правим src/map/mob.c #include "map.h" Добавляем перед: #include "mapreg.h" Находим: if (data->state.ai) md->special_state.ai = data->state.ai; Добавляем перед (на самом деле это необязательно, но всегда обнуляйте переменные!): md->special_state.demonic = 0; Дальше находим: if(md->db->option) // Added for carts, falcons and pecos for cloned monsters. [Valaris] md->sc.option = md->db->option; Добавляем после: /* NeoTemple Extra Demonic Mob */ md->special_state.demonic = 0; // It's not Demonic now if( !(md->status.mode&MD_BOSS || md->status.mode&MD_PLANT || md->status.mode&MD_NODEMONIC || md->mob_id == MOBID_EMPERIUM || mob_is_battleground(md)) ) { int min_mob_level = mapreg_readreg( add_str("$demonicminlevel") ); if( md->level >= min_mob_level ) { int chance_rate = mapreg_readreg( add_str("$demonicrate") ); if( rnd()%10000 <= chance_rate ) { int list_num, demonic_match = 0, max_tick = -1; // tick = -1 is infinity tick // Проверяем режим карты и запрещённых/разрешённых мобов // 1 - только указанные в списке мобы могут стать демоническими // 0 - указанные в списке мобы не могут быть демоническими // Примечание: // Проверка этого списка явно тяжелее чем прогрузка параметров и вычисление шанса, // поэтому делаем эту проверку уже в самом конце for( list_num = 0; list_num < MAX_MAP_LIST; list_num++ ) { if( !map[md->bl.m].demonic_mobid[list_num] ) { break; // Всегда считаем 0 окончанием списка (накосячили с прописыванием списка мобов - ваши проблемы!) } if( md->mob_id == map[md->bl.m].demonic_mobid[list_num] ) { demonic_match = 1; break; // Достаточно одного совпадения в любом случае } } if( (map[md->bl.m].flag.demonicdisabled && demonic_match) || (!map[md->bl.m].flag.demonicdisabled && !demonic_match) ) { md->special_state.demonic = 10+5*(rnd()%9); // Храним не то, что моб Демонический, а его разницу в уровне с оригиналом // Пригодится при расчёте шанса выпадения md->level += md->special_state.demonic; status_calc_mob(md, SCO_NONE); // Update mob data status_percent_heal(&md->bl, 100, 0); // Heal 100% md->level = md->db->lv + (md->special_state.demonic/5); md->status.flee = (short) (md->db->status.flee+(md->status.flee-md->db->status.flee)/2); sc_start(&md->bl, &md->bl, SC_ASPDPOTION2, 100, 9, max_tick); sc_start(&md->bl, &md->bl, SC_SPEEDUP1, 100, 8, max_tick); sc_start(&md->bl, &md->bl, SC_ENDURE, 100, 8, max_tick); sc_start4(&md->bl, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_ANGRY, 0, -1); // Anyway create aggressive and angry mob md->status.hit += (short) (md->special_state.demonic/1.5); md->status.rhw.atk = md->status.rhw.atk*(125+md->special_state.demonic)/100; md->status.rhw.atk2 = md->status.rhw.atk*(125+md->special_state.demonic)/100; } } // rnd()%10000 } // md->level } // if( !(md->status.mode&MD_BOSS /* --------------- */ Это основной процесс создания Демонического монстра. Тут всё немного сложно, но если вкратце, то для начала мы проверяем некоторые состояния моба. Если это растение или Босс, то он никогда не станет Демоническим (хотя агрессивная трава это было бы весело), так же не может быть Империум (это моб, кстати, тут ещё было бы неплохо сделать проверку на сокровищницу и стражников), ещё на BG так же не может быть Демонических мобов. Остальные проверки касаются дополнительных настроек — о них чуть позже. Сам Демонический монстр — это более прокаченная версия обычного, достигается это засчёт повышения его уровня, у меня сделано повышение кратное 5, минимально уровень выше на 10, максимально на 50. Затем пропорционально уровню повышаются статы (Agi, Dex, Str, Vit, Luk). Отображаемый уровень монстра мы увеличиваем максимум на 10 уровней (каждый 5 уровней разницы всего на 1 уровень отображения). Это необходимо, чтобы монстр был в механике Renewal'а по вычислению опыта. В самом конце моб делается агрессивным и злобным, на него накладывается некоторые статы для усиления - ENDURE, увеличение ASPD и увеличение скорости передвижения. Так же увеличиваем HIT монстра и его базовые ATK и ATK2. Теперь Демонический монстр действительно получился сильным. Продолжаем, находим: if (drop_rate <= 0) { if (battle_config.drop_rate0item) continue; drop_rate = 1; } Добавляем после: /* NeoTemple Extra Demonic Mob */ if( md->special_state.demonic && drop_rate <= 2500 ) { double rate = drop_rate; double adjust_rate = (log(md->special_state.demonic)*100)/2; rate = rate * pow((5.0 - log10(rate)), (log(adjust_rate/100.) / log(5.0))) + 0.5; drop_rate = (unsigned int)cap_value(rate, 0, 7500); } /* ------------------ */ Это процесс вычисления нового шанса выпадения предметов, он использует код логарифмических рейтов. Шанс выпадения не может быть выше 75%. В расчёт берутся только предметы чей шанс выпадения ниже 25%. Повышающие рейты вычисляются относительно разницы уровня оригинального монстра и демонического. Чем ниже шанс выпадения предмета, тем выше его новые рейты на выпадение. Улучшаем по опыту, находим: if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris] bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate; Заменяем на: // NeoTemple Extra Demonic Mob if( md->special_state.demonic ) { bonus += (int)(25.*log(md->special_state.demonic)); } else { if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris] bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate; } Теперь за демонических монстров будет действительно приятное вознаграждение. Кол-во опыта так же вычисляется логарифмически. Идём дальше в src/map/status.h, находим: MD_NOCAST_SKILL = 0x800000, Добавляем после: MD_NODEMONIC = 0x40000000, // NeoTemple Extra Demonic Mob Это особый режим монстра, который можно прописывать в db/re/mob_db.txt указывая в поле Mode, к примеру, вот так выглядит запись Poring'а: 1002,PORING,Poring,Poring,1,60,1,27,20,1,8,9,2,5,6,1,1,0,6,5,10,12,1,3,21,0x83,400,1872,672,480,0,0,0,0,0,0,0,909,7000,1202,100,938,400,512,1000,713,1500,512,150,619,20,0,0,0,0,4001,1 Если указать этот режим, то моб никогда не будет Демоническим. Пример Poring'а после модификации: 1002,PORING,Poring,Poring,1,60,1,27,20,1,8,9,2,5,6,1,1,0,6,5,10,12,1,3,21,0x40000083,400,1872,672,480,0,0,0,0,0,0,0,909,7000,1202,100,938,400,512,1000,713,1500,512,150,619,20,0,0,0,0,4001,1 Учтите, что этот участок исходников может отличаться в разных версиях, будьте внимательны или выбирайте флаг Демонических монстров максимально большим. Теперь правим src/map/map.h, находим: struct map_flag { Добавляем перед: int demonic_mobid[MAX_MAP_LIST]; // NeoTemple Extra Demonic Mob Добавляем после: unsigned demonicdisabled : 1; // NeoTemple Extra Demonic Mob Находим тут же: #define MAX_MAP_SIZE 512*512 // Wasn't there something like this already? Can't find it.. [Shinryo] Добавляем после: #define MAX_MAP_LIST 32 Ещё правим src/map/npc.c, находим: else if (!strcmpi(w3,"autotrade")) Добавляем перед: // ----------- NeoTemple Extra Demonic Mob else if (!strcmpi(w3,"demonicdisabled")) { char *demonic_param = NULL; int demonic_mobid_restriction = 0, demonic_count = 0, demonic_type = 1; // demonic_type: 1 - allow only mob id in list, 0 - deny mob id in list // Always default 1, because is type set to "allow only" mode // First read allow/deny, or may be it's short type of mapflag? demonic_param = strtok(w4, " ,.-"); if( demonic_param != NULL ) { if( !strcmpi(demonic_param, "deny") ) { demonic_type = 0; // Deny mode } do { demonic_param = strtok(NULL, " ,.-"); if( demonic_param == NULL ) { break; // Read last param } demonic_mobid_restriction = atoi(demonic_param); // No need to check this mob id, if it numeric(?!) - it's always correct map[m].demonic_mobid[demonic_count] = demonic_mobid_restriction; demonic_count++; } while( 1 ); } // if demonic_param != NULL map[m].flag.demonicdisabled = demonic_type; // at last set mapflag } // if strcmpi demonicdisabled // ----------- End of NeoTemple Extra Demonic Mob Данный кусок создаёт дополнительный mapflag, который указывает на каких картах не могут появляться демонические монстры. Пример: prt_fild08 mapflag demonicdisabled Можно так же указывать списки разрешённых и запрещённых мобов для появления, пример: prt_fild08 mapflag demonicdisabled deny,1002 На карте prt_fild08 моб с id 1002 (Поринг) не может стать Демоническим, или можно вот так: prt_fild08 mapflag demonicdisabled allow,1002 В таком случае только моб с id 1002 (Поринг) может стать Демоническим. В списках через ","(запятую) можно указывать несколько мобов, максимум можно указать 32 id моба (?! мало будет добавите в MAX_MAP_LIST, но знайте - вы упоролись) Необходимо ещё исправить src/map/map.c, находим: memset(map[i].drop_list, 0, sizeof(map[i].drop_list)); // pvp nightmare drop list Добавляем после: memset(map[i].demonic_mobid, 0, sizeof(map[i].demonic_mobid)); // NeoTemple Extra Demonic Mob Теперь очень важное исправление src/map/status.c, находим: if (battle_config.mobs_level_up && md->level > md->db->lv) И заменяем на: if ( (battle_config.mobs_level_up && md->level > md->db->lv) || md->special_state.demonic) /* NeoTemple Extra Demonic Mob */ Это исправление необходимо для создания усиленных версий, то есть Демонических монстров с повышенными значениями статов. Итак, тут мы закончили, следующие исправления несут только декоративный характер, к тому же незначительно нагружают интернет канал. Если вы считаете, что декор вам не нужен или у вас сильно ограничен канал(?!), то пропустите следующие исправления. Работаем с src/map/cliff.c, находим: if(md->special_state.size==SZ_BIG) // tiny/big mobs[Valaris] clif_specialeffect(&md->bl,423,AREA); Добавляем перед: /* NeoTemple Extra Mobs - Demonic */ if( md->special_state.demonic ) { clif_specialeffect(&md->bl, 680, AREA); } /* --------------- */ Данную процедуру выполяем 2 раза (ДВА РАЗА), то есть вносим два испрваления(!!!) — два раза поиск и два раза вставка. Там же находим: if(md->special_state.size==SZ_BIG) // tiny/big mobs[Valaris] clif_specialeffect_single(bl,423,sd->fd); И добавляем перед: if( md->special_state.demonic ) { clif_specialeffect_single(&md->bl, 680, sd->fd); } Данный фикс добавит красивую зелёную ауру у Демонических монстров. Теперь, для того, чтобы исправление начало полноценно работать нам нужно сделать скрипт, который будет устанавливать некоторые параметры работы фикса. Вот самый простой скрипт: - script DemonicMob -1,{ OnInit: set $demonicrate, 5000; set $demonicminlevel, 1; end; } Этот скрипт просто устанавливает параметры по которым будут создаваться Демонические монстры. — $demonicrate - шанс появления монстров (10000 - 100%) — $demonicminlevel - какой минимальный уровень мобов необходим для появления Демонического монстра (если уровень моба ниже указанного, то он никогда не станет Демоническим) В своих скриптах вы можете делать интересные ивенты или в ночное время увеличивать шанс появления подобных монстров. Вы так же можете сами указывать различные параметры Демонических монстров внося исправления в src. У меня сделано, что монстры могут быть выше от 10 до 50 уровней, но это число можно менять, учтите, что монстры достаточно сильными становятся при повышении уровня. todo (Что нужно сделать) — Сделать в mapflag указание рейтов появления Демонического монстра: mapflag demonicdisabled <type>,<rate>,<...> — Сделать кеширование считывания глобальных переменных ($demonicrate и $demonicminlevel) для уменьшения нагрузки — Сделать модфикс в виде .patch файлика Описание для старой версии rA.