-
Постов
178 -
Зарегистрирован
-
Посещение
-
Победитель дней
24
Сообщения, опубликованные Nurkz
-
-
Ну во первых в участке кода
if (mob->lookup_const(mobt, "DamageMotion", &i32) && i32 >= 0) { if (battle_config.monster_damage_delay_rate != 100) md.status.dmotion = i32 * battle_config.monster_damage_delay_rate / 100; else md.status.dmotion = i32; }
нужно добавить проверку, считается ли моб боссом
if (mob->lookup_const(mobt, "DamageMotion", &i32) && i32 >= 0) { if (!(md.status.mode & MD_BOSS) && battle_config.monster_damage_delay_rate != 100) md.status.dmotion = i32 * battle_config.monster_damage_delay_rate / 100; else md.status.dmotion = i32; }
и далее после участка кода
// MVP EXP Bonus: MEXP if (mob->lookup_const(mobt, "MvpExp", &i32) && i32 >= 0) { // Some new MVP's MEXP multiple by high exp-rate cause overflow. [LuzZza] int64 exp = apply_percentrate64(i32, battle_config.mvp_exp_rate, 100); md.mexp = (unsigned int)cap_value(exp, 0, UINT_MAX); }
добавляем
if ((md.status.mode & MD_BOSS)) { if (md.mexp == 0 && battle_config.boss_damage_delay_rate != 100) md.status.dmotion = md.status.dmotion * battle_config.boss_damage_delay_rate / 100; else if (md.mexp > 0 && battle_config.mvp_damage_delay_rate != 100) md.status.dmotion = md.status.dmotion * battle_config.mvp_damage_delay_rate / 100; else if (battle_config.monster_damage_delay_rate != 100) md.status.dmotion = md.status.dmotion * battle_config.monster_damage_delay_rate / 100; }
- 2
-
У вас на 678 строке происходит декрементация idx и дальнейшая работа с ним, а в 676 строке idx не декрементирован
-
3 часа назад, Ultima сказал:
А можно продемонстрировать, как сделаешь это ты?)
или получается, что такой напарник никому не нужен.
( на самом деле мне просто интересно посмотреть, а ещё больше захапать к себе эту модификацию )- 4
-
8 часов назад, Кеник сказал:
А я нашел косяк
Нет ты ничего не видел
-
Сам думал о такой идее, но все упиралось во время. Нужна будет любая помощь, можете писать
Тоже интересно, на чем пишете?
Пс. На open-source проект пойдёт куда быстрее.
-
1 час назад, gloom_lie сказал:
Старая сборка еамода (2011-2012г.) со старой механикой идеально подходит для нынешней русско-язычной аудитории и более менее стабильна. При должных навыках, все баги правятся быстро. Как мне известно таковая стояла на тервисте и его предшественниках, жалоб не было. Но проблема здесь в другом, новые версии клиентов скорее всего будут несовместимы с этим эмулятором.
Вы правы, но очень многое было переписано, можно считать это был своего рода эксклюзив. И всё же, за основу брался старенький еАмод. =) Но были и свои проблемы, недочеты, поэтому мы недавно перешли на Herc.
-
Глянул, в последних ра проверку из clif_parse_loadEndAck засунули в src/map/pc.c функция pc_setpos
for( i = 0; i < EQI_MAX; i++ ) { if( sd->equip_index[i] >= 0 ) if( pc_isequip(sd,sd->equip_index[i]) ) pc_unequipitem(sd,sd->equip_index[i],2); }
Ну и в src/map/map.c функция map_quit
for (i = 0; i < EQI_MAX; i++) { if (sd->equip_index[i] >= 0) if (pc_isequip(sd,sd->equip_index[i])) pc_unequipitem(sd,sd->equip_index[i],2); }
В обоих случаях просто заменить на банальное.
for (i = 0; i < EQI_MAX; i++) { if (sd->equip_index[i] >= 0) { if ((sd->class_ & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level > 96) continue; if (pc_isequip(sd,sd->equip_index[i])) pc_unequipitem(sd,sd->equip_index[i],2); } }
Не идеально, но сойдет.
- 2
-
Отключи проверку предметов для снов 99-го, pc_checkequip вроде. Или если нужно только при смене карты, clif_parse_LoadEndAck
- 1
-
- 2
-
@Kubix! Напиши в пм, есть желание затестить YARL.
-
Ребят, внедрение внешних программ запрещено =)
Скрытый текст -
К - Качество! Или как не надо пользоваться "гуглтранслейтом"..
ПС! Фаталити!
Скрытый текстПростите, не удержался =)
-
По теме как надо косить под руофф - https://oldro.me/
Ребята, которые смогли, но их жадность их же и погубила.
-
8 часов назад, Salfer сказал:
Так-то ты написал, но кое чего не хватает =D
Ох, я и забыл что мне далеко до уровня написания кода здешнего уровня.
Ну поведайте нам чего же не хватает ?
-
Скрытый текст
ACMD(jumptoseller) { struct map_session_data *pl_sd = NULL; char *mapname = "prontera"; nullpo_retr(false, sd); memset(atcmd_player_name, 0, sizeof(atcmd_player_name)); if (!*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { clif->message(fd, "Please enter a player name (usage: @jumptoseller <char name>"); return false; } if (sd->mapindex != mapindex->name2id(mapname)) clif->message(fd, "You are not authorized to warp from your current map."); return false; } if (pc_isdead(sd)) { clif->message(fd, "You cannot use this command when dead."); return false; } if ((pl_sd = map->nick2sd(atcmd_player_name)) == NULL) { clif->message(fd, "Character not found."); return false; } if (pl_sd->mapindex != mapindex->name2id(mapname)) clif->message(fd, "You can't jump to this seller/buyer."); return false; } if (!pl_sd->state.vending && !pl_sd->state.buyingstore) clif->message(fd, "Followed character is not a seller/buyer."); return false; } if (pl_sd == sd || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) { clif->message(fd, "You already are at your destination!"); return false; } pc->setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT); safesnprintf(atcmd_output, sizeof(atcmd_output), "Jumped to %s (x=%d, y=%d)", pl_sd->status.name, pl_sd->bl.x, pl_sd->bl.y); clif->message(fd, atcmd_output); return true; }
ACMD_DEF(jumptoseller),
- 1
-
Сделаю за 10$
- 1
-
Ничего у них не выгорит, опыта 0, навыков 0, денег.. 0? Короче, не доживет и до открытия, нечего тут обсуждать.
Никогда не отписывался в подобных темах, но с названия пригорело, сам начинал свой путь с руоффа, помню как это было.
- 1
-
смените кодировку на utf8
-
Если будет нужно что, пиши телеграм @Nurkz, помогу по мере свободного времени
- 1
-
Чет у вас тут страсти
-
5 часов назад, Collapse сказал:
status_calc_misc(&nd->bl, &nd->status, nd->level);
Извиняюсь =)
Еще было бы правильно поправить status_get_status_data и status_get_base_status.
Обновил пост выше.
- 1
-
В rA и Herc уже можно давным давно давать статы нпсам, но если у нас eAthena, ничего страшного, всегда можно стырить =)
Ну во первых изменим в src/map/script.c функции unitskilluseid и unitskillusepos
Меняем в функции unitskilluseid:
if( bl != NULL ) unit_skilluse_id(bl, target_id, skill_id, skill_lv);
На:
if (bl != NULL) { if (bl->type == BL_NPC) { if (!((TBL_NPC*)bl)->status.hp) status_calc_npc(((TBL_NPC*)bl), true); else status_calc_npc(((TBL_NPC*)bl), false); } unit_skilluse_id(bl, target_id, skill_id, skill_lv); }
И в unitskillusepos:
if( bl != NULL ) unit_skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv);
На:
if (bl != NULL) { if (bl->type == BL_NPC) { if (!((TBL_NPC*)bl)->status.hp) status_calc_npc(((TBL_NPC*)bl), true); else status_calc_npc(((TBL_NPC*)bl), false); } unit_skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv); }
Далее добавим функцию добавления статов нпсу =)
BUILDIN_FUNC(setnpcstats) { TBL_NPC* nd = NULL; unsigned int value = 0; if (script_hasdata(st,2)) nd = map_id2nd(script_getnum(st,2)); else nd = map_id2nd(st->oid); if (nd == NULL) return 0; if (script_hasdata(st,3)) value = script_getnum(st,3); if (!nd->status.hp) status_calc_npc(nd, true); else status_calc_npc(nd, false); break; nd->stat_point = value > 0 ? value : 999; status_calc_misc(&nd->bl, &nd->status, nd->level); }
и ниже описываем что она будет принимать: (Всего два необязательных параметра)
BUILDIN_DEF(setnpcstats,"??"),
Далее идем в src/map/status.c и функцию status_calc_bl_
в свиче добавляем новый кейс которым будет выглядеть данным образом:
case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), first); break;
Далее ищем status_get_status_data и добавляем:
case BL_NPC: return ((mobdb_checkid(((TBL_NPC*)bl)->class_) == 0) ? &((TBL_NPC*)bl)->status : &dummy_status);
То же самое ниже в status_get_base_status:
case BL_NPC: return ((mobdb_checkid(((TBL_NPC*)bl)->class_) == 0) ? &((TBL_NPC*)bl)->status : NULL);
И добавляем функцию status_calc_npc_:
int status_calc_npc_(struct npc_data *nd, bool first) { struct status_data *status = &nd->status; if (!nd) return 0; if (first) { status->hp = 1; status->sp = 1; status->max_hp = 1; status->max_sp = 1; status->def_ele = ELE_NEUTRAL; status->ele_lv = 1; status->race = RC_DEMIHUMAN; status->size = nd->size; status->rhw.range = 1 + status->size; status->mode = (MD_CANMOVE|MD_CANATTACK); status->speed = nd->speed; } status->str = nd->stat_point + nd->params.str; status->agi = nd->stat_point + nd->params.agi; status->vit = nd->stat_point + nd->params.vit; status->int_= nd->stat_point + nd->params.int_; status->dex = nd->stat_point + nd->params.dex; status->luk = nd->stat_point + nd->params.luk; status_calc_misc(&nd->bl, status, nd->level); status_cpy(&nd->status, status); return 0; }
Далее заходим в src/map/status.h
В самом верху песле строчки:
struct mercenary_data;
Добавляем:
struct npc_data;
Листаем в самый низ и находим:
#define status_calc_mercenary(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first)
Добавляем следующей строчкой:
#define status_calc_npc(nd, first) status_calc_bl_(&(nd)->bl, SCB_ALL, first)
Ниже видим:
int status_calc_mercenary_(struct mercenary_data *md, bool first);
Добавляем:
int status_calc_npc_(struct npc_data *nd, bool first);
Далее идём в src/map/npc.h и видим строчку:
unsigned size : 2;
Ниже добавляем:
struct status_data status; unsigned int level,stat_point; struct s_npc_params { unsigned short str, agi, vit, int_, dex, luk; } params;
Вот вроде и всё, рекомпилим и пишем в скрипте:
getmapxy .@map$, .@x, .@y, 1; setnpcstats getnpcid(0), 999; unitskillusepos getnpcid(0), WZ_METEOR, 10, .@x, .@y;
ПС! Хотя я бы всё же рекомендовал перейти на rA/Herc и использовать setunitdata.
Может кому нужно будет, пусть будет.
- 1
-
1 час назад, Gandalf сказал:
Вряд ли как - то можно убить мобов скиллом нпца, у нпца нет статов и вообще ничего, даже команды на использование скилла в eAthena, насколько я помню.
Можно запустить эффект и юзнуть killmonsterall какой-нибудь.А почему бы не дать нпцу статов?)
-
Скажите ревизию rA или лучше выложите эмулятор.
здарова гомики
в Флуд
Опубликовано