- Added check to clear skill unit group that created by NPC/script before the NPC/script unloaded.
- Changed enum for NPC subtype, added prefix NPCTYPE_. See map.h::npc_subtype. - Changed Channel_Config struct usage to -> extern struct Channel_Config channel_config. - Added restriction for atcommand that cannot be executed when Player is in autotrade, to prevent map crash. (bugreport:9196) TODO: Check other atcommand or change this behavior. - Added enum for atcommand restriction with prefix ATCMD_NO. See atcommand.c::e_atcmd_restict. - Updated atcommand documentations. - Changed dummy_sd's attributes to group_id & group_level 99, and gives all permissions (PC_PERM_ALLPERMISSION). dummy_sd is being used by 'atcommand' or 'useatcmd' script when no rid/player attached. Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
parent
880903bdab
commit
3efe5375f3
@ -13,6 +13,10 @@ This file describes the usage of in-game commands and assumes that
|
||||
atcommand_symbol : "@"
|
||||
charcommand_symbol: "#"
|
||||
|
||||
Some commands cannot be used from console or script command to prevent map-server crashed.
|
||||
See atcommand.c::atcommand_basecommands for restricted commands. Please tell us if any
|
||||
other atcommand that causes map-server crashed executed by console or script commands.
|
||||
|
||||
To search for a command, write "@" before the command name (ex. @commands).
|
||||
The format of this file is as follows:
|
||||
1. System Commands
|
||||
@ -799,6 +803,9 @@ Warps to predefined locations in major cities.
|
||||
If no ID is given, all available maps will be displayed in the chat window.
|
||||
Locations and coordinates are stored in '/src/map/atcommand.c'.
|
||||
|
||||
Restriction:
|
||||
- Used from console
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@warp <map> {<x> <y>}
|
||||
@ -808,6 +815,9 @@ Locations and coordinates are stored in '/src/map/atcommand.c'.
|
||||
Warps to the specified map.
|
||||
If no coordinates are entered, a random location will be chosen.
|
||||
|
||||
Restriction:
|
||||
- Used from console
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@jumpto <player name/ID>
|
||||
@ -851,6 +861,9 @@ Allows other players to attack you outside of PvP.
|
||||
|
||||
Changes base or job level by the specified amount.
|
||||
|
||||
Restriction:
|
||||
- Used from console
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@str <+/- amount>
|
||||
@ -908,6 +921,9 @@ An 'upper' value can be specified with a job ID to produce its normal (0), advan
|
||||
If no job is given, a list of all available jobs will be returned.
|
||||
Note that jobs 22 (Wedding), 26 (Summer), 27 (Christmas), and 28 (Hanbok) are not available via @job.
|
||||
|
||||
Restriction:
|
||||
- Used from console
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@speed <0-1000>
|
||||
@ -1224,6 +1240,14 @@ If a time is not specified (jailfor), the player will be jailed indefinitely.
|
||||
---------------------------------------
|
||||
|
||||
@kick <player name/ID>
|
||||
|
||||
Kick a player from the server.
|
||||
|
||||
Restriction:
|
||||
- Used from 'atcommand' or 'useatcmd' by autotrader
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@kickall
|
||||
/killall
|
||||
|
||||
@ -1317,7 +1341,10 @@ Affected files:
|
||||
-- questdb: quest_db.txt
|
||||
-- script: /npc/*.txt, /npc/*.conf
|
||||
-- skilldb: skill_db.txt, const.txt, skill_require_db.txt, skill_cast_db.txt, skill_castnodex_db.txt, skill_nocast_db.txt, skill_copyable_db.txt, skill_improvise_db.txt, skill_changematerial_db.txt, skill_nonearnpc_db.txt, skill_damage_db.txt, skill_unit_db.txt, abra_db.txt, create_arrow_db.txt, produce_db.txt, spellbook_db.txt, magicmushroom_db.txt
|
||||
-- statusdb: attr_fix.txt, size_fix.txt, refine_db.tx
|
||||
-- statusdb: attr_fix.txt, size_fix.txt, refine_db.tx
|
||||
|
||||
Restriction:
|
||||
- Used from 'atcommand' or 'useatcmd'. For @reload & @reloadscript
|
||||
|
||||
---------------------------------------
|
||||
|
||||
|
@ -894,7 +894,7 @@ int chmapif_parse_save_scdata(int fd){
|
||||
|
||||
// Whatever comes from the mapserver, now is the time to drop previous entries
|
||||
if( Sql_Query( sql_handle, "DELETE FROM `%s` where `account_id` = %d and `char_id` = %d;", schema_config.scdata_db, aid, cid ) != SQL_SUCCESS ){
|
||||
Sql_ShowDebug( sql_handle );
|
||||
Sql_ShowDebug( sql_handle );
|
||||
}
|
||||
else if( count > 0 )
|
||||
{
|
||||
|
@ -60,12 +60,19 @@ typedef struct AliasInfo AliasInfo;
|
||||
|
||||
int atcmd_binding_count = 0;
|
||||
|
||||
/// Atcommand restriction usage
|
||||
enum e_atcmd_restict {
|
||||
ATCMD_NOCONSOLE = 0x1, /// Cannot be used via console (is_atcommand type 2)
|
||||
ATCMD_NOSCRIPT = 0x2, /// Cannot be used via script command 'atcommand' or 'useatcmd' (is_atcommand type 0 and 3)
|
||||
ATCMD_NOAUTOTRADE = 0x4, /// Like ATCMD_NOSCRIPT, but if the player is autotrader. Example: atcommand "@kick "+strcharinfo(0);
|
||||
};
|
||||
|
||||
struct AtCommandInfo {
|
||||
char command[ATCOMMAND_LENGTH];
|
||||
AtCommandFunc func;
|
||||
char* at_groups;/* quick @commands "can-use" lookup */
|
||||
char* char_groups;/* quick @charcommands "can-use" lookup */
|
||||
int restriction; //prevent : 1 console, 2 script...
|
||||
char* at_groups; /// Quick @commands "can-use" lookup
|
||||
char* char_groups; /// Quick @charcommands "can-use" lookup
|
||||
uint8 restriction; /// Restrictions see enum e_restict
|
||||
};
|
||||
|
||||
struct AliasInfo {
|
||||
@ -9136,7 +9143,7 @@ static inline void atcmd_channel_help(struct map_session_data *sd, const char *c
|
||||
{
|
||||
int fd = sd->fd;
|
||||
bool can_delete = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN);
|
||||
bool can_create = (can_delete || Channel_Config.user_chenable);
|
||||
bool can_create = (can_delete || channel_config.user_chenable);
|
||||
clif_displaymessage(fd, msg_txt(sd,1414));// ---- Available options:
|
||||
|
||||
//option create
|
||||
@ -9229,7 +9236,7 @@ ACMD_FUNC(channel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( strcmpi(key,"create") == 0 && ( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) {
|
||||
if( strcmpi(key,"create") == 0 && ( channel_config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) {
|
||||
if(sub3[0] != '\0'){
|
||||
clif_displaymessage(fd, msg_txt(sd,1408)); // Channel password may not contain spaces.
|
||||
return -1;
|
||||
@ -9277,8 +9284,8 @@ ACMD_FUNC(fontcolor)
|
||||
sd->fontcolor = 0;
|
||||
} else {
|
||||
unsigned char k;
|
||||
ARR_FIND(0,Channel_Config.colors_count,k,( strcmpi(message,Channel_Config.colors_name[k]) == 0 ));
|
||||
if( k == Channel_Config.colors_count ) {
|
||||
ARR_FIND(0,channel_config.colors_count,k,( strcmpi(message,channel_config.colors_name[k]) == 0 ));
|
||||
if( k == channel_config.colors_count ) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1411), message);// Unknown color '%s'.
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
return -1;
|
||||
@ -9661,17 +9668,17 @@ ACMD_FUNC(clonestat) {
|
||||
**/
|
||||
#define ACMD_DEF(x) { #x, atcommand_ ## x, NULL, NULL, 0 }
|
||||
#define ACMD_DEF2(x2, x) { x2, atcommand_ ## x, NULL, NULL, 0 }
|
||||
//define with restriction
|
||||
// Define with restriction
|
||||
#define ACMD_DEFR(x, r) { #x, atcommand_ ## x, NULL, NULL, r }
|
||||
#define ACMD_DEF2R(x2, x, r) { x2, atcommand_ ## x, NULL, NULL, r }
|
||||
void atcommand_basecommands(void) {
|
||||
/**
|
||||
* Command reference list, place the base of your commands here
|
||||
* TODO : all restricted command are crashing case, please look into it
|
||||
* TODO: List all commands that causing crash
|
||||
**/
|
||||
AtCommandInfo atcommand_base[] = {
|
||||
#include "../custom/atcommand_def.inc"
|
||||
ACMD_DEF2R("warp", mapmove, 1),
|
||||
ACMD_DEF2R("warp", mapmove, ATCMD_NOCONSOLE),
|
||||
ACMD_DEF(where),
|
||||
ACMD_DEF(jumpto),
|
||||
ACMD_DEF(jump),
|
||||
@ -9689,7 +9696,7 @@ void atcommand_basecommands(void) {
|
||||
ACMD_DEF(guildstorage),
|
||||
ACMD_DEF(option),
|
||||
ACMD_DEF(hide), // + /hide
|
||||
ACMD_DEFR(jobchange, 1),
|
||||
ACMD_DEFR(jobchange, ATCMD_NOCONSOLE),
|
||||
ACMD_DEF(kill),
|
||||
ACMD_DEF(alive),
|
||||
ACMD_DEF(kami),
|
||||
@ -9705,7 +9712,7 @@ void atcommand_basecommands(void) {
|
||||
ACMD_DEF(clearstorage),
|
||||
ACMD_DEF(cleargstorage),
|
||||
ACMD_DEF(clearcart),
|
||||
ACMD_DEF2R("blvl", baselevelup, 1),
|
||||
ACMD_DEF2R("blvl", baselevelup, ATCMD_NOCONSOLE),
|
||||
ACMD_DEF2("jlvl", joblevelup),
|
||||
ACMD_DEF(help),
|
||||
ACMD_DEF(pvpoff),
|
||||
@ -9713,7 +9720,7 @@ void atcommand_basecommands(void) {
|
||||
ACMD_DEF(gvgoff),
|
||||
ACMD_DEF(gvgon),
|
||||
ACMD_DEF(model),
|
||||
ACMD_DEFR(go, 1),
|
||||
ACMD_DEFR(go, ATCMD_NOCONSOLE),
|
||||
ACMD_DEF(monster),
|
||||
ACMD_DEF2("monstersmall", monster),
|
||||
ACMD_DEF2("monsterbig", monster),
|
||||
@ -9746,7 +9753,7 @@ void atcommand_basecommands(void) {
|
||||
ACMD_DEF(doommap),
|
||||
ACMD_DEF(raise),
|
||||
ACMD_DEF(raisemap),
|
||||
ACMD_DEF(kick), // + right click menu for GM "(name) force to quit"
|
||||
ACMD_DEFR(kick,ATCMD_NOAUTOTRADE), // + right click menu for GM "(name) force to quit"
|
||||
ACMD_DEF(kickall),
|
||||
ACMD_DEF(allskill),
|
||||
ACMD_DEF(questskill),
|
||||
@ -9762,11 +9769,11 @@ void atcommand_basecommands(void) {
|
||||
ACMD_DEF(broadcast), // + /b and /nb
|
||||
ACMD_DEF(localbroadcast), // + /lb and /nlb
|
||||
ACMD_DEF(recallall),
|
||||
ACMD_DEFR(reload,2),
|
||||
ACMD_DEFR(reload,ATCMD_NOSCRIPT),
|
||||
ACMD_DEF2("reloaditemdb", reload),
|
||||
ACMD_DEF2("reloadmobdb", reload),
|
||||
ACMD_DEF2("reloadskilldb", reload),
|
||||
ACMD_DEF2R("reloadscript", reload,2),
|
||||
ACMD_DEF2R("reloadscript", reload, ATCMD_NOSCRIPT),
|
||||
ACMD_DEF2("reloadatcommand", reload),
|
||||
ACMD_DEF2("reloadbattleconf", reload),
|
||||
ACMD_DEF2("reloadstatusdb", reload),
|
||||
@ -10057,12 +10064,15 @@ static void atcommand_get_suggestions(struct map_session_data* sd, const char *n
|
||||
dbi_destroy(alias_iter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes an at-command
|
||||
* \param type :
|
||||
/**
|
||||
* Executes an at-command
|
||||
* @param fd
|
||||
* @param sd
|
||||
* @param message
|
||||
* @param type
|
||||
* 0 : script call (atcommand)
|
||||
* 1 : normal player @atcommand
|
||||
* 2 : console
|
||||
* 2 : console (admin:@atcommand)
|
||||
* 3 : script call (useatcmd)
|
||||
*/
|
||||
bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type)
|
||||
@ -10143,7 +10153,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
|
||||
if( x >= 1 || y >= 1 ) { /* we have command */
|
||||
info = get_atcommandinfo_byname(atcommand_checkalias(command + 1));
|
||||
if( !info || info->char_groups[sd->group_pos] == 0 ) /* if we can't use or doesn't exist: don't even display the command failed message */
|
||||
return false;
|
||||
return false;
|
||||
} else
|
||||
return false;/* display as normal message */
|
||||
}
|
||||
@ -10211,17 +10221,20 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
|
||||
}
|
||||
|
||||
//check restriction
|
||||
if(info->restriction){
|
||||
if(info->restriction&1 && type == 2) //console prevent
|
||||
if (info->restriction) {
|
||||
if (info->restriction&ATCMD_NOCONSOLE && type == 2) //console prevent
|
||||
return true;
|
||||
if(info->restriction&2 && (type == 0 || type == 3) ) //scripts prevent
|
||||
if (info->restriction&ATCMD_NOSCRIPT && (type == 0 || type == 3)) //scripts prevent
|
||||
return true;
|
||||
if (info->restriction&ATCMD_NOAUTOTRADE && (type == 0 || type == 3)
|
||||
&& ((*atcmd_msg == atcommand_symbol && sd && sd->state.autotrade) || (ssd && ssd->state.autotrade)))
|
||||
return true;
|
||||
}
|
||||
|
||||
// type == 1 : player invoked
|
||||
if (type == 1) {
|
||||
if ((*command == atcommand_symbol && info->at_groups[sd->group_pos] == 0) ||
|
||||
(*command == charcommand_symbol && info->char_groups[sd->group_pos] == 0) ) {
|
||||
(*command == charcommand_symbol && info->char_groups[sd->group_pos] == 0) ) {
|
||||
return false;
|
||||
}
|
||||
if( pc_isdead(sd) && pc_has_permission(sd,PC_PERM_DISABLE_CMD_DEAD) ) {
|
||||
@ -10232,7 +10245,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
|
||||
|
||||
// Check if target is valid only if confirmed that player can use command.
|
||||
if (*message == charcommand_symbol &&
|
||||
(ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL ) {
|
||||
(ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL ) {
|
||||
sprintf(output, msg_txt(sd,1389), command); // %s failed. Player not found.
|
||||
clif_displaymessage(fd, output);
|
||||
return true;
|
||||
|
@ -18,8 +18,10 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
static DBMap* channel_db; // channels
|
||||
DBMap* channel_get_db(void){ return channel_db; }
|
||||
|
||||
struct Channel_Config channel_config;
|
||||
|
||||
DBMap* channel_get_db(void){ return channel_db; }
|
||||
|
||||
struct chan_banentry {
|
||||
int char_id;
|
||||
@ -163,12 +165,12 @@ int channel_mjoin(struct map_session_data *sd) {
|
||||
if(!sd) return -1;
|
||||
|
||||
if( !map[sd->bl.m].channel ) {
|
||||
map[sd->bl.m].channel = channel_create(Channel_Config.map_chname,NULL,Channel_Config.map_chcolor,CHAN_TYPE_MAP,sd->bl.m);
|
||||
map[sd->bl.m].channel = channel_create(channel_config.map_chname,NULL,channel_config.map_chcolor,CHAN_TYPE_MAP,sd->bl.m);
|
||||
}
|
||||
|
||||
if( !( map[sd->bl.m].channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
|
||||
char mout[60];
|
||||
sprintf(mout, msg_txt(sd,1435),Channel_Config.map_chname,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
|
||||
sprintf(mout, msg_txt(sd,1435),channel_config.map_chname,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
|
||||
clif_disp_onlyself(sd, mout, strlen(mout));
|
||||
}
|
||||
|
||||
@ -219,7 +221,7 @@ int channel_gjoin(struct map_session_data *sd, int flag){
|
||||
|
||||
channel = g->channel;
|
||||
if(!channel){
|
||||
channel = channel_create(Channel_Config.ally_chname,NULL,Channel_Config.ally_chcolor,CHAN_TYPE_ALLY,g->guild_id);
|
||||
channel = channel_create(channel_config.ally_chname,NULL,channel_config.ally_chcolor,CHAN_TYPE_ALLY,g->guild_id);
|
||||
g->channel = channel;
|
||||
channel_ajoin(g);
|
||||
}
|
||||
@ -299,7 +301,7 @@ int channel_pcquit(struct map_session_data *sd, int type){
|
||||
if(!sd) return -1;
|
||||
|
||||
// Leave all chat channels.
|
||||
if(type&(1|2) && Channel_Config.ally_enable && sd->guild){ //quit guild and ally chan
|
||||
if(type&(1|2) && channel_config.ally_enable && sd->guild){ //quit guild and ally chan
|
||||
struct guild *g = sd->guild;
|
||||
if(type&1 && channel_haspc(g->channel,sd)==1){
|
||||
channel_clean(g->channel,sd,0); //leave guild chan
|
||||
@ -315,7 +317,7 @@ int channel_pcquit(struct map_session_data *sd, int type){
|
||||
}
|
||||
}
|
||||
}
|
||||
if(type&4 && Channel_Config.map_enable && channel_haspc(map[sd->bl.m].channel,sd)==1){ //quit map chan
|
||||
if(type&4 && channel_config.map_enable && channel_haspc(map[sd->bl.m].channel,sd)==1){ //quit map chan
|
||||
channel_clean(map[sd->bl.m].channel,sd,0);
|
||||
}
|
||||
if(type&8 && sd->channel_count ) { //quit all chan
|
||||
@ -376,8 +378,8 @@ int channel_chk(char *chname, char *chpass, int type){
|
||||
if ( strlen(chname) < 3 || strlen(chname) > CHAN_NAME_LENGTH )
|
||||
return -2;
|
||||
if( (type&2) && (
|
||||
strcmpi(chname + 1,Channel_Config.map_chname) == 0
|
||||
|| strcmpi(chname + 1,Channel_Config.ally_chname) == 0
|
||||
strcmpi(chname + 1,channel_config.map_chname) == 0
|
||||
|| strcmpi(chname + 1,channel_config.ally_chname) == 0
|
||||
|| strdb_exists(channel_db, chname + 1) )
|
||||
) {
|
||||
return -4;
|
||||
@ -402,16 +404,16 @@ int channel_chk(char *chname, char *chpass, int type){
|
||||
struct Channel* channel_name2channel(char *chname, struct map_session_data *sd, int flag){
|
||||
if(channel_chk(chname, NULL, 1))
|
||||
return NULL;
|
||||
if(sd && strcmpi(chname + 1,Channel_Config.map_chname) == 0){
|
||||
if(sd && strcmpi(chname + 1,channel_config.map_chname) == 0){
|
||||
if(flag&1 && !map[sd->bl.m].channel)
|
||||
map[sd->bl.m].channel = channel_create(Channel_Config.map_chname,NULL,Channel_Config.map_chcolor,CHAN_TYPE_MAP,sd->bl.m);
|
||||
map[sd->bl.m].channel = channel_create(channel_config.map_chname,NULL,channel_config.map_chcolor,CHAN_TYPE_MAP,sd->bl.m);
|
||||
if(flag&2)
|
||||
channel_mjoin(sd);
|
||||
return map[sd->bl.m].channel;
|
||||
}
|
||||
else if(sd && (strcmpi(chname + 1,Channel_Config.ally_chname) == 0) && sd->guild){
|
||||
else if(sd && (strcmpi(chname + 1,channel_config.ally_chname) == 0) && sd->guild){
|
||||
if(flag&1 && !sd->guild->channel)
|
||||
sd->guild->channel = channel_create(Channel_Config.ally_chname,NULL,Channel_Config.ally_chcolor,CHAN_TYPE_ALLY,sd->guild->guild_id);
|
||||
sd->guild->channel = channel_create(channel_config.ally_chname,NULL,channel_config.ally_chcolor,CHAN_TYPE_ALLY,sd->guild->guild_id);
|
||||
if(flag&2)
|
||||
channel_gjoin(sd,3);
|
||||
return sd->guild->channel;
|
||||
@ -472,9 +474,6 @@ int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel){
|
||||
* -1 : fail
|
||||
*/
|
||||
int channel_display_list(struct map_session_data *sd, char *options){
|
||||
struct Channel *channel;
|
||||
char output[128];
|
||||
int k;
|
||||
|
||||
if(!sd || !options)
|
||||
return -1;
|
||||
@ -482,10 +481,13 @@ int channel_display_list(struct map_session_data *sd, char *options){
|
||||
//display availaible colors
|
||||
if( options[0] != '\0' && strcmpi(options,"colors") == 0 ) {
|
||||
char msg[40];
|
||||
unsigned char k;
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,1444)); // ---- Available Colors ----
|
||||
for( k = 0; k < Channel_Config.colors_count; k++ ) {
|
||||
sprintf(msg, msg_txt(sd,1445),Channel_Config.colors_name[k]);// - '%s'
|
||||
clif_colormes(sd,Channel_Config.colors[k],msg);
|
||||
for( k = 0; k < channel_config.colors_count; k++ ) {
|
||||
if (channel_config.colors[k]) {
|
||||
sprintf(msg, msg_txt(sd,1445),channel_config.colors_name[k]);// - '%s'
|
||||
clif_colormes(sd,channel_config.colors[k],msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( options[0] != '\0' && strcmpi(options,"mine") == 0 ) { //display chan I'm into
|
||||
@ -493,8 +495,12 @@ int channel_display_list(struct map_session_data *sd, char *options){
|
||||
if(!sd->channel_count)
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,1476)); // You have not joined any channels.
|
||||
else {
|
||||
unsigned char k;
|
||||
struct Channel *channel;
|
||||
for(k=0; k<sd->channel_count; k++){
|
||||
channel = sd->channels[k];
|
||||
char output[128];
|
||||
if (!(channel = sd->channels[k]))
|
||||
continue;
|
||||
sprintf(output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
|
||||
clif_displaymessage(sd->fd, output);
|
||||
}
|
||||
@ -503,17 +509,20 @@ int channel_display_list(struct map_session_data *sd, char *options){
|
||||
else { //display public chanels
|
||||
DBIterator *iter;
|
||||
bool has_perm = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false;
|
||||
struct Channel *channel;
|
||||
char output[128];
|
||||
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,1410)); // ---- Public Channels ----
|
||||
if( Channel_Config.map_enable ) {
|
||||
sprintf(output, msg_txt(sd,1409), Channel_Config.map_chname, map[sd->bl.m].channel ? db_size(map[sd->bl.m].channel->users) : 0);// - #%s (%d users)
|
||||
if( channel_config.map_enable && map[sd->bl.m].channel ) {
|
||||
sprintf(output, msg_txt(sd,1409), channel_config.map_chname, map[sd->bl.m].channel ? db_size(map[sd->bl.m].channel->users) : 0);// - #%s (%d users)
|
||||
clif_displaymessage(sd->fd, output);
|
||||
}
|
||||
if( Channel_Config.ally_enable && sd->status.guild_id ) {
|
||||
if( channel_config.ally_enable && sd->status.guild_id ) {
|
||||
struct guild *g = sd->guild;
|
||||
if( !g ) return -1; //how can this happen if status.guild_id true ?
|
||||
sprintf(output, msg_txt(sd,1409), Channel_Config.ally_chname, db_size(((struct Channel *)g->channel)->users));// - #%s (%d users)
|
||||
clif_displaymessage(sd->fd, output);
|
||||
if (g && g->channel) {
|
||||
sprintf(output, msg_txt(sd,1409), channel_config.ally_chname, db_size(((struct Channel *)g->channel)->users));// - #%s (%d users)
|
||||
clif_displaymessage(sd->fd, output);
|
||||
}
|
||||
}
|
||||
iter = db_iterator(channel_db);
|
||||
for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) {
|
||||
@ -618,7 +627,7 @@ int channel_pcleave(struct map_session_data *sd, char *chname){
|
||||
return -2; //channel doesn't exist or player don't have it
|
||||
}
|
||||
|
||||
if( !Channel_Config.closing && (channel->opt & CHAN_OPT_ANNOUNCE_JOIN) ) {
|
||||
if( !channel_config.closing && (channel->opt & CHAN_OPT_ANNOUNCE_JOIN) ) {
|
||||
char message[60];
|
||||
sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
|
||||
clif_channel_msg(channel,sd,message,channel->color);
|
||||
@ -726,14 +735,14 @@ int channel_pccolor(struct map_session_data *sd, char *chname, char *color){
|
||||
return -1;
|
||||
}
|
||||
|
||||
ARR_FIND(0,Channel_Config.colors_count,k,( strcmpi(color,Channel_Config.colors_name[k]) == 0 ) );
|
||||
if( k >= Channel_Config.colors_count ) {
|
||||
ARR_FIND(0,channel_config.colors_count,k,( strcmpi(color,channel_config.colors_name[k]) == 0 ) );
|
||||
if( k >= channel_config.colors_count ) {
|
||||
sprintf(output, msg_txt(sd,1411), color);// Unknown color '%s'.
|
||||
clif_displaymessage(sd->fd, output);
|
||||
return -1;
|
||||
}
|
||||
channel->color = k;
|
||||
sprintf(output, msg_txt(sd,1413),chname,Channel_Config.colors_name[k]);// '%s' channel color updated to '%s'.
|
||||
sprintf(output, msg_txt(sd,1413),chname,channel_config.colors_name[k]);// '%s' channel color updated to '%s'.
|
||||
clif_displaymessage(sd->fd, output);
|
||||
return 0;
|
||||
}
|
||||
@ -1031,74 +1040,74 @@ void channel_read_config(void) {
|
||||
|
||||
if( !config_setting_lookup_string(settings, "map_local_channel_name", &map_chname) )
|
||||
map_chname = "map";
|
||||
safestrncpy(Channel_Config.map_chname, map_chname, CHAN_NAME_LENGTH);
|
||||
safestrncpy(channel_config.map_chname, map_chname, CHAN_NAME_LENGTH);
|
||||
|
||||
if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_chname) )
|
||||
ally_chname = "ally";
|
||||
safestrncpy(Channel_Config.ally_chname, ally_chname, CHAN_NAME_LENGTH);
|
||||
safestrncpy(channel_config.ally_chname, ally_chname, CHAN_NAME_LENGTH);
|
||||
|
||||
config_setting_lookup_bool(settings, "map_local_channel", &local_enabled);
|
||||
config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled);
|
||||
|
||||
if( local_enabled )
|
||||
Channel_Config.map_enable = true;
|
||||
channel_config.map_enable = true;
|
||||
if( ally_enabled )
|
||||
Channel_Config.ally_enable = true;
|
||||
channel_config.ally_enable = true;
|
||||
|
||||
config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin);
|
||||
config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin);
|
||||
|
||||
if( local_autojoin )
|
||||
Channel_Config.map_autojoin = true;
|
||||
channel_config.map_autojoin = true;
|
||||
if( ally_autojoin )
|
||||
Channel_Config.ally_autojoin = true;
|
||||
channel_config.ally_autojoin = true;
|
||||
|
||||
config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
|
||||
|
||||
if( allow_user_channel_creation )
|
||||
Channel_Config.user_chenable = true;
|
||||
channel_config.user_chenable = true;
|
||||
|
||||
if( (colors = config_setting_get_member(settings, "colors")) != NULL ) {
|
||||
int color_count = config_setting_length(colors);
|
||||
CREATE( Channel_Config.colors, unsigned long, color_count );
|
||||
CREATE( Channel_Config.colors_name, char *, color_count );
|
||||
CREATE( channel_config.colors, unsigned long, color_count );
|
||||
CREATE( channel_config.colors_name, char *, color_count );
|
||||
for(i = 0; i < color_count; i++) {
|
||||
config_setting_t *color = config_setting_get_elem(colors, i);
|
||||
CREATE( Channel_Config.colors_name[i], char, CHAN_NAME_LENGTH );
|
||||
CREATE( channel_config.colors_name[i], char, CHAN_NAME_LENGTH );
|
||||
|
||||
safestrncpy(Channel_Config.colors_name[i], config_setting_name(color), CHAN_NAME_LENGTH);
|
||||
Channel_Config.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0);
|
||||
Channel_Config.colors[i] = (Channel_Config.colors[i] & 0x0000FF) << 16 | (Channel_Config.colors[i] & 0x00FF00) | (Channel_Config.colors[i] & 0xFF0000) >> 16;//RGB to BGR
|
||||
safestrncpy(channel_config.colors_name[i], config_setting_name(color), CHAN_NAME_LENGTH);
|
||||
channel_config.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0);
|
||||
channel_config.colors[i] = (channel_config.colors[i] & 0x0000FF) << 16 | (channel_config.colors[i] & 0x00FF00) | (channel_config.colors[i] & 0xFF0000) >> 16;//RGB to BGR
|
||||
}
|
||||
Channel_Config.colors_count = color_count;
|
||||
channel_config.colors_count = color_count;
|
||||
}
|
||||
|
||||
config_setting_lookup_string(settings, "map_local_channel_color", &map_color);
|
||||
|
||||
for (k = 0; k < Channel_Config.colors_count; k++) {
|
||||
if( strcmpi(Channel_Config.colors_name[k],map_color) == 0 )
|
||||
for (k = 0; k < channel_config.colors_count; k++) {
|
||||
if( strcmpi(channel_config.colors_name[k],map_color) == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if( k < Channel_Config.colors_count ) {
|
||||
Channel_Config.map_chcolor = k;
|
||||
if( k < channel_config.colors_count ) {
|
||||
channel_config.map_chcolor = k;
|
||||
} else {
|
||||
ShowError("channels.conf: unknown color '%s' for 'map_local_channel_color', disabling '#%s'...\n",map_color,map_chname);
|
||||
Channel_Config.map_enable = false;
|
||||
channel_config.map_enable = false;
|
||||
}
|
||||
|
||||
config_setting_lookup_string(settings, "ally_channel_color", &ally_color);
|
||||
|
||||
for (k = 0; k < Channel_Config.colors_count; k++) {
|
||||
if( strcmpi(Channel_Config.colors_name[k],ally_color) == 0 )
|
||||
for (k = 0; k < channel_config.colors_count; k++) {
|
||||
if( strcmpi(channel_config.colors_name[k],ally_color) == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if( k < Channel_Config.colors_count ) {
|
||||
Channel_Config.ally_chcolor = k;
|
||||
if( k < channel_config.colors_count ) {
|
||||
channel_config.ally_chcolor = k;
|
||||
} else {
|
||||
ShowError("channels.conf: unknown color '%s' for 'ally_channel_color', disabling '#%s'...\n",ally_color,ally_chname);
|
||||
Channel_Config.ally_enable = false;
|
||||
channel_config.ally_enable = false;
|
||||
}
|
||||
|
||||
if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) {
|
||||
@ -1108,15 +1117,15 @@ void channel_read_config(void) {
|
||||
config_setting_t *channel = config_setting_get_elem(channels, i);
|
||||
const char *color = config_setting_get_string_elem(channels,i);
|
||||
char *name = config_setting_name(channel);
|
||||
for (k = 0; k < Channel_Config.colors_count; k++) {
|
||||
if( strcmpi(Channel_Config.colors_name[k],color) == 0 )
|
||||
for (k = 0; k < channel_config.colors_count; k++) {
|
||||
if( strcmpi(channel_config.colors_name[k],color) == 0 )
|
||||
break;
|
||||
}
|
||||
if( k == Channel_Config.colors_count ) {
|
||||
if( k == channel_config.colors_count ) {
|
||||
ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name);
|
||||
continue;
|
||||
}
|
||||
if( strcmpi(name,Channel_Config.map_chname) == 0 || strcmpi(name,Channel_Config.ally_chname) == 0 || strdb_exists(channel_db, name) ) {
|
||||
if( strcmpi(name,channel_config.map_chname) == 0 || strcmpi(name,channel_config.ally_chname) == 0 || strdb_exists(channel_db, name) ) {
|
||||
ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name);
|
||||
continue;
|
||||
}
|
||||
@ -1136,7 +1145,7 @@ void channel_read_config(void) {
|
||||
*/
|
||||
void do_init_channel(void) {
|
||||
channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, CHAN_NAME_LENGTH);
|
||||
Channel_Config.ally_enable = Channel_Config.map_enable = Channel_Config.ally_autojoin = Channel_Config.map_autojoin = false;
|
||||
channel_config.ally_enable = channel_config.map_enable = channel_config.ally_autojoin = channel_config.map_autojoin = false;
|
||||
channel_read_config();
|
||||
}
|
||||
|
||||
@ -1158,12 +1167,12 @@ void do_final_channel(void) {
|
||||
db_destroy(channel_db);
|
||||
|
||||
//delete all color thing
|
||||
if( Channel_Config.colors_count ) {
|
||||
if( channel_config.colors_count ) {
|
||||
int i=0;
|
||||
for(i = 0; i < Channel_Config.colors_count; i++) {
|
||||
aFree(Channel_Config.colors_name[i]);
|
||||
for(i = 0; i < channel_config.colors_count; i++) {
|
||||
aFree(channel_config.colors_name[i]);
|
||||
}
|
||||
aFree(Channel_Config.colors_name);
|
||||
aFree(Channel_Config.colors);
|
||||
aFree(channel_config.colors_name);
|
||||
aFree(channel_config.colors);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ enum Channel_Type {
|
||||
CHAN_TYPE_ALLY = 3, //guild
|
||||
};
|
||||
|
||||
struct {
|
||||
struct Channel_Config {
|
||||
unsigned long *colors; //color avail int list
|
||||
char **colors_name; //colors avail name list
|
||||
unsigned char colors_count; //color avail count
|
||||
@ -36,7 +36,8 @@ struct {
|
||||
bool map_autojoin, ally_autojoin; //do user auto join in mapchange, guildjoin ?
|
||||
char map_chname[CHAN_NAME_LENGTH], ally_chname[CHAN_NAME_LENGTH]; //channel name for map and ally
|
||||
bool closing; //server is closing
|
||||
} Channel_Config;
|
||||
};
|
||||
extern struct Channel_Config channel_config;
|
||||
|
||||
struct Channel {
|
||||
char name[CHAN_NAME_LENGTH]; //channel name
|
||||
|
@ -286,7 +286,6 @@ int chrif_save(struct map_session_data *sd, int flag) {
|
||||
pc_makesavestatus(sd);
|
||||
|
||||
if (flag && sd->state.active) { //Store player data which is quitting
|
||||
//FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
|
||||
if (chrif_isconnected()) {
|
||||
chrif_save_scdata(sd);
|
||||
chrif_skillcooldown_save(sd);
|
||||
|
@ -5657,7 +5657,7 @@ void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char
|
||||
WFIFOW(sd->fd,0) = 0x2C1;
|
||||
WFIFOW(sd->fd,2) = msg_len + 12;
|
||||
WFIFOL(sd->fd,4) = 0;
|
||||
WFIFOL(sd->fd,8) = Channel_Config.colors[color];
|
||||
WFIFOL(sd->fd,8) = channel_config.colors[color];
|
||||
safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
|
||||
|
||||
iter = db_iterator(channel->users);
|
||||
@ -9784,7 +9784,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
sd->state.changemap = false;
|
||||
|
||||
// Instances do not need their own channels
|
||||
if( Channel_Config.map_enable && Channel_Config.map_autojoin && !map[sd->bl.m].flag.chmautojoin && !map[sd->bl.m].instance_id )
|
||||
if( channel_config.map_enable && channel_config.map_autojoin && !map[sd->bl.m].flag.chmautojoin && !map[sd->bl.m].instance_id )
|
||||
channel_mjoin(sd); //join new map
|
||||
} else if (sd->guild && (battle_config.guild_notice_changemap == 2 || guild_notice))
|
||||
clif_guild_notice(sd, sd->guild); // Displays at end
|
||||
|
@ -511,7 +511,7 @@ int guild_recv_info(struct guild *sg) {
|
||||
if( sd==NULL )
|
||||
continue;
|
||||
sd->guild = g;
|
||||
if(Channel_Config.ally_autojoin ) {
|
||||
if(channel_config.ally_autojoin ) {
|
||||
channel_gjoin(sd,3); //make all member join guildchan+allieschan
|
||||
}
|
||||
|
||||
@ -676,7 +676,7 @@ void guild_member_joined(struct map_session_data *sd) {
|
||||
g->member[i].sd = sd;
|
||||
sd->guild = g;
|
||||
|
||||
if( Channel_Config.ally_enable && Channel_Config.ally_autojoin ) {
|
||||
if( channel_config.ally_enable && channel_config.ally_autojoin ) {
|
||||
channel_gjoin(sd,3);
|
||||
}
|
||||
}
|
||||
@ -1673,7 +1673,7 @@ int guild_broken(int guild_id,int flag) {
|
||||
guild_db->foreach(guild_db,guild_broken_sub,guild_id);
|
||||
castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
|
||||
guild_storage_delete(guild_id);
|
||||
if( Channel_Config.ally_enable ) {
|
||||
if( channel_config.ally_enable ) {
|
||||
channel_delete(g->channel);
|
||||
}
|
||||
idb_remove(guild_db,guild_id);
|
||||
|
@ -3832,7 +3832,7 @@ void do_final(void)
|
||||
struct s_mapiterator* iter;
|
||||
|
||||
ShowStatus("Terminating...\n");
|
||||
Channel_Config.closing = true;
|
||||
channel_config.closing = true;
|
||||
|
||||
//Ladies and babies first.
|
||||
iter = mapit_getallusers();
|
||||
|
@ -298,10 +298,19 @@ enum bl_type {
|
||||
BL_ALL = 0xFFF,
|
||||
};
|
||||
|
||||
//For common mapforeach calls. Since pets cannot be affected, they aren't included here yet.
|
||||
/// For common mapforeach calls. Since pets cannot be affected, they aren't included here yet.
|
||||
#define BL_CHAR (BL_PC|BL_MOB|BL_HOM|BL_MER|BL_ELEM)
|
||||
|
||||
enum npc_subtype { WARP, SHOP, SCRIPT, CASHSHOP, ITEMSHOP, POINTSHOP, TOMB };
|
||||
/// NPC Subtype
|
||||
enum npc_subtype {
|
||||
NPCTYPE_WARP, /// Warp
|
||||
NPCTYPE_SHOP, /// Shop
|
||||
NPCTYPE_SCRIPT, /// Script
|
||||
NPCTYPE_CASHSHOP, /// Cashshop
|
||||
NPCTYPE_ITEMSHOP, /// Itemshop
|
||||
NPCTYPE_POINTSHOP, /// Pointshop
|
||||
NPCTYPE_TOMB /// Monster tomb
|
||||
};
|
||||
|
||||
enum e_race {
|
||||
RC_NONE_ = -1, //don't give us bonus
|
||||
|
@ -149,7 +149,7 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
|
||||
|
||||
nd->class_ = 565;
|
||||
nd->speed = 200;
|
||||
nd->subtype = TOMB;
|
||||
nd->subtype = NPCTYPE_TOMB;
|
||||
|
||||
nd->u.tomb.md = md;
|
||||
nd->u.tomb.kill_time = time;
|
||||
@ -1192,7 +1192,7 @@ static int mob_warpchase_sub(struct block_list *bl,va_list ap) {
|
||||
|
||||
nd = (TBL_NPC*) bl;
|
||||
|
||||
if(nd->subtype != WARP)
|
||||
if(nd->subtype != NPCTYPE_WARP)
|
||||
return 0; //Not a warp
|
||||
|
||||
if(nd->u.warp.mapindex != map[target->m].index)
|
||||
|
148
src/map/npc.c
148
src/map/npc.c
@ -128,10 +128,10 @@ int npc_isnear_sub(struct block_list* bl, va_list args) {
|
||||
|
||||
if (idx > 0 && skill_db[idx].unit_nonearnpc_type) {
|
||||
while (1) {
|
||||
if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&4 && nd->subtype == SCRIPT) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&8 && nd->subtype == TOMB) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == NPCTYPE_WARP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == NPCTYPE_SHOP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&4 && nd->subtype == NPCTYPE_SCRIPT) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&8 && nd->subtype == NPCTYPE_TOMB) break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -944,11 +944,11 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
|
||||
}
|
||||
|
||||
switch(map[m].npc[i]->subtype) {
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
xs=map[m].npc[i]->u.warp.xs;
|
||||
ys=map[m].npc[i]->u.warp.ys;
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
xs=map[m].npc[i]->u.scr.xs;
|
||||
ys=map[m].npc[i]->u.scr.ys;
|
||||
break;
|
||||
@ -966,14 +966,14 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
|
||||
return 1;
|
||||
}
|
||||
switch(map[m].npc[i]->subtype) {
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
if (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]) || pc_isdead(sd))
|
||||
break; // hidden or dead chars cannot use warps
|
||||
pc_setpos(sd,map[m].npc[i]->u.warp.mapindex,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,CLR_OUTSIGHT);
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
for (j = i; j < map[m].npc_num; j++) {
|
||||
if (map[m].npc[j]->subtype != WARP) {
|
||||
if (map[m].npc[j]->subtype != NPCTYPE_WARP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1023,13 +1023,13 @@ int npc_touch_areanpc2(struct mob_data *md)
|
||||
|
||||
switch( map[m].npc[i]->subtype )
|
||||
{
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
if( !( battle_config.mob_warp&1 ) )
|
||||
continue;
|
||||
xs = map[m].npc[i]->u.warp.xs;
|
||||
ys = map[m].npc[i]->u.warp.ys;
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
xs = map[m].npc[i]->u.scr.xs;
|
||||
ys = map[m].npc[i]->u.scr.ys;
|
||||
break;
|
||||
@ -1041,14 +1041,14 @@ int npc_touch_areanpc2(struct mob_data *md)
|
||||
{ // In the npc touch area
|
||||
switch( map[m].npc[i]->subtype )
|
||||
{
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
xs = map_mapindex2mapid(map[m].npc[i]->u.warp.mapindex);
|
||||
if( m < 0 )
|
||||
break; // Cannot Warp between map servers
|
||||
if( unit_warp(&md->bl, xs, map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, CLR_OUTSIGHT) == 0 )
|
||||
return 1; // Warped
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
if( map[m].npc[i]->bl.id == md->areanpc_id )
|
||||
break; // Already touch this NPC
|
||||
snprintf(eventname, ARRAYLENGTH(eventname), "%s::OnTouchNPC", map[m].npc[i]->exname);
|
||||
@ -1102,13 +1102,13 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
|
||||
|
||||
switch(map[m].npc[i]->subtype)
|
||||
{
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
if (!(flag&1))
|
||||
continue;
|
||||
xs=map[m].npc[i]->u.warp.xs;
|
||||
ys=map[m].npc[i]->u.warp.ys;
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
if (!(flag&2))
|
||||
continue;
|
||||
xs=map[m].npc[i]->u.scr.xs;
|
||||
@ -1218,18 +1218,18 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
|
||||
return 1;
|
||||
|
||||
switch(nd->subtype) {
|
||||
case SHOP:
|
||||
case ITEMSHOP:
|
||||
case POINTSHOP:
|
||||
case NPCTYPE_SHOP:
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
case NPCTYPE_POINTSHOP:
|
||||
clif_npcbuysell(sd,nd->bl.id);
|
||||
break;
|
||||
case CASHSHOP:
|
||||
case NPCTYPE_CASHSHOP:
|
||||
clif_cashshop_show(sd,nd);
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
|
||||
break;
|
||||
case TOMB:
|
||||
case NPCTYPE_TOMB:
|
||||
run_tomb(sd,nd);
|
||||
break;
|
||||
}
|
||||
@ -1289,7 +1289,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
|
||||
if ((nd = npc_checknear(sd,map_id2bl(id))) == NULL)
|
||||
return 1;
|
||||
|
||||
if (nd->subtype != SHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP) {
|
||||
if (nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP) {
|
||||
ShowError("no such shop npc : %d\n",id);
|
||||
if (sd->npc_id == id)
|
||||
sd->npc_id=0;
|
||||
@ -1301,7 +1301,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nd->subtype == ITEMSHOP) {
|
||||
if (nd->subtype == NPCTYPE_ITEMSHOP) {
|
||||
char output[CHAT_SIZE_MAX];
|
||||
struct item_data *itd = itemdb_exists(nd->u.shop.itemshop_nameid);
|
||||
memset(output,'\0',sizeof(output));
|
||||
@ -1309,7 +1309,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
|
||||
sprintf(output,msg_txt(sd,714),itd->jname,itd->nameid); // Item Shop List: %s (%hu)
|
||||
clif_broadcast(&sd->bl,output,strlen(output) + 1,BC_BLUE,SELF);
|
||||
}
|
||||
} else if (nd->subtype == POINTSHOP) {
|
||||
} else if (nd->subtype == NPCTYPE_POINTSHOP) {
|
||||
char output[CHAT_SIZE_MAX];
|
||||
memset(output,'\0',sizeof(output));
|
||||
sprintf(output,msg_txt(sd,715),nd->u.shop.pointshop_str); // Point Shop List: '%s'
|
||||
@ -1336,7 +1336,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
|
||||
unsigned short nameid;
|
||||
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
|
||||
|
||||
if( !nd || nd->subtype != CASHSHOP )
|
||||
if( !nd || nd->subtype != NPCTYPE_CASHSHOP )
|
||||
return 1;
|
||||
|
||||
if( sd->state.trading )
|
||||
@ -1453,7 +1453,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
|
||||
if( points < 0 )
|
||||
return 6;
|
||||
|
||||
if( !nd || nd->subtype != CASHSHOP )
|
||||
if( !nd || nd->subtype != NPCTYPE_CASHSHOP )
|
||||
return 1;
|
||||
|
||||
if( sd->state.trading )
|
||||
@ -1538,7 +1538,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
nd = npc_checknear(sd,map_id2bl(sd->npc_shopid));
|
||||
if( nd == NULL )
|
||||
return 3;
|
||||
if( nd->subtype != SHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP )
|
||||
if( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP )
|
||||
return 3;
|
||||
|
||||
z = 0;
|
||||
@ -1602,11 +1602,11 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
return npc_buylist_sub(sd,n,item_list,nd->master_nd);
|
||||
|
||||
switch(nd->subtype) {
|
||||
case SHOP:
|
||||
case NPCTYPE_SHOP:
|
||||
if (z > (double)sd->status.zeny)
|
||||
return 1; // Not enough Zeny
|
||||
break;
|
||||
case ITEMSHOP:
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
for (k = 0; k < MAX_INVENTORY; k++) {
|
||||
if (sd->status.inventory[k].nameid == nd->u.shop.itemshop_nameid)
|
||||
count += sd->status.inventory[k].amount;
|
||||
@ -1619,7 +1619,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case POINTSHOP:
|
||||
case NPCTYPE_POINTSHOP:
|
||||
switch(nd->u.shop.pointshop_str[0]) {
|
||||
case '#':
|
||||
if (nd->u.shop.pointshop_str[1] == '#')
|
||||
@ -1646,13 +1646,13 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
return 3; // Not enough space to store items
|
||||
|
||||
switch(nd->subtype) {
|
||||
case SHOP:
|
||||
case NPCTYPE_SHOP:
|
||||
pc_payzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
|
||||
break;
|
||||
case ITEMSHOP:
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), (int)z, 0, 0, LOG_TYPE_NPC);
|
||||
break;
|
||||
case POINTSHOP:
|
||||
case NPCTYPE_POINTSHOP:
|
||||
switch(nd->u.shop.pointshop_str[0]) {
|
||||
case '#':
|
||||
if (nd->u.shop.pointshop_str[1] == '#')
|
||||
@ -1701,7 +1701,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
}
|
||||
}
|
||||
|
||||
if (nd->subtype == POINTSHOP) {
|
||||
if (nd->subtype == NPCTYPE_POINTSHOP) {
|
||||
sprintf(output,msg_txt(sd,716),nd->u.shop.pointshop_str,count - (int)z); // Your '%s' now: %d
|
||||
clif_disp_onlyself(sd,output,strlen(output)+1);
|
||||
}
|
||||
@ -1782,7 +1782,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
nullpo_retr(1, item_list);
|
||||
|
||||
if( ( nd = npc_checknear(sd, map_id2bl(sd->npc_shopid)) ) == NULL
|
||||
|| ( nd->subtype != SHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP ) )
|
||||
|| ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -1877,6 +1877,8 @@ int npc_remove_map(struct npc_data* nd)
|
||||
if(nd->bl.prev == NULL || nd->bl.m < 0)
|
||||
return 1; //Not assigned to a map.
|
||||
m = nd->bl.m;
|
||||
if (nd->subtype == NPCTYPE_SCRIPT)
|
||||
skill_clear_unitgroup(&nd->bl);
|
||||
clif_clearunit_area(&nd->bl,CLR_RESPAWN);
|
||||
npc_unsetcells(nd);
|
||||
map_delblock(&nd->bl);
|
||||
@ -1955,9 +1957,9 @@ int npc_unload(struct npc_data* nd, bool single) {
|
||||
if( single && nd->bl.m != -1 )
|
||||
map_remove_questinfo(nd->bl.m, nd);
|
||||
|
||||
if( (nd->subtype == SHOP || nd->subtype == CASHSHOP || nd->subtype == ITEMSHOP || nd->subtype == POINTSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
|
||||
if( (nd->subtype == NPCTYPE_SHOP || nd->subtype == NPCTYPE_CASHSHOP || nd->subtype == NPCTYPE_ITEMSHOP || nd->subtype == NPCTYPE_POINTSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
|
||||
aFree(nd->u.shop.shop_item);
|
||||
else if( nd->subtype == SCRIPT ) {
|
||||
else if( nd->subtype == NPCTYPE_SCRIPT ) {
|
||||
struct s_mapiterator* iter;
|
||||
struct block_list* bl;
|
||||
|
||||
@ -2267,7 +2269,7 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
|
||||
nd->u.warp.xs = xs;
|
||||
nd->u.warp.ys = xs;
|
||||
nd->bl.type = BL_NPC;
|
||||
nd->subtype = WARP;
|
||||
nd->subtype = NPCTYPE_WARP;
|
||||
npc_setcells(nd);
|
||||
if(map_addblock(&nd->bl))
|
||||
return NULL;
|
||||
@ -2344,7 +2346,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
|
||||
nd->u.warp.ys = ys;
|
||||
npc_warp++;
|
||||
nd->bl.type = BL_NPC;
|
||||
nd->subtype = WARP;
|
||||
nd->subtype = NPCTYPE_WARP;
|
||||
npc_setcells(nd);
|
||||
if(map_addblock(&nd->bl)) //couldn't add on map
|
||||
return strchr(start,'\n');
|
||||
@ -2405,19 +2407,19 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
}
|
||||
|
||||
if( !strcasecmp(w2,"cashshop") )
|
||||
type = CASHSHOP;
|
||||
type = NPCTYPE_CASHSHOP;
|
||||
else if( !strcasecmp(w2,"itemshop") )
|
||||
type = ITEMSHOP;
|
||||
type = NPCTYPE_ITEMSHOP;
|
||||
else if( !strcasecmp(w2,"pointshop") )
|
||||
type = POINTSHOP;
|
||||
type = NPCTYPE_POINTSHOP;
|
||||
else
|
||||
type = SHOP;
|
||||
type = NPCTYPE_SHOP;
|
||||
|
||||
p = strchr(w4,',');
|
||||
memset(point_str,'\0',sizeof(point_str));
|
||||
|
||||
switch(type) {
|
||||
case ITEMSHOP: {
|
||||
case NPCTYPE_ITEMSHOP: {
|
||||
if (sscanf(p,",%hu:%d,",&nameid,&is_discount) < 1) {
|
||||
ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
|
||||
return strchr(start,'\n'); // skip and continue
|
||||
@ -2429,7 +2431,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
p = strchr(p+1,',');
|
||||
break;
|
||||
}
|
||||
case POINTSHOP: {
|
||||
case NPCTYPE_POINTSHOP: {
|
||||
if (sscanf(p, ",%32[^,:]:%d,",point_str,&is_discount) < 1) {
|
||||
ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
|
||||
return strchr(start,'\n'); // skip and continue
|
||||
@ -2473,14 +2475,14 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
continue;
|
||||
}
|
||||
if( value < 0 ) {
|
||||
if( type == SHOP ) value = id->value_buy;
|
||||
if( type == NPCTYPE_SHOP ) value = id->value_buy;
|
||||
else value = 0; // Cashshop doesn't have a "buy price" in the item_db
|
||||
}
|
||||
if( (type == SHOP || type == ITEMSHOP || type == POINTSHOP) && value == 0 ) { // NPC selling items for free!
|
||||
if( (type == NPCTYPE_SHOP || type == NPCTYPE_ITEMSHOP || type == NPCTYPE_POINTSHOP) && value == 0 ) { // NPC selling items for free!
|
||||
ShowWarning("npc_parse_shop: Item %s [%hu] is being sold for FREE in file '%s', line '%d'.\n",
|
||||
id->name, nameid2, filepath, strline(buffer,start-buffer));
|
||||
}
|
||||
if( type == SHOP && value*0.75 < id->value_sell*1.24 ) { // Exploit possible: you can buy and sell back with profit
|
||||
if( type == NPCTYPE_SHOP && value*0.75 < id->value_sell*1.24 ) { // Exploit possible: you can buy and sell back with profit
|
||||
ShowWarning("npc_parse_shop: Item %s [%hu] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
|
||||
id->name, nameid2, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer));
|
||||
}
|
||||
@ -2504,9 +2506,9 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
return strchr(start,'\n');// continue
|
||||
}
|
||||
|
||||
if (type != SHOP) {
|
||||
if (type == ITEMSHOP) nd->u.shop.itemshop_nameid = nameid; // Item shop currency
|
||||
else if (type == POINTSHOP) safestrncpy(nd->u.shop.pointshop_str,point_str,strlen(point_str)+1); // Point shop currency
|
||||
if (type != NPCTYPE_SHOP) {
|
||||
if (type == NPCTYPE_ITEMSHOP) nd->u.shop.itemshop_nameid = nameid; // Item shop currency
|
||||
else if (type == NPCTYPE_POINTSHOP) safestrncpy(nd->u.shop.pointshop_str,point_str,strlen(point_str)+1); // Point shop currency
|
||||
nd->u.shop.discount = is_discount;
|
||||
}
|
||||
nd->bl.prev = nd->bl.next = NULL;
|
||||
@ -2547,11 +2549,11 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
* @return bool 'true' is discountable, 'false' otherwise
|
||||
*/
|
||||
bool npc_shop_discount(enum npc_subtype type, bool discount) {
|
||||
if (type == SHOP || (type != SHOP && discount))
|
||||
if (type == NPCTYPE_SHOP || (type != NPCTYPE_SHOP && discount))
|
||||
return true;
|
||||
|
||||
if( (type == ITEMSHOP && battle_config.discount_item_point_shop&1) ||
|
||||
(type == POINTSHOP && battle_config.discount_item_point_shop&2) )
|
||||
if( (type == NPCTYPE_ITEMSHOP && battle_config.discount_item_point_shop&1) ||
|
||||
(type == NPCTYPE_POINTSHOP && battle_config.discount_item_point_shop&2) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -2754,7 +2756,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
|
||||
|
||||
++npc_script;
|
||||
nd->bl.type = BL_NPC;
|
||||
nd->subtype = SCRIPT;
|
||||
nd->subtype = NPCTYPE_SCRIPT;
|
||||
|
||||
if( m >= 0 )
|
||||
{
|
||||
@ -2847,7 +2849,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
type = dnd->subtype;
|
||||
|
||||
// get placement
|
||||
if( (type == SHOP || type == CASHSHOP || type == ITEMSHOP || type == POINTSHOP || type == SCRIPT) && strcmp(w1, "-") == 0 ) {// floating shop/chashshop/itemshop/pointshop/script
|
||||
if( (type == NPCTYPE_SHOP || type == NPCTYPE_CASHSHOP || type == NPCTYPE_ITEMSHOP || type == NPCTYPE_POINTSHOP || type == NPCTYPE_SCRIPT) && strcmp(w1, "-") == 0 ) {// floating shop/chashshop/itemshop/pointshop/script
|
||||
x = y = dir = 0;
|
||||
m = -1;
|
||||
} else {
|
||||
@ -2864,9 +2866,9 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
ShowError("npc_parse_duplicate: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
|
||||
}
|
||||
|
||||
if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
|
||||
else if( type == SCRIPT && sscanf(w4, "%*[^,],%d,%d", &xs, &ys) == 2);// <sprite id>,<triggerX>,<triggerY>
|
||||
else if( type == WARP ) {
|
||||
if( type == NPCTYPE_WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
|
||||
else if( type == NPCTYPE_SCRIPT && sscanf(w4, "%*[^,],%d,%d", &xs, &ys) == 2);// <sprite id>,<triggerX>,<triggerY>
|
||||
else if( type == NPCTYPE_WARP ) {
|
||||
ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
|
||||
return end;// next line, try to continue
|
||||
}
|
||||
@ -2885,7 +2887,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
nd->bl.type = BL_NPC;
|
||||
nd->subtype = (enum npc_subtype)type;
|
||||
switch( type ) {
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
++npc_script;
|
||||
nd->u.scr.xs = xs;
|
||||
nd->u.scr.ys = ys;
|
||||
@ -2894,16 +2896,16 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
|
||||
break;
|
||||
|
||||
case SHOP:
|
||||
case CASHSHOP:
|
||||
case ITEMSHOP:
|
||||
case POINTSHOP:
|
||||
case NPCTYPE_SHOP:
|
||||
case NPCTYPE_CASHSHOP:
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
case NPCTYPE_POINTSHOP:
|
||||
++npc_shop;
|
||||
nd->u.shop.shop_item = dnd->u.shop.shop_item;
|
||||
nd->u.shop.count = dnd->u.shop.count;
|
||||
break;
|
||||
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
++npc_warp;
|
||||
if( !battle_config.warp_point_debug )
|
||||
nd->class_ = WARP_CLASS;
|
||||
@ -2937,7 +2939,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
}
|
||||
strdb_put(npcname_db, nd->exname, nd);
|
||||
|
||||
if( type != SCRIPT )
|
||||
if( type != NPCTYPE_SCRIPT )
|
||||
return end;
|
||||
|
||||
//-----------------------------------------
|
||||
@ -2970,7 +2972,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( snd->subtype == WARP ) { // Adjust destination, if instanced
|
||||
if( snd->subtype == NPCTYPE_WARP ) { // Adjust destination, if instanced
|
||||
struct npc_data *wnd = NULL; // New NPC
|
||||
struct instance_data *im = &instance_data[map[m].instance_id];
|
||||
int dm = map_mapindex2mapid(snd->u.warp.mapindex), imap = 0, i;
|
||||
@ -3007,7 +3009,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
|
||||
wnd->u.warp.xs = snd->u.warp.xs;
|
||||
wnd->u.warp.ys = snd->u.warp.ys;
|
||||
wnd->bl.type = BL_NPC;
|
||||
wnd->subtype = WARP;
|
||||
wnd->subtype = NPCTYPE_WARP;
|
||||
npc_setcells(wnd);
|
||||
if(map_addblock(&wnd->bl))
|
||||
return 1;
|
||||
@ -3057,11 +3059,11 @@ void npc_setcells(struct npc_data* nd)
|
||||
|
||||
switch(nd->subtype)
|
||||
{
|
||||
case WARP:
|
||||
case NPCTYPE_WARP:
|
||||
xs = nd->u.warp.xs;
|
||||
ys = nd->u.warp.ys;
|
||||
break;
|
||||
case SCRIPT:
|
||||
case NPCTYPE_SCRIPT:
|
||||
xs = nd->u.scr.xs;
|
||||
ys = nd->u.scr.ys;
|
||||
break;
|
||||
@ -3095,7 +3097,7 @@ void npc_unsetcells(struct npc_data* nd)
|
||||
int16 m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
|
||||
int i,j, x0, x1, y0, y1;
|
||||
|
||||
if (nd->subtype == WARP) {
|
||||
if (nd->subtype == NPCTYPE_WARP) {
|
||||
xs = nd->u.warp.xs;
|
||||
ys = nd->u.warp.ys;
|
||||
} else {
|
||||
@ -4167,7 +4169,7 @@ void do_final_npc(void) {
|
||||
static void npc_debug_warps_sub(struct npc_data* nd)
|
||||
{
|
||||
int16 m;
|
||||
if (nd->bl.type != BL_NPC || nd->subtype != WARP || nd->bl.m < 0)
|
||||
if (nd->bl.type != BL_NPC || nd->subtype != NPCTYPE_WARP || nd->bl.m < 0)
|
||||
return;
|
||||
|
||||
m = map_mapindex2mapid(nd->u.warp.mapindex);
|
||||
@ -4256,7 +4258,7 @@ void do_init_npc(void){
|
||||
|
||||
npc_script++;
|
||||
fake_nd->bl.type = BL_NPC;
|
||||
fake_nd->subtype = SCRIPT;
|
||||
fake_nd->subtype = NPCTYPE_SCRIPT;
|
||||
|
||||
strdb_put(npcname_db, fake_nd->exname, fake_nd);
|
||||
fake_nd->u.scr.timerid = INVALID_TIMER;
|
||||
|
@ -467,6 +467,4 @@ void pc_groups_reload(void) {
|
||||
pc_group_pc_load(sd);
|
||||
}
|
||||
mapit_free(iter);
|
||||
|
||||
|
||||
}
|
||||
|
@ -11814,7 +11814,7 @@ BUILDIN_FUNC(flagemblem)
|
||||
nd = (TBL_NPC*)map_id2nd(st->oid);
|
||||
if( nd == NULL ) {
|
||||
ShowError("script:flagemblem: npc %d not found\n", st->oid);
|
||||
} else if( nd->subtype != SCRIPT ) {
|
||||
} else if( nd->subtype != NPCTYPE_SCRIPT ) {
|
||||
ShowError("script:flagemblem: unexpected subtype %d for npc %d '%s'\n", nd->subtype, st->oid, nd->exname);
|
||||
} else {
|
||||
bool changed = ( nd->u.scr.guild_id != g_id )?true:false;
|
||||
@ -13242,10 +13242,9 @@ BUILDIN_FUNC(nude)
|
||||
}
|
||||
|
||||
int atcommand_sub(struct script_state* st,int type) {
|
||||
TBL_PC dummy_sd;
|
||||
TBL_PC* sd;
|
||||
TBL_PC *sd, dummy_sd;
|
||||
int fd;
|
||||
const char* cmd;
|
||||
const char *cmd;
|
||||
|
||||
cmd = script_getstr(st,2);
|
||||
|
||||
@ -13257,19 +13256,23 @@ int atcommand_sub(struct script_state* st,int type) {
|
||||
fd = 0;
|
||||
|
||||
memset(&dummy_sd, 0, sizeof(TBL_PC));
|
||||
if (st->oid)
|
||||
{
|
||||
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);
|
||||
sd->mapindex = (bl->m > 0) ? bl->m : mapindex_name2id(MAP_DEFAULT);
|
||||
}
|
||||
|
||||
// Init Group ID, Level, & permissions
|
||||
sd->group_id = sd->group_level = 99;
|
||||
sd->permissions |= PC_PERM_ALLPERMISSION;
|
||||
}
|
||||
|
||||
if (!is_atcommand(fd, sd, cmd, type)) {
|
||||
ShowWarning("script: buildin_atcommand: failed to execute command '%s'\n", cmd);
|
||||
ShowWarning("buildin_atcommand: failed to execute command '%s'\n", cmd);
|
||||
script_reportsrc(st);
|
||||
return 1;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -15473,14 +15476,14 @@ BUILDIN_FUNC(callshop)
|
||||
if( script_hasdata(st,3) )
|
||||
flag = script_getnum(st,3);
|
||||
nd = npc_name2id(shopname);
|
||||
if( !nd || nd->bl.type != BL_NPC || (nd->subtype != SHOP && nd->subtype != CASHSHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP) )
|
||||
if( !nd || nd->bl.type != BL_NPC || (nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP) )
|
||||
{
|
||||
ShowError("buildin_callshop: Shop [%s] not found (or NPC is not shop type)\n", shopname);
|
||||
script_pushint(st,0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( nd->subtype == SHOP || nd->subtype == ITEMSHOP || nd->subtype == POINTSHOP )
|
||||
if( nd->subtype == NPCTYPE_SHOP || nd->subtype == NPCTYPE_ITEMSHOP || nd->subtype == NPCTYPE_POINTSHOP )
|
||||
{
|
||||
// flag the user as using a valid script call for opening the shop (for floating NPCs)
|
||||
sd->state.callshop = 1;
|
||||
@ -15507,7 +15510,7 @@ BUILDIN_FUNC(npcshopitem)
|
||||
int n, i;
|
||||
int amount;
|
||||
|
||||
if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP ) )
|
||||
if( !nd || ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
|
||||
{ //Not found.
|
||||
script_pushint(st,0);
|
||||
return 0;
|
||||
@ -15536,7 +15539,7 @@ BUILDIN_FUNC(npcshopadditem)
|
||||
int n, i;
|
||||
int amount;
|
||||
|
||||
if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP ) )
|
||||
if( !nd || ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
|
||||
{ //Not found.
|
||||
script_pushint(st,0);
|
||||
return 0;
|
||||
@ -15567,7 +15570,7 @@ BUILDIN_FUNC(npcshopdelitem)
|
||||
int amount;
|
||||
int size;
|
||||
|
||||
if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP ) )
|
||||
if( !nd || ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
|
||||
{ //Not found.
|
||||
script_pushint(st,0);
|
||||
return 0;
|
||||
@ -15606,7 +15609,7 @@ BUILDIN_FUNC(npcshopattach)
|
||||
if( script_hasdata(st,3) )
|
||||
flag = script_getnum(st,3);
|
||||
|
||||
if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP && nd->subtype != ITEMSHOP && nd->subtype != POINTSHOP ) )
|
||||
if( !nd || ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
|
||||
{ //Not found.
|
||||
script_pushint(st,0);
|
||||
return 0;
|
||||
@ -16426,7 +16429,7 @@ BUILDIN_FUNC(getvariableofnpc)
|
||||
}
|
||||
|
||||
nd = npc_name2id(script_getstr(st,3));
|
||||
if( nd == NULL || nd->subtype != SCRIPT || nd->u.scr.script == NULL )
|
||||
if( nd == NULL || nd->subtype != NPCTYPE_SCRIPT || nd->u.scr.script == NULL )
|
||||
{// NPC not found or has no script
|
||||
ShowError("script:getvariableofnpc: can't find npc %s\n", script_getstr(st,3));
|
||||
script_pushnil(st);
|
||||
@ -16455,10 +16458,9 @@ BUILDIN_FUNC(warpportal)
|
||||
struct block_list* bl;
|
||||
|
||||
bl = map_id2bl(st->oid);
|
||||
if( bl == NULL )
|
||||
{
|
||||
ShowError("script:warpportal: npc is needed\n");
|
||||
return 1;
|
||||
if( bl == NULL ) {
|
||||
ShowError("buildin_warpportal: NPC is needed\n");
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
spx = script_getnum(st,2);
|
||||
@ -16467,12 +16469,14 @@ BUILDIN_FUNC(warpportal)
|
||||
tpx = script_getnum(st,5);
|
||||
tpy = script_getnum(st,6);
|
||||
|
||||
if( mapindex == 0 )
|
||||
return 0;// map not found
|
||||
if( mapindex == 0 ) {
|
||||
ShowError("buildin_warpportal: Target map not found %s.\n", script_getstr(st, 4));
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
group = skill_unitsetting(bl, AL_WARP, 4, spx, spy, 0);
|
||||
if( group == NULL )
|
||||
return 0;// failed
|
||||
return SCRIPT_CMD_FAILURE;// failed
|
||||
group->val1 = (group->val1<<16)|(short)0;
|
||||
group->val2 = (tpx<<16) | tpy;
|
||||
group->val3 = mapindex;
|
||||
|
@ -6734,7 +6734,7 @@ int status_get_guild_id(struct block_list *bl)
|
||||
return ((TBL_MER*)bl)->master->status.guild_id;
|
||||
break;
|
||||
case BL_NPC:
|
||||
if (((TBL_NPC*)bl)->subtype == SCRIPT)
|
||||
if (((TBL_NPC*)bl)->subtype == NPCTYPE_SCRIPT)
|
||||
return ((TBL_NPC*)bl)->u.scr.guild_id;
|
||||
break;
|
||||
case BL_SKILL:
|
||||
@ -6781,7 +6781,7 @@ int status_get_emblem_id(struct block_list *bl)
|
||||
return ((TBL_MER*)bl)->master->guild_emblem_id;
|
||||
break;
|
||||
case BL_NPC:
|
||||
if (((TBL_NPC*)bl)->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
|
||||
if (((TBL_NPC*)bl)->subtype == NPCTYPE_SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
|
||||
struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
|
||||
if (g)
|
||||
return g->emblem_id;
|
||||
|
@ -18,7 +18,7 @@ extern const short dirx[8]; ///lookup to know where will move to x according dir
|
||||
extern const short diry[8]; ///lookup to know where will move to y according dir
|
||||
|
||||
struct unit_data {
|
||||
struct block_list *bl; ///link to owner object BL_CHAR (BL_PC|BL_HOM|BL_PET|BL_ELE|BL_MER)
|
||||
struct block_list *bl; ///link to owner object BL_PC|BL_MOB|BL_PET|BL_NPC|BL_HOM|BL_MER|BL_ELEM
|
||||
struct walkpath_data walkpath;
|
||||
struct skill_timerskill *skilltimerskill[MAX_SKILLTIMERSKILL];
|
||||
struct skill_unit_group *skillunit[MAX_SKILLUNITGROUP];
|
||||
|
@ -297,6 +297,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
|
||||
* @param data : itemlist data \n
|
||||
* data := {<index>.w <amount>.w <value>.l}[count]
|
||||
* @param count : number of different items
|
||||
* @return 0 If success, 1 - Cannot open (die, not state.prevend, trading), 2 - No cart, 3 - Count issue, 4 - Cart data isn't saved yet, 5 - No valid item found
|
||||
*/
|
||||
char vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
|
||||
int i, j;
|
||||
|
Loading…
x
Reference in New Issue
Block a user