diff options
Diffstat (limited to 'src/emap/script.c')
-rw-r--r-- | src/emap/script.c | 1148 |
1 files changed, 1148 insertions, 0 deletions
diff --git a/src/emap/script.c b/src/emap/script.c new file mode 100644 index 0000000..d492430 --- /dev/null +++ b/src/emap/script.c @@ -0,0 +1,1148 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2014 Evol developers + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "common/HPMi.h" +#include "common/malloc.h" +#include "common/mmo.h" +#include "common/socket.h" +#include "common/strlib.h" +#include "common/timer.h" +#include "map/chrif.h" +#include "map/clif.h" +#include "map/npc.h" +#include "map/pc.h" +#include "map/script.h" +#include "map/quest.h" +#include "map/unit.h" + +#include "emap/script.h" +#include "emap/clif.h" +#include "emap/lang.h" +#include "emap/scriptdefines.h" +#include "emap/send.h" +#include "emap/data/mapd.h" +#include "emap/data/npcd.h" +#include "emap/data/session.h" +#include "emap/struct/mapdext.h" +#include "emap/struct/npcdext.h" +#include "emap/struct/sessionext.h" +#include "emap/utils/formatutils.h" + +BUILDIN(l) +{ + format_sub(st, 1); + return true; +} + +BUILDIN(lg) +{ + format_sub(st, 2); + return true; +} + +BUILDIN(setCamNpc) +{ + getSD(); + TBL_NPC *nd = NULL; + + int x = 0; + int y = 0; + + if (script_hasdata(st, 2)) + { + nd = npc->name2id (script_getstr(st, 2)); + } + else + { + if (!st->oid) + { + ShowWarning("npc not attached\n"); + script->reportsrc(st); + return false; + } + + nd = (TBL_NPC *) map->id2bl (st->oid); + } + if (!nd) + { + ShowWarning("npc not found\n"); + script->reportsrc(st); + return false; + } + if (sd->bl.m != nd->bl.m) + { + ShowWarning("npc and player located in other maps\n"); + script->reportsrc(st); + return false; + } + + if (script_hasdata(st, 3) && script_hasdata(st, 4)) + { + x = script_getnum(st, 3); + y = script_getnum(st, 4); + } + + send_npccommand2(script->rid2sd (st), st->oid, 2, nd->bl.id, x, y); + + return true; +} + +BUILDIN(setCam) +{ + send_npccommand2(script->rid2sd (st), st->oid, 2, 0, + script_getnum(st, 2), script_getnum(st, 3)); + + return true; +} + +BUILDIN(moveCam) +{ + send_npccommand2(script->rid2sd (st), st->oid, 4, 0, + script_getnum(st, 2), script_getnum(st, 3)); + + return true; +} + +BUILDIN(restoreCam) +{ + getSD(); + send_npccommand(sd, st->oid, 3); + return true; +} + +BUILDIN(npcTalk3) +{ + const char *str; + char *msg; + TBL_NPC *nd = NULL; + + getSD(); + + if (script_hasdata(st, 3)) + { + nd = npc->name2id (script_getstr(st, 2)); + str = script_getstr(st, 3); + } + else + { + nd = (TBL_NPC *) map->id2bl (st->oid); + str = script_getstr(st, 2); + } + + if (!nd) + { + ShowWarning("npc not found\n"); + script->reportsrc(st); + return false; + } + + if (!str) + { + ShowWarning("error in string\n"); + script->reportsrc(st); + return false; + } + + if (sd) + msg = (char*)lang_pctrans (nd->name, sd); + else + msg = nd->name; + + if (!msg) + { + ShowWarning("error in string\n"); + script->reportsrc(st); + return false; + } + if (strlen(str) + strlen(msg) > 450) + { + ShowWarning("text message too big\n"); + script->reportsrc(st); + return false; + } + + if (nd) + { + char message[500]; + char name[500]; + strcpy (name, msg); + strtok(name, "#"); + strcpy (message, name); + strcat (message, " : "); + strcat (message, str); + send_local_message (sd->fd, &(nd->bl), message); + } + + return true; +} + +BUILDIN(closeDialog) +{ + getSD(); + send_npccommand(script->rid2sd (st), st->oid, 5); + return true; +} + +BUILDIN(shop) +{ + getSD(); + TBL_NPC *nd = npc->name2id (script_getstr(st, 2)); + if (!nd) + { + ShowWarning("shop npc not found\n"); + script->reportsrc(st); + return false; + } + + st->state = sd->state.dialog == 1 ? CLOSE : END; + clif->scriptclose(sd, st->oid); + + clif->npcbuysell (sd, nd->bl.id); + return true; +} + +BUILDIN(getItemLink) +{ + struct item_data *i_data; + char *item_name; + int item_id = 0; + + if (script_isstringtype(st, 2)) + { + i_data = itemdb->search_name (script_getstr(st, 2)); + } + else + { + item_id = script_getnum (st, 2); + i_data = itemdb->search (item_id); + } + + item_name = (char *) aCalloc (100, sizeof (char)); + TBL_PC *sd = script->rid2sd(st); + + if (sd) + { + int version = 0; + struct SessionExt *data = session_get_bysd(sd); + if (data) + version = data->clientVersion; + + if (i_data && version >= 7) + sprintf(item_name, "[@@%u|@@]", (unsigned)i_data->nameid); + else if (i_data) + sprintf(item_name, "[@@%u|%s@@]", (unsigned)i_data->nameid, lang_pctrans (i_data->jname, sd)); + else if (item_id > 0) + sprintf(item_name, "[@@%u|Unknown Item@@]", (unsigned)item_id); + else + sprintf(item_name, "[Unknown Item]"); + } + else + { + if (i_data) + sprintf(item_name, "[%s]", lang_pctrans (i_data->jname, sd)); + else + sprintf(item_name, "[Unknown Item]"); + } + + script_pushstr(st, item_name); + + return true; +} + +BUILDIN(requestLang) +{ + getSD(); + struct script_data* data; + int64 uid; + const char* name; + + data = script_getdata(st, 2); + if (!data_isreference(data)) + { + ShowError("script:requestlang: not a variable\n"); + script->reportsrc(st); + st->state = END; + return false; + } + uid = reference_getuid(data); + name = reference_getname(data); + + if (is_string_variable(name)) + { + ShowError("script:requestlang: not a variable\n"); + script->reportsrc(st); + return false; + } + + if (!sd->state.menu_or_input) + { + // first invocation, display npc input box + sd->state.menu_or_input = 1; + st->state = RERUNLINE; + + // send lang request + send_npccommand(script->rid2sd(st), st->oid, 0); + clif->scriptinputstr(sd, st->oid); + } + else + { + // take received text/value and store it in the designated variable + sd->state.menu_or_input = 0; + + int lng = -1; + if (*sd->npc_str) + lng = lang_getId(sd->npc_str); + script->set_reg(st, sd, uid, name, (void*)h64BPTRSIZE(lng), script_getref(st,2)); + st->state = RUN; + } + return true; +} + +BUILDIN(requestItem) +{ + getSD(); + struct script_data* data; + int64 uid; + const char* name; + + data = script_getdata(st, 2); + if (!data_isreference(data)) + { + ShowError("script:requestitem: not a variable\n"); + script->reportsrc(st); + st->state = END; + return false; + } + uid = reference_getuid(data); + name = reference_getname(data); + + if (is_string_variable(name)) + { + ShowError("script:requestlang: not a variable\n"); + script->reportsrc(st); + return false; + } + + if (!sd->state.menu_or_input) + { + // first invocation, display npc input box + sd->state.menu_or_input = 1; + st->state = RERUNLINE; + + // send item request + send_npccommand(script->rid2sd(st), st->oid, 10); + } + else + { + // take received text/value and store it in the designated variable + sd->state.menu_or_input = 0; + + int item = 0; + + if (!sd->npc_str) + { + ShowWarning("npc string not found\n"); + script->reportsrc(st); + return false; + } + + if (sscanf (sd->npc_str, "%5d", &item) < 1) + { + ShowWarning("input data is not item id\n"); + script->reportsrc(st); + return false; + } + + script->set_reg(st, sd, uid, name, (void*)h64BPTRSIZE(item), script_getref(st,2)); + st->state = RUN; + } + return true; +} + +BUILDIN(requestItems) +{ + getSD(); + struct script_data* data; + int64 uid; + const char* name; + + data = script_getdata(st, 2); + if (!data_isreference(data)) + { + ShowError("script:requestitem: not a variable\n"); + script->reportsrc(st); + st->state = END; + return false; + } + uid = reference_getuid(data); + name = reference_getname(data); + + if (!is_string_variable(name)) + { + ShowWarning("parameter is not variable\n"); + script->reportsrc(st); + return false; + } + + int count = 1; + + if (script_hasdata(st, 3)) + { + count = script_getnum(st, 3); + if (count < 0) + count = 1; + } + + if (!sd->state.menu_or_input) + { + // first invocation, display npc input box + sd->state.menu_or_input = 1; + st->state = RERUNLINE; + + // send item request with limit count + send_npccommand2(script->rid2sd (st), st->oid, 10, count, 0, 0); + } + else + { + // take received text/value and store it in the designated variable + sd->state.menu_or_input = 0; + + if (!sd->npc_str) + { + ShowWarning("npc string not found\n"); + script->reportsrc(st); + return false; + } + + script->set_reg(st, sd, uid, name, (void*)sd->npc_str, script_getref(st, 2)); + st->state = RUN; + } + return true; +} + +BUILDIN(setq) +{ + int i; + getSD(); + + int quest_id = script_getnum(st, 2); + int quest_value = script_getnum(st, 3); + + if (quest->check(sd, quest_id, HAVEQUEST) < 0) + quest->add(sd, quest_id); + ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id); + if (i == sd->num_quests) + { + ShowError("Quest with id=%d not found\n", quest_id); + script->reportsrc(st); + return false; + } + + sd->quest_log[i].count[0] = quest_value; + sd->save_quest = true; + if (map->save_settings & 64) + chrif->save(sd,0); + + eclif_quest_add(sd, &sd->quest_log[i]); + return true; +} + +BUILDIN(getq) +{ + int i; + getSDReturn(0); + + int quest_id = script_getnum(st, 2); + if (quest->check(sd, quest_id, HAVEQUEST) < 0) + { + script_pushint(st, 0); + return true; + } + ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id); + if (i == sd->num_quests) + { + script_pushint(st, 0); + return true; + } + script_pushint(st, sd->quest_log[i].count[0]); + return true; +} + +BUILDIN(setNpcDir) +{ + int newdir; + TBL_NPC *nd = 0; + + if (script_hasdata(st, 3)) + { + nd = npc->name2id (script_getstr(st, 2)); + newdir = script_getnum(st, 3); + } + else if (script_hasdata(st, 2)) + { + if (!st->oid) + { + ShowWarning("npc not found\n"); + script->reportsrc(st); + return false; + } + + nd = (TBL_NPC *) map->id2bl (st->oid); + newdir = script_getnum(st, 2); + } + if (!nd) + { + ShowWarning("npc not found\n"); + script->reportsrc(st); + return false; + } + + if (newdir < 0) + newdir = 0; + else if (newdir > 7) + newdir = 7; + + nd->dir = newdir; + npc->enable (nd->name, 1); + + return true; +} + +BUILDIN(rif) +{ + const char *str = 0; + if (script_getnum(st, 2)) + { + str = script_getstr(st, 3); + if (str) + script_pushstr(st, aStrdup(str)); + else + script_pushconststr(st, (char *)""); + } + else if (script_hasdata(st, 4)) + { + str = script_getstr(st, 4); + if (str) + script_pushstr(st, aStrdup(str)); + else + script_pushconststr(st, (char *)""); + } + else + { + script_pushconststr(st, (char *)""); + } + + return true; +} + +BUILDIN(countItemColor) +{ + int nameid, i; + int count = 0; + struct item_data* id = NULL; + + TBL_PC* sd = script->rid2sd(st); + if (!sd) + { + ShowWarning("player not attached\n"); + script->reportsrc(st); + return false; + } + + if (script_isstringtype(st, 2)) + { + // item name + id = itemdb->search_name(script_getstr(st, 2)); + } + else + { + // item id + id = itemdb->exists(script_getnum(st, 2)); + } + + if (id == NULL) + { + ShowError("buildin_countitem: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was + script->reportsrc(st); + script_pushint(st,0); + return false; + } + + nameid = id->nameid; + + for(i = 0; i < MAX_INVENTORY; i++) + { + if(sd->status.inventory[i].nameid == nameid) + count += sd->status.inventory[i].amount; + } + + script_pushint(st, count); + return true; +} + +BUILDIN(miscEffect) +{ + int type = script_getnum(st, 2); + struct block_list *bl = NULL; + + if (script_hasdata(st, 3)) + { + if (script_isstring(st, 3)) + { + TBL_PC *sd = map->nick2sd(script_getstr(st, 3)); + if (sd) + bl = &sd->bl; + } + else if (script_isint(st, 3)) + { + bl = map->id2bl(script_getnum(st, 3)); + } + } + + if (!bl) + { + TBL_PC *sd = script->rid2sd (st); + if (sd) + bl = &sd->bl; + } + if (bl) + clif->specialeffect(bl, type, AREA); + return true; +} + +BUILDIN(setMapMask) +{ + const char *const mapName = script_getstr(st, 2); + if (!mapName) + { + ShowWarning("invalid map name\n"); + script->reportsrc(st); + return false; + } + const int m = map->mapname2mapid(mapName); + if (m < 0) + { + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + getMapData(m); + + const int val = script_getnum(st, 3); + const unsigned int old = mapData->mask; + mapData->mask = val; + if (old != mapData->mask) + send_mapmask_brodcast(m, mapData->mask); + return true; +} + +BUILDIN(getMapMask) +{ + const char *const mapName = script_getstr(st, 2); + if (!mapName) + { + script_pushint(st, 0); + ShowWarning("invalid map name\n"); + script->reportsrc(st); + return false; + } + const int m = map->mapname2mapid(mapName); + if (m < 0) + { + script_pushint(st, 0); + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + getMapDataReturn(m, 0); + script_pushint(st, mapData->mask); + return true; +} + +BUILDIN(addMapMask) +{ + const char *const mapName = script_getstr(st, 2); + if (!mapName) + { + ShowWarning("invalid map name\n"); + script->reportsrc(st); + return false; + } + const int m = map->mapname2mapid(mapName); + if (m < 0) + { + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + getMapData(m); + const int val = script_getnum(st, 3); + const unsigned int old = mapData->mask; + mapData->mask |= val; + if (old != mapData->mask) + send_mapmask_brodcast(m, mapData->mask); + + return true; +} + +BUILDIN(removeMapMask) +{ + const char *const mapName = script_getstr(st, 2); + if (!mapName) + { + ShowWarning("invalid map name\n"); + script->reportsrc(st); + return true; + } + const int m = map->mapname2mapid(mapName); + if (m < 0) + { + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + getMapData(m); + const int val = script_getnum(st, 3); + const unsigned int old = mapData->mask; + mapData->mask |= val; + mapData->mask ^= val; + if (old != mapData->mask) + send_mapmask_brodcast(m, mapData->mask); + return true; +} + +BUILDIN(setNpcSex) +{ + TBL_NPC *nd = NULL; + int sex = 0; + if (script_hasdata(st, 3)) + { + nd = npc->name2id (script_getstr(st, 2)); + sex = script_getnum(st, 3); + } + else if (script_hasdata(st, 2)) + { + sex = script_getnum(st, 2); + } + else + { + ShowWarning("no parameters provided\n"); + script->reportsrc(st); + return false; + } + + if (!nd && !st->oid) + { + ShowWarning("npc not found\n"); + script->reportsrc(st); + return false; + } + + if (!nd) + nd = (TBL_NPC *) map->id2bl(st->oid); + + if (!nd || !nd->vd) + { + ShowWarning("npc not found\n"); + script->reportsrc(st); + return false; + } + + clif->clearunit_area(&nd->bl, CLR_OUTSIGHT); + nd->vd->sex = sex; + clif->spawn(&nd->bl); + return true; +} + +BUILDIN(showAvatar) +{ + int id = 0; + if (script_hasdata(st, 2)) + id = script_getnum(st, 2); + + send_npccommand2(script->rid2sd (st), st->oid, 6, id, 0, 0); + return true; +} + +BUILDIN(setAvatarDir) +{ + int newdir = script_getnum(st, 2); + + if (newdir < 0) + newdir = 0; + else if (newdir > 7) + newdir = 7; + + send_npccommand2(script->rid2sd (st), st->oid, 7, newdir, 0, 0); + return true; +} + +BUILDIN(setAvatarAction) +{ + send_npccommand2(script->rid2sd (st), st->oid, 8, script_getnum(st, 2), 0, 0); + return true; +} + +BUILDIN(clear) +{ + send_npccommand(script->rid2sd (st), st->oid, 9); + return true; +} + +BUILDIN(changeMusic) +{ + const char *const mapName = script_getstr(st, 2); + const char *const music = script_getstr(st, 3); + if (!music) + { + ShowWarning("invalid music file\n"); + script->reportsrc(st); + return false; + } + if (!mapName) + { + ShowWarning("invalid map file\n"); + script->reportsrc(st); + return false; + } + const int m = map->mapname2mapid(mapName); + if (m < 0) + { + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + + send_changemusic_brodcast(m, music); + return true; +} + +BUILDIN(setNpcDialogTitle) +{ + const char *const name = script_getstr(st, 2); + if (!name) + { + ShowWarning("invalid window title\n"); + script->reportsrc(st); + return false; + } + TBL_PC *sd = script->rid2sd (st); + if (!sd) + { + ShowWarning("player not attached\n"); + script->reportsrc(st); + return false; + } + + send_changenpc_title(sd, st->oid, name); + return true; +} + +BUILDIN(getMapName) +{ + TBL_PC *sd = script->rid2sd(st); + if (!sd) + { + script_pushstr(st, aStrdup("")); + ShowWarning("player not attached\n"); + script->reportsrc(st); + return false; + } + if (sd->bl.m == -1) + { + script_pushstr(st, aStrdup("")); + ShowWarning("invalid map\n"); + script->reportsrc(st); + return false; + } + script_pushstr(st, aStrdup(map->list[sd->bl.m].name)); + return true; +} + +BUILDIN(unequipById) +{ + int nameid = 0; + int i; + struct item_data *item_data; + TBL_PC *sd = script->rid2sd(st); + + if (sd == NULL) + { + ShowWarning("player not attached\n"); + script->reportsrc(st); + return false; + } + + nameid = script_getnum(st, 2); + if((item_data = itemdb->exists(nameid)) == NULL) + { + ShowWarning("item %d not found\n", nameid); + script->reportsrc(st); + return false; + } + for (i = 0; i < EQI_MAX; i++) + { + const int idx = sd->equip_index[i]; + if (idx >= 0) + { + if (sd->status.inventory[idx].nameid == nameid) + pc->unequipitem(sd, idx, 1 | 2); + } + } + return true; +} + +BUILDIN(isPcDead) +{ + TBL_PC *sd = script->rid2sd(st); + + if (sd == NULL) + { + ShowWarning("player not attached\n"); + script->reportsrc(st); + return false; + } + + script_pushint(st, pc_isdead(sd) ? 1 : 0); + return true; +} + +static int areatimer_sub(struct block_list *bl, va_list ap) +{ + int tick; + char *event; + TBL_PC *sd; + + tick = va_arg(ap, int); + event = va_arg(ap, char*); + + sd = (TBL_PC *)bl; + if (!pc->addeventtimer(sd, tick, event)) + { + if (sd) + ShowWarning("buildin_addtimer: Event timer is full, can't add new event timer. (cid:%d timer:%s)\n", sd->status.char_id, event); + } + return 0; +} + +BUILDIN(areaTimer) +{ + const char *const mapname = script_getstr(st, 2); + const int x1 = script_getnum(st, 3); + const int y1 = script_getnum(st, 4); + const int x2 = script_getnum(st, 5); + const int y2 = script_getnum(st, 6); + const int time = script_getnum(st, 7); + const char *const eventName = script_getstr(st, 8); + int m; + + if ((m = map->mapname2mapid(mapname)) < 0) + { + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + + map->foreachinarea(areatimer_sub, m, x1, y1, x2, y2, BL_PC, time, eventName); + + return true; +} + +static int buildin_getareadropitem_sub_del(struct block_list *bl, va_list ap) +{ + if (!bl) + return 0; + + const int item = va_arg(ap, int); + int *const amount = va_arg(ap, int *); + TBL_ITEM *drop = (TBL_ITEM *)bl; + + if (drop->item_data.nameid == item) + { + (*amount) += drop->item_data.amount; + map->clearflooritem(&drop->bl); + } + + return 0; +} + +BUILDIN(getAreaDropItem) +{ + const char *const str = script_getstr(st, 2); + int16 m; + int x0 = script_getnum(st, 3); + int y0 = script_getnum(st, 4); + int x1 = script_getnum(st, 5); + int y1 = script_getnum(st, 6); + int item; + int amount = 0; + + if (script_isstringtype(st, 7)) + { + const char *name = script_getstr(st, 7); + struct item_data *item_data = itemdb->search_name(name); + item = UNKNOWN_ITEM_ID; + if (item_data) + item = item_data->nameid; + } + else + { + item = script_getnum(st, 7); + } + + if ((m = map->mapname2mapid(str)) < 0) + { + script_pushint(st, -1); + ShowWarning("map not found\n"); + script->reportsrc(st); + return false; + } + + if (script_hasdata(st, 8) && script_getnum(st, 8)) + { + map->foreachinarea(buildin_getareadropitem_sub_del, + m, x0, y0, x1, y1, BL_ITEM, item, &amount); + } + else + { + map->foreachinarea(script->buildin_getareadropitem_sub, + m, x0, y0, x1, y1, BL_ITEM, item, &amount); + } + script_pushint(st, amount); + return true; +} + +enum setmount_type +{ + SETMOUNT_TYPE_NONE = 0, + SETMOUNT_TYPE_PECO = 1, + SETMOUNT_TYPE_WUG = 2, + SETMOUNT_TYPE_MADO = 3, + SETMOUNT_TYPE_DRAGON_GREEN = 4, + SETMOUNT_TYPE_DRAGON_BROWN = 5, + SETMOUNT_TYPE_DRAGON_GRAY = 6, + SETMOUNT_TYPE_DRAGON_BLUE = 7, + SETMOUNT_TYPE_DRAGON_RED = 8, + SETMOUNT_TYPE_MAX, + SETMOUNT_TYPE_DRAGON = SETMOUNT_TYPE_DRAGON_GREEN, +}; + +BUILDIN(setMount) +{ + int flag = SETMOUNT_TYPE_NONE; + TBL_PC* sd = script->rid2sd(st); + + if (sd == NULL) + return true; // no player attached, report source + + if (script_hasdata(st, 2)) + flag = script_getnum(st, 2); + + // Sanity checks and auto-detection + if (flag >= SETMOUNT_TYPE_DRAGON_GREEN && flag <= SETMOUNT_TYPE_DRAGON_RED) + { + if (pc->checkskill(sd, RK_DRAGONTRAINING)) + { + // Rune Knight (Dragon) + unsigned int option; + option = ( flag == SETMOUNT_TYPE_DRAGON_GREEN ? OPTION_DRAGON1 : + flag == SETMOUNT_TYPE_DRAGON_BROWN ? OPTION_DRAGON2 : + flag == SETMOUNT_TYPE_DRAGON_GRAY ? OPTION_DRAGON3 : + flag == SETMOUNT_TYPE_DRAGON_BLUE ? OPTION_DRAGON4 : + flag == SETMOUNT_TYPE_DRAGON_RED ? OPTION_DRAGON5 : + OPTION_DRAGON1); // default value + pc->setridingdragon(sd, option); + } + } + else if (flag == SETMOUNT_TYPE_WUG) + { + // Ranger (Warg) + if (pc->checkskill(sd, RA_WUGRIDER)) + pc->setridingwug(sd, true); + } + else if (flag == SETMOUNT_TYPE_MADO) + { + // Mechanic (Mado Gear) + if (pc->checkskill(sd, NC_MADOLICENCE)) + pc->setmadogear(sd, true); + } + else if (flag == SETMOUNT_TYPE_PECO) + { + // Knight / Crusader (Peco Peco) + if (pc->checkskill(sd, KN_RIDING)) + pc->setridingpeco(sd, true); + } + else if (flag == SETMOUNT_TYPE_NONE && pc_hasmount(sd)) + { + if (pc_isridingdragon(sd)) + { + pc->setridingdragon(sd, 0); + } + if (pc_isridingwug(sd)) + { + pc->setridingwug(sd, false); + } + if (pc_ismadogear(sd)) + { + pc->setmadogear(sd, false); + } + if (pc_isridingpeco(sd)) + { + pc->setridingpeco(sd, false); + } + } + + return true; +} + +BUILDIN(clientCommand) +{ + TBL_PC* sd = script->rid2sd(st); + + if (sd == NULL) + { + ShowWarning("player not attached\n"); + script->reportsrc(st); + return false; + } + const char *const command = script_getstr(st, 2); + if (!command) + { + ShowWarning("invalid client command\n"); + script->reportsrc(st); + return false; + } + send_client_command(sd, command); + return true; +} + +BUILDIN(isUnitWalking) +{ + int id = 0; + if (script_hasdata(st, 2)) + id = script_getnum(st, 2); + else + id = st->oid; + struct block_list *bl = map->id2bl(id); + if (!bl) + { + ShowWarning("invalid unit id\n"); + script->reportsrc(st); + script_pushint(st, 0); + return false; + } + struct unit_data *ud = unit->bl2ud(bl); + if (!ud) + { + ShowWarning("invalid unit data\n"); + script->reportsrc(st); + script_pushint(st, 0); + return false; + } + script_pushint(st, ud->walktimer != INVALID_TIMER); + return true; +} |