21 сообщение в этой теме

Здравствуйте, сделала нпц и фантазия заставила нпцеху запускать скилы. Мне нужно что бы в определенный момент нпц запустило метеор и убило вокруг меня всех мобов. Подскажите пожалуйста можно ли как то это воплотить в жизнь на eathena. 

Изменено пользователем E r a
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Надо прописывать время, и радиус клеток вокруг нпц... Впринципе это возможно

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вряд ли как - то можно убить мобов скиллом нпца, у нпца нет статов и вообще ничего, даже команды на использование скилла в eAthena, насколько я помню.
Можно запустить эффект и юзнуть killmonsterall какой-нибудь.

Изменено пользователем Gandalf
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну я об этом и сказал, что надо настроить время использования команды килмонстералл и добавить еффект метеора в этот момент)

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Gandalf сказал:

Вряд ли как - то можно убить мобов скиллом нпца, у нпца нет статов и вообще ничего, даже команды на использование скилла в eAthena, насколько я помню.
Можно запустить эффект и юзнуть killmonsterall какой-нибудь.

А почему бы не дать нпцу статов?)

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

да но)  killmonsterall  убивает без эффекта, моб просто исчезает, наверно можно добавить эффект при убийстве?. Можно сделать НПЦ через unitskilluseid, unitskillusepos, оно кастует и убивает но присутствует задержка. 

Изменено пользователем E r a
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

///

Изменено пользователем E r a
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
5 часов назад, Nurkz сказал:

А почему бы не дать нпцу статов?)

Вряд ли человек, который спрашивает как сделать эффекты с убийством, сделает статы нпцу )

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
19 минуту назад, Gandalf сказал:

Вряд ли человек, который спрашивает как сделать эффекты с убийством, сделает статы нпцу )

а все же, как?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не знаю, мб придется переписать структуру нпцов, чтоб статы учитывались и тп.
А мб можно просто захардкодить переменные, и сделать скрипт команду npcskill какую-то и учитывать их.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В эмуляторе rAthena у НПЦ есть статы, присутствует скриптовая команда npcskill.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В 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 [email protected]$, [email protected], [email protected], 1;
setnpcstats getnpcid(0), 999;
unitskillusepos getnpcid(0), WZ_METEOR, 10, [email protected], [email protected];

 

ПС! Хотя я бы всё же рекомендовал перейти на rA/Herc и использовать setunitdata.

Может кому нужно будет, пусть будет.

Изменено пользователем Nurkz
1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну я и не говорил что в ра/геркулесе нет статов у нпцов, сам их юзал :)
я писал именно об eAthena.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

например такой скриптик:

zzzz,x,y,5    script    zzzz    zzz,{
  mes "zzzzzz.";
  delitem zzzz,1;
  getitem zzzz,1;
  npcskilleffect zzzz,10,x,y;

killmonsterall "<map name>"{,<type>};
    sleep 500;
    npcskilleffect zzzz,10,x,y;
    sleep 501;
    npcskilleffect zzzz,10,x,y;
    sleep 502;
    npcskilleffect zzzz,10,x,y;
  close;
}

я всовываю не правильно слип и "close;" уже не работает,(

Изменено пользователем E r a
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

попробуй так

 

 zzzz,x,y,5    script    zzzz    zzz,{
  mes "zzzzzz.";
  delitem zzzz,1;
  getitem zzzz,1;
  npcskilleffect zzzz,10,x,y;
  close2;
killmonsterall "<map name>"{,<type>};
    sleep 500;
    npcskilleffect zzzz,10,x,y;
    sleep 501;
    npcskilleffect zzzz,10,x,y;
    sleep 502;
    npcskilleffect zzzz,10,x,y;
  end;
} 

 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

спасибо)

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Скрытый текст
В 05.12.2016в10:50 PM, Nurkz сказал:

В 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 &((TBL_NPC*)bl)->status;

То же самое ниже в status_get_base_status:


case BL_NPC: return &((TBL_NPC*)bl)->status;

И добавляем функцию 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 [email protected]$, [email protected], [email protected], 1;
setnpcstats getnpcid(0), 999;
unitskillusepos getnpcid(0), WZ_METEOR, 10, [email protected], [email protected];

 

ПС! Хотя я бы всё же рекомендовал перейти на rA/Herc и использовать setunitdata.

Может кому нужно будет, пусть будет.

При компиляции получаю ошибку

error: incompatible type for argument 1 of 'status_calc_misc'
  status_calc_misc(nd->bl, &nd->status, nd->level);


 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создай новую тему, раз пишешь по другому вопросу, а вообще по мимо ошибки обычно пишет где именно допущена ошибка.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
4 минуты назад, Salfer сказал:

Создай новую тему, раз пишешь по другому вопросу, а вообще по мимо ошибки обычно пишет где именно допущена ошибка.

Вопрос все тот же. Ошибка в куске 
 

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);
}
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Выложи функцию

status_calc_misc
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
5 часов назад, Collapse сказал:
  Показать содержимое

При компиляции получаю ошибку

error: incompatible type for argument 1 of 'status_calc_misc'
  status_calc_misc(nd->bl, &nd->status, nd->level);


 

status_calc_misc(&nd->bl, &nd->status, nd->level);

Извиняюсь =)

Еще было бы правильно поправить status_get_status_data и status_get_base_status.

Обновил пост выше.

Изменено пользователем Nurkz
1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас