-
Постов
250 -
Зарегистрирован
-
Посещение
-
Победитель дней
119
Сообщения, опубликованные Fox RM
-
-
в эмулятор вводил какие-либо моды? на подобии Tomb (надгробия) , возможно не хватает в grf этого "надгробия".
-
Доброго времени суток, сразу скажу по поводу исходников, нашел мод в своем старом эмуле, соответственно мод написал [ToastOfDoom], под eAthena (в rAthena ,по моему, есть по дефолту этот скрипт.)
Мод включает в себя 3 команды, а именно:
bindatcmd (<atcmd>,<event>);
Да бы каждый раз не править src , в первой строке atcmd - вводите название команды (бинд) , во втором event - название лейбла который будет использовать скрипт нпц. Чтобы все стало понятней, ниже будет рассмотрен пример работы.
unbindatcmd(<atcmd>);
Это позволит удалить все существующие привязки к определенной atcmd.</span><br />
useatcmd(<atcmd string>);
Работает по принципу atcommand() . Более подробный принцип работы увидете ниже, в примере.
Когда atcmd перенаправляется к лейблу, параметры этого atcmd передаются следующими переменными:
. @ atcmd_command $: atcmd который используется.
. @ atcmd_numparameters: количество параметров
. @ atcmd_parameters $ [-]: Параметры, указанные в массиве
Пример:
- script atcmd_sample_inject -1,{
OnInit:
bindatcmd("warp", "atcmd_sample_inject::OnAtCmd");
end;
OnAtCmd:
if(Zeny >= 1000) {
set Zeny, Zeny - 1000;
useatcmd "@warp " + .@atcmd_parameters$[0] + " " + .@atcmd_parameters$[1] + " " + .@atcmd_parameters$[2];
} else {
dispbottom "Sorry... you need at least 1000z to use this service";
}
end;
}Соответственно вводите в игре @warp и в работу включается лейбл OnAtCmd: ,объяснять его работу не буду, т.к все итак понятно.
Непосредственно сам код:
Index: map/atcommand.c
===================================================================
--- map/atcommand.c (revision 15268)
+++ map/atcommand.c (working copy)
@@ -9182,6 +9494,13 @@
return ( info != NULL ) ? info->level : 100; // 100: command can not be used
}
+struct Atcmd_Binding* get_atcommandbind_byname(const char* name)
+{
+ int i;
+ if( *name == atcommand_symbol || *name == charcommand_symbol ) name++; // for backwards compatibility
+ ARR_FIND( 0, ARRAYLENGTH(atcmd_binding), i, strcmp(atcmd_binding[i].command, name) == 0 );
+ return ( i < ARRAYLENGTH(atcmd_binding) ) ? &atcmd_binding[i] : NULL;
+}
/// Executes an at-command.
bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type)
@@ -9287,6 +9607,18 @@
if( sscanf(atcmd_msg, "%99s %99[^\n]", command, params) < 2 )
params[0] = '\0';
+
+ //check for atcmd events
+ if( type == 1 )
+ {
+ Atcmd_Binding * binding = get_atcommandbind_byname(command);
+ if( binding != NULL && binding->npc_event[0] )
+ { //execute event if binded
+ npc_do_atcmd_event((*atcmd_msg == atcommand_symbol) ? sd : ssd, command, params, binding->npc_event);
+ return true;
+ }
+ }
+
//Grab the command information and check for the proper GM level required to use it or if the command exists
info = get_atcommandinfo_byname(command);
if( info == NULL || info->func == NULL || ( type && ((*atcmd_msg == atcommand_symbol && pc_isGM(sd) < info->level) || (*atcmd_msg == charcommand_symbol && pc_isGM(sd) < info->level2)) ) )
Index: map/atcommand.h
===================================================================
--- map/atcommand.h (revision 15268)
+++ map/atcommand.h (working copy)
@@ -45,4 +45,16 @@
int msg_config_read(const char* cfgName);
void do_final_msg(void);
+#define MAX_ATCMD_BINDINGS 100
+
+typedef struct Atcmd_Binding {
+ char command[50];
+ char npc_event[50];
+} Atcmd_Binding;
+
+//At command events
+struct Atcmd_Binding atcmd_binding[MAX_ATCMD_BINDINGS];
+struct Atcmd_Binding* get_atcommandbind_byname(const char* name);
+
+
#endif /* _ATCOMMAND_H_ */
Index: map/npc.c
===================================================================
--- map/npc.c (revision 15268)
+++ map/npc.c (working copy)
@@ -27,6 +27,7 @@
#include "unit.h"
#include "npc.h"
#include "chat.h"
+#include "atcommand.h"
#include <stdio.h>
#include <stdlib.h>
@@ -2649,6 +2715,115 @@
clif_spawn(&nd->bl);// fade in
}
+int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname)
+{
+ struct event_data* ev = (struct event_data*)strdb_get(ev_db, eventname);
+ struct npc_data *nd;
+ struct script_state *st;
+ int i = 0, j = 0, k = 0;
+ char *temp;
+ temp = (char*)aMallocA(strlen(message) + 1);
+
+ nullpo_ret(sd);
+
+ if( ev == NULL || (nd = ev->nd) == NULL )
+ {
+ ShowError("npc_event: event not found [%s]\n", eventname);
+ return 0;
+ }
+
+ if( sd->npc_id != 0 )
+ { // Enqueue the event trigger.
+ int i;
+ ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' );
+ if( i < MAX_EVENTQUEUE )
+ {
+ safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
+ return 0;
+ }
+
+ ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
+ return 1;
+ }
+
+ if( ev->nd->sc.option&OPTION_INVISIBLE )
+ { // Disabled npc, shouldn't trigger event.
+ npc_event_dequeue(sd);
+ return 2;
+ }
+
+ st = script_alloc_state(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
+ setd_sub(st, NULL, ".@atcmd_command$", 0, (void *)command, NULL);
+
+ // split atcmd parameters based on spaces
+ i = 0;
+ j = 0;
+ while( message[i] != '\0' )
+ {
+ if( message[i] == ' ' && k < 127 )
+ {
+ temp[j] = '\0';
+ setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
+ j = 0;
+ ++i;
+ }
+ else
+ temp[j++] = message[i++];
+ }
+
+ temp[j] = '\0';
+ setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
+ setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)k, NULL);
+ aFree(temp);
+
+ run_script_main(st);
+ return 0;
+}
+
/// Parses a function.
/// function%TAB%script%TAB%<function name>%TAB%{<code>}
static const char* npc_parse_function(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
Index: map/npc.h
===================================================================
--- map/npc.h (revision 15268)
+++ map/npc.h (working copy)
@@ -153,7 +164,12 @@
int npc_duplicate4instance(struct npc_data *snd, int m);
int npc_cashshop_buy(struct map_session_data* sd, unsigned int nameid, int amount, int points);
extern struct npc_data* fake_nd;
+// @commands (script-based)
+int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname);
+
+
#endif /* _NPC_H_ */
Index: map/script.c
===================================================================
--- map/script.c (revision 15268)
+++ map/script.c (working copy)
@@ -3821,9 +3823,18 @@
int script_reload()
{
+ int i;
userfunc_db->clear(userfunc_db,do_final_userfunc_sub);
scriptlabel_db->clear(scriptlabel_db, NULL);
+
+ // clear atcmd bindings
+ for( i = 0; i < MAX_ATCMD_BINDINGS; i++ )
+ {
+ safestrncpy(atcmd_binding[i].command, "", 50);
+ safestrncpy(atcmd_binding[i].npc_event, "", 50);
+ }
+
if(sleep_db) {
struct linkdb_node *n = (struct linkdb_node *)sleep_db;
while(n) {
@@ -15417,7 +16577,301 @@
return 0;
}
+BUILDIN_FUNC(bindatcmd)
+{
+ const char* atcmd;
+ const char* eventName;
+ int i = 0;
+
+ atcmd = script_getstr(st,2);
+ eventName = script_getstr(st,3);
+
+ // check if event is already binded
+ ARR_FIND(0, MAX_ATCMD_BINDINGS, i, strcmp(atcmd_binding[i].command,atcmd) == 0);
+ if( i < MAX_ATCMD_BINDINGS )
+ safestrncpy(atcmd_binding[i].npc_event, eventName, 50);
+ else
+ { // make new binding
+ ARR_FIND(0, MAX_ATCMD_BINDINGS, i, atcmd_binding[i].command[0] == '\0');
+ if( i < MAX_ATCMD_BINDINGS )
+ {
+ safestrncpy(atcmd_binding[i].command, atcmd, 50);
+ safestrncpy(atcmd_binding[i].npc_event, eventName, 50);
+ }
+ }
+
+ return 0;
+}
+
+BUILDIN_FUNC(unbindatcmd)
+{
+ const char* atcmd;
+ int i = 0;
+
+ atcmd = script_getstr(st, 2);
+
+ ARR_FIND(0, MAX_ATCMD_BINDINGS, i, strcmp(atcmd_binding[i].command, atcmd) == 0);
+ if( i < MAX_ATCMD_BINDINGS )
+ {
+ safestrncpy(atcmd_binding[i].command, "", 50);
+ safestrncpy(atcmd_binding[i].npc_event, "", 50);
+ }
+
+ return 0;
+}
+
+BUILDIN_FUNC(useatcmd)
+{
+ TBL_PC dummy_sd;
+ TBL_PC* sd;
+ int fd;
+ const char* cmd;
+
+ cmd = script_getstr(st,2);
+
+ if( st->rid )
+ {
+ sd = script_rid2sd(st);
+ fd = sd->fd;
+ }
+ else
+ { // Use a dummy character.
+ sd = &dummy_sd;
+ fd = 0;
+
+ memset(&dummy_sd, 0, sizeof(TBL_PC));
+ if( st->oid )
+ {
+ struct block_list* bl = map_id2bl(st->oid);
+ memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
+ if( bl->type == BL_NPC )
+ safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
+ }
+ }
+
+ // compatibility with previous implementation (deprecated!)
+ if( cmd[0] != atcommand_symbol )
+ {
+ cmd += strlen(sd->status.name);
+ while( *cmd != atcommand_symbol && *cmd != 0 )
+ cmd++;
+ }
+
+ is_atcommand(fd, sd, cmd, 2);
+ return 0;
+}
@@ -15834,5 +17330,23 @@
BUILDIN_DEF(checkquest, "i?"),
BUILDIN_DEF(changequest, "ii"),
BUILDIN_DEF(showevent, "ii"),
+ BUILDIN_DEF(bindatcmd, "ss"),
+ BUILDIN_DEF(unbindatcmd, "s"),
+ BUILDIN_DEF(useatcmd, "s"),
+
{NULL,NULL,NULL},
};
Index: map/script.h
===================================================================
--- map/script.h (revision 15268)
+++ map/script.h (working copy)
@@ -181,5 +182,8 @@
int add_str(const char* p);
const char* get_str(int id);
int script_reload(void);
+//At command events [ToastOfDoom]
+void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct linkdb_node **ref);
#endif /* _SCRIPT_H_ */- 2
-
Заменить это:
Index: map/pc.h
===================================================================
--- map/pc.h (revision 15268)
+++ map/pc.h (working copy)
@@ -84,6 +84,28 @@
unsigned short pos;
};
+//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
+//where the arrows are equipped)
+enum equip_index {
+ EQI_ACC_L = 0,
+ EQI_ACC_R,
+ EQI_SHOES,
+ EQI_GARMENT,
+ EQI_HEAD_LOW,
+ EQI_HEAD_MID,
+ EQI_HEAD_TOP,
+ EQI_ARMOR,
+ EQI_HAND_L,
+ EQI_HAND_R,
+ EQI_MAX_BONUS,
+ EQI_COSTUME_TOP,
+ EQI_COSTUME_MID,
+ EQI_COSTUME_LOW,
+ EQI_COSTUME_GARMENT,
+ EQI_AMMO,
+ EQI_MAX
+};
+
struct map_session_data {
struct block_list bl;
struct unit_data ud;На это:
Index: map/pc.h
===================================================================
--- map/pc.h (revision 15268)
+++ map/pc.h (working copy)
@@ -84,6 +84,28 @@
unsigned short pos;
};
+//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
+//where the arrows are equipped)
+enum equip_index {
+ EQI_ACC_L = 0,
+ EQI_ACC_R,
+ EQI_SHOES,
+ EQI_GARMENT,
+ EQI_HEAD_LOW,
+ EQI_HEAD_MID,
+ EQI_HEAD_TOP,
+ EQI_ARMOR,
+ EQI_HAND_L,
+ EQI_HAND_R,
+ EQI_AMMO,
+ EQI_MAX_BONUS = 10,
+ EQI_COSTUME_TOP,
+ EQI_COSTUME_MID,
+ EQI_COSTUME_LOW,
+ EQI_COSTUME_GARMENT,
+ EQI_MAX
+};
+
struct map_session_data {
struct block_list bl;
struct unit_data ud;- 2
-
Зачем разводить такой срач, появится время ,сегодня - исправлю.
- 1
-
Отсутствуют строки:
int clif_setip(const char* ip)
@@ -1016,6 +1149,7 @@
clif_specialeffect(bl,423,AREA);
else if(sd->state.size==1)
clif_specialeffect(bl,421,AREA);
+ clif_sendauras((TBL_PC*)bl, AREA);
}
break;
case BL_MOB:
@@ -3388,6 +3522,7 @@
clif_specialeffect_single(bl,423,sd->fd);
else if(tsd->state.size==1)
clif_specialeffect_single(bl,421,sd->fd);
+ clif_sendaurastoone(tsd, sd);
}
break;
case BL_NPC:
@@ -3413,6 +3548,37 @@
}
}- 1
-
int number = 0, item_id, flag = 0, costume = 0;заменить на :
int number = 0, flag = 0,costume = 0,bound = 0;Это:
+ if( !(item_data->equip&EQP_HEAD_LOW) &&
+ !(item_data->equip&EQP_HEAD_MID) &&
+ !(item_data->equip&EQP_HEAD_TOP) &&
+ !(item_data->equip&EQP_COSTUME_HEAD_LOW) &&
+ !(item_data->equip&EQP_COSTUME_HEAD_MID) &&
+ !(item_data->equip&EQP_COSTUME_HEAD_TOP) )На это:
if( !(item_data[j]->equip&EQP_HEAD_LOW) &&
!(item_data[j]->equip&EQP_HEAD_MID) &&
!(item_data[j]->equip&EQP_HEAD_TOP) &&
!(item_data[j]->equip&EQP_COSTUME_HEAD_LOW) &&
!(item_data[j]->equip&EQP_COSTUME_HEAD_MID) &&
!(item_data[j]->equip&EQP_COSTUME_HEAD_TOP) )- 1
-
Я так понимаю, локация эта : evt_xmas13.rsw#bgm\\137.mp3# ,а если например вставить другое дефолтное бгм, такая же проблема?
-
Если не затруднит, скинь пожалуйста mp3nametable.txt
-
Вполне возможно , хотя это только предположение, что не соответствует setup.exe. Хотя опять же , только на одной локации такой косяк или на всех?
-
Хотелось бы уточнить, BGM кастомные или дефолтные?
-
Скрины прикрепляй
-
Пиши в ПМ (либо Скайп) - помогу
-
вот такая ошибка:
root@vps**:~# cd /home/eathena2
root@vps**:/home/eathena2# make clean
-bash: make: command not found
root@vps**:/home/eathena2#
сервер остановлен, права правильные, но выдает эту ошибку...
cd /home/eathena2/
apt-get install gcc zlib1g-dev libmysql++-dev
./configure --enable-64bit
apt-get install make- 1
-
Патч не до конца прошёл Rejected script.c , battle.conf
а так принцепи сама команда работает, компиляция не выбила ничего, но мапсервер отказался читать a = getequipid(.@Part); и costume .@Part; // Convert the Headgear
Скрипт переписывать нужно, он под рАфину реализован, по поводу черепахи разберусь, я всё руками ввожу.
- 2
-
Это я и хотел услышать, спасибо за инфу
- 1
-
Найти , помоему проще задачи нет, ну ты мне обьясни в чем баг то продажи нпц, если сумма продажи составляет такую же стоимость
P/S реализация самого мода , стоит через нпц
UPD. Уменьшил хайд
-
Решил взглянуть. Далеко не всё в этом коде пофикшено.
Костюмы можно также продавать нпц за зени.
И что в этом плохого?
-
Доброго времени суток, как вы заметили в паблике лежит данный мод написанный под rAthena , так же есть и под eAthena (by greenbox) , но вся "прелесть" в том, что там присутствуют такие баги как , например: -Вставляются карты в костюмы, далее перечислять не буду, кому нужно, тот посмотрит. В моде же, который написан под rAthen'у такие баги исправлены.
Возникла необходимость переписать данный мод (rAthena - by Rebel, Zephyrus) , под последнюю версию eAthena ( rev. 15268) . Но в процессе возникли некие проблемы . Они были указаны в недавней теме, как вы все помните. Проблемы решились и вот соответственно сам мод:
Пользуйтесь.
Исходник (rAthena) :
- 6
-
Проблема решена. За помощь благодарю Functor'a
-
Спору нет, сервер сам по себе сделан качественно, админы молодцы, вопросов нет, но это лично мое мнение, чего -то не хватает
-
Поиграв полтара часа на этом сервере, остался лишь негативный осадок
- 1
-
ну желательно бы скрины, тут же не ясновидящие
-
ошибки при компиле какие
-
А можете сделать патч что бы используя черепахуу залить это в еа 15268) А то патчить умею а создавать патчи ещё неумею) или обьясните как с помощью черепашки это сделать буду очень признателен)))
- 2
Угадайте Аниме)
в Флуд
Опубликовано
еще картинок!!