// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. // Copyright (c) 2014 Evol developers #include #include #include #include "../../../common/HPMi.h" #include "../../../common/malloc.h" #include "../../../common/mmo.h" #include "../../../common/socket.h" #include "../../../common/strlib.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 "map/script.h" #include "map/clif.h" #include "map/lang.h" #include "map/scriptdefines.h" #include "map/send.h" #include "map/data/mapd.h" #include "map/data/session.h" #include "map/struct/mapdext.h" #include "map/struct/sessionext.h" #include "map/utils/formatutils.h" BUILDIN(l) { format_sub(st, 1); return true; } BUILDIN(lg) { format_sub(st, 2); return true; } BUILDIN(setCamNpc) { getSD(); struct npc_data *nd = NULL; int x = 0; int y = 0; if (script_hasdata(st, 2)) { nd = npc->name2id (script_getstr(st, 2)); } else { if (!st->oid) return false; nd = (struct npc_data *) map->id2bl (st->oid); } if (!nd || sd->bl.m != nd->bl.m) 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; struct npc_data *nd = NULL; getSD(); if (script_hasdata(st, 3)) { nd = npc->name2id (script_getstr(st, 2)); str = script_getstr(st, 3); } else { nd = (struct npc_data *) map->id2bl (st->oid); str = script_getstr(st, 2); } if (!nd) return false; if (sd) msg = (char*)lang_pctrans (nd->name, sd); else msg = nd->name; if (strlen(str) + strlen(msg) > 450) return false; if (nd) { char message[500]; strcpy (message, msg); 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(); struct npc_data *nd = npc->name2id (script_getstr(st, 2)); if (!nd) 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) { 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->reportdata(data); st->state = END; return false; } uid = reference_getuid(data); name = reference_getname(data); if (is_string_variable(name)) 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(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); 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 false; } script_pushint(st, sd->quest_log[i].count[0]); return true; } BUILDIN(getNpcDir) { struct npc_data *nd = 0; if (script_hasdata(st, 2)) { nd = npc->name2id (script_getstr(st, 2)); } if (!nd && !st->oid) { script_pushint(st, -1); return true; } if (!nd) nd = (struct npc_data *) map->id2bl (st->oid); if (!nd) { script_pushint(st, -1); return true; } script_pushint(st, (int)nd->dir); return true; } BUILDIN(setNpcDir) { int newdir; struct npc_data *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) return false; nd = (struct npc_data *) map->id2bl (st->oid); newdir = script_getnum(st, 2); } if (!nd) 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) return true; 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_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) return true; const int m = map->mapname2mapid(mapName); if (m < 0) 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); return true; } const int m = map->mapname2mapid(mapName); if (m < 0) { script_pushint(st, 0); return false; } getMapDataReturn(m, 0); script_pushint(st, mapData->mask); return true; } BUILDIN(addMapMask) { const char *const mapName = script_getstr(st, 2); if (!mapName) return true; const int m = map->mapname2mapid(mapName); if (m < 0) 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) return true; const int m = map->mapname2mapid(mapName); if (m < 0) 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(getNpcClass) { struct npc_data *nd = 0; if (script_hasdata(st, 2)) { nd = npc->name2id (script_getstr(st, 2)); } if (!nd && !st->oid) { script_pushint(st, -1); return false; } if (!nd) nd = (struct npc_data *) map->id2bl(st->oid); if (!nd) { script_pushint(st, -1); return false; } script_pushint(st, (int)nd->class_); return true; } BUILDIN(setNpcSex) { struct npc_data *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 { return false; } if (!nd && !st->oid) { return false; } if (!nd) nd = (struct npc_data *) map->id2bl(st->oid); if (!nd || !nd->vd) { script_pushint(st, -1); return false; } clif->clearunit_area(&nd->bl, CLR_OUTSIGHT); nd->vd->sex = sex; clif->spawn(&nd->bl); return true; } BUILDIN(setPcSit) { TBL_PC *sd = NULL; int state = 0; if (script_hasdata(st, 3)) { sd = map->nick2sd (script_getstr(st, 2)); state = script_getnum(st, 3); } else if (script_hasdata(st, 2)) { sd = script->rid2sd(st); state = script_getnum(st, 2); } else { return false; } if (!sd) return false; if (state < 0) state = 0; if (state > 1) state = 1; if (!state) { if (pc_issit(sd)) { pc->setstand(sd); clif->standing(&sd->bl); } } else if (!pc_issit (sd)) { sd->state.dead_sit = 2; sd->vd.dead_sit = 2; clif->sitting(&sd->bl); } return true; } BUILDIN(getPcSit) { TBL_PC *sd = NULL; if (script_hasdata(st, 2)) sd = map->nick2sd (script_getstr(st, 2)); else sd = script->rid2sd(st); if (!sd) script_pushint(st, -1); else script_pushint(st, pc_issit (sd)); return true; }