diff options
author | Valaris <Valaris@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-01-29 16:00:45 +0000 |
---|---|---|
committer | Valaris <Valaris@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-01-29 16:00:45 +0000 |
commit | a2675f07d7da22a7c6ae11f545bf8f671e785a82 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/map | |
parent | b8801ae9585201eaaf9fdf80d9c7117ee18f52e2 (diff) | |
download | hercules-a2675f07d7da22a7c6ae11f545bf8f671e785a82.tar.gz hercules-a2675f07d7da22a7c6ae11f545bf8f671e785a82.tar.bz2 hercules-a2675f07d7da22a7c6ae11f545bf8f671e785a82.tar.xz hercules-a2675f07d7da22a7c6ae11f545bf8f671e785a82.zip |
Clearing trunk.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5091 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
51 files changed, 0 insertions, 82229 deletions
diff --git a/src/map/.svnignore b/src/map/.svnignore deleted file mode 100644 index d2a881f54..000000000 --- a/src/map/.svnignore +++ /dev/null @@ -1,3 +0,0 @@ -txtobj -GNUmakefile -sqlobj diff --git a/src/map/Makefile b/src/map/Makefile deleted file mode 100644 index b413c8a62..000000000 --- a/src/map/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -all: txt sql - -txt: txtobj map-server - -sql: sqlobj map-server_sql - -txtobj: - mkdir txtobj - -sqlobj: - mkdir sqlobj - -COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/grfio.o ../common/obj/db.o ../common/obj/lock.o ../common/obj/nullpo.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o ../common/obj/strlib.o - -COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/grfio.h ../common/db.h ../common/lock.h ../common/nullpo.h ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h -LIBS = -lz -lm - -map-server: txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/status.o txtobj/npc.o txtobj/npc_chat.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o txtobj/log.o $(COMMON_OBJ) - $(CC) -o ../../$@ $> $(LIBS) $(LIB_S) - -map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/status.o sqlobj/npc.o sqlobj/npc_chat.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o sqlobj/log.o $(COMMON_OBJ) - $(CC) -o ../../$@ $> $(LIB_S) - -txtobj/%.o: %.c - $(COMPILE.c) -DTXT_ONLY $(OUTPUT_OPTION) $< - -sqlobj/%.o: %.c - $(COMPILE.c) $(OUTPUT_OPTION) $< - -txtobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h $(COMMON_H) -txtobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H) -txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h $(COMMON_H) -txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h $(COMMON_H) -txtobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H) -txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H) -txtobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H) -txtobj/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H) -txtobj/path.o: path.c map.h battle.h $(COMMON_H) -txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H) -txtobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h $(COMMON_H) -txtobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h $(COMMON_H) -txtobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H) -txtobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h $(COMMON_H) -txtobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H) -txtobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H) -txtobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H) -txtobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h $(COMMON_H) -txtobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H) -txtobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h $(COMMON_H) -txtobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h $(COMMON_H) -txtobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H) -txtobj/log.o: log.c log.h map.h $(COMMON_H) -txtobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H) - -sqlobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h $(COMMON_H) -sqlobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H) -sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h $(COMMON_H) -sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h $(COMMON_H) -sqlobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H) -sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H) -sqlobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H) -sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H) -sqlobj/path.o: path.c map.h battle.h $(COMMON_H) -sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H) -sqlobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h $(COMMON_H) -sqlobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h $(COMMON_H) -sqlobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H) -sqlobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h $(COMMON_H) -sqlobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H) -sqlobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H) -sqlobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H) -sqlobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h $(COMMON_H) -sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H) -sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h $(COMMON_H) -sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h $(COMMON_H) -sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H) -sqlobj/mail.o: mail.c mail.h $(COMMON_H) -sqlobj/log.o: log.c log.h map.h $(COMMON_H) -sqlobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H) - -clean: - rm -rf *.o ../../map-server ../../map-server_sql sqlobj txtobj diff --git a/src/map/Makefile.win32 b/src/map/Makefile.win32 deleted file mode 100644 index 2fa1861ac..000000000 --- a/src/map/Makefile.win32 +++ /dev/null @@ -1,96 +0,0 @@ -# grab a copy of http://www.winimage.com/zLibDll/zlib122.zip -# and put safely into a subdirectory someplace -# then point ZLIBDIR at whereever you put it -# - -all: txt sql - -txt: txtobj map-server - -sql: sqlobj map-server_sql - -txtobj: - mkdir txtobj - -sqlobj: - mkdir sqlobj - -ZLIBDIR = ../zlib -PACKETDEF = -DPACKETVER=6 -DNEW_006b -D__WIN32 -DLOCALZLIB -# OPT = /MDd /D_DEBUG -OPT = -LINKOPT = /debug /SUBSYSTEM:CONSOLE -# OPT = /O2 -CFLAGS = $(OPT) /nologo /I../common /I$(ZLIBDIR) $(PACKETDEF) /D_WIN32 - -COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/showmsg.o ../common/strlib.o ../common/utils.o - -LIBS = "WSOCK32.LIB" - -# "WSOCK32.LIB" "USER32.LIB" "ADVAPI32.LIB" "MSVCRT.LIB" "OLDNAMES.LIB" "KERNEL32.LIB" - -TXTOBJS = txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/status.o txtobj/npc.o txtobj/npc_chat.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o txtobj/log.o $(COMMON_OBJ) $(ZLIBDIR)/inflate.o $(ZLIBDIR)/deflate.o $(ZLIBDIR)/trees.o $(ZLIBDIR)/adler32.o $(ZLIBDIR)/compress.o $(ZLIBDIR)/crc32.o $(ZLIBDIR)/inftrees.o $(ZLIBDIR)/zutil.o $(ZLIBDIR)/inffast.o - -SQLOBJS = sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/status.o sqlobj/npc.o sqlobj/npc_chat.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/log.o $(COMMON_OBJ) $(ZLIBDIR)/inflate.o $(ZLIBDIR)/adler32.o $(ZLIBDIR)/crc32.o $(ZLIBDIR)/inftrees.o $(ZLIBDIR)/zutil.o $(ZLIBDIR)/inffast.o - -map-server: $(TXTOBJS) - link $(LINKOPT) /out:../../$@.exe $(TXTOBJS) $(LIBS) - -map-server_sql: $(SQLOBJS) - link $(LINKOPT) /out:../../$@.exe $> $(LIBS) - -txtobj/%.o: %.c - Cl /c $(CFLAGS) -DTXT_ONLY /Fo$@ $< - -sqlobj/%.o: %.c - Cl /c $(CFLAGS) /Fo$@ $< - -%.o: %.c - Cl /c $(CFLAGS) /Fo$@ $< - -txtobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h ../common/core.h ../common/timer.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h -txtobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h atcommand.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/showmsg.h -txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h -txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h -txtobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h -txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h -txtobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h ../common/timer.h ../common/socket.h ../common/mmo.h ../common/showmsg.h -txtobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h ../common/showmsg.h -txtobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h ../common/showmsg.h -txtobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h ../common/socket.h ../common/mmo.h ../common/showmsg.h -txtobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h ../common/mmo.h ../common/showmsg.h -txtobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h ../common/mmo.h ../common/showmsg.h -txtobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -txtobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h - -sqlobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h ../common/core.h ../common/timer.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h -sqlobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h atcommand.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/showmsg.h -sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h -sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h -sqlobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h -sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h -sqlobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h ../common/timer.h ../common/socket.h ../common/mmo.h ../common/showmsg.h -sqlobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h ../common/showmsg.h -sqlobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h ../common/showmsg.h -sqlobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h ../common/socket.h ../common/mmo.h ../common/showmsg.h -sqlobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h ../common/mmo.h ../common/showmsg.h -sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h ../common/mmo.h ../common/showmsg.h -sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h -sqlobj/mail.o: mail.c mail.h ../common/showmsg.h ../common/strlib.h ../common/utils.h -sqlobj/log.o: log.c log.h map.h ../common/nullpo.h - -clean: - rm -rf *.o ../../map-server ../../map-server_sql sqlobj txtobj diff --git a/src/map/atcommand.c b/src/map/atcommand.c deleted file mode 100644 index 79e3ec675..000000000 --- a/src/map/atcommand.c +++ /dev/null @@ -1,9229 +0,0 @@ -// $Id: atcommand.c 148 2004-09-30 14:05:37Z MouseJstr $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <math.h> - -#include "../common/socket.h" -#include "../common/timer.h" -#include "../common/nullpo.h" -#include "../common/mmo.h" -#include "../common/db.h" -#include "../common/core.h" - -#include "log.h" -#include "clif.h" -#include "chrif.h" -#include "intif.h" -#include "itemdb.h" -#include "map.h" -#include "pc.h" -#include "status.h" -#include "skill.h" -#include "mob.h" -#include "pet.h" -#include "battle.h" -#include "party.h" -#include "guild.h" -#include "atcommand.h" -#include "script.h" -#include "npc.h" -#include "trade.h" - -#ifndef TXT_ONLY -#include "mail.h" -#endif - -#define STATE_BLIND 0x10 - -static char command_symbol = '@'; // first char of the commands (by [Yor]) - -#define MAX_MSG 1000 -char *msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) - -#define ACMD_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message) -ACMD_FUNC(broadcast); -ACMD_FUNC(localbroadcast); -ACMD_FUNC(rura); -ACMD_FUNC(where); -ACMD_FUNC(jumpto); -ACMD_FUNC(jump); -ACMD_FUNC(who); -ACMD_FUNC(who2); -ACMD_FUNC(who3); -ACMD_FUNC(whomap); -ACMD_FUNC(whomap2); -ACMD_FUNC(whomap3); -ACMD_FUNC(whogm); // by Yor -ACMD_FUNC(whozeny); // [Valaris] -ACMD_FUNC(happyhappyjoyjoy); // [Valaris] -ACMD_FUNC(save); -ACMD_FUNC(load); -ACMD_FUNC(speed); -ACMD_FUNC(storage); -ACMD_FUNC(guildstorage); -ACMD_FUNC(option); -ACMD_FUNC(hide); -ACMD_FUNC(jobchange); -ACMD_FUNC(die); -ACMD_FUNC(kill); -ACMD_FUNC(alive); -ACMD_FUNC(kami); -ACMD_FUNC(heal); -ACMD_FUNC(item); -ACMD_FUNC(item2); -ACMD_FUNC(itemreset); -ACMD_FUNC(itemcheck); -ACMD_FUNC(baselevelup); -ACMD_FUNC(joblevelup); -ACMD_FUNC(help); -ACMD_FUNC(gm); -ACMD_FUNC(pvpoff); -ACMD_FUNC(pvpon); -ACMD_FUNC(gvgoff); -ACMD_FUNC(gvgon); -ACMD_FUNC(model); -ACMD_FUNC(go); -ACMD_FUNC(monster); -ACMD_FUNC(monstersmall); -ACMD_FUNC(monsterbig); -ACMD_FUNC(spawn); -ACMD_FUNC(killmonster); -ACMD_FUNC(killmonster2); -ACMD_FUNC(refine); -ACMD_FUNC(produce); -ACMD_FUNC(memo); -ACMD_FUNC(gat); -ACMD_FUNC(packet); -ACMD_FUNC(statuspoint); -ACMD_FUNC(skillpoint); -ACMD_FUNC(zeny); -ACMD_FUNC(param); -ACMD_FUNC(guildlevelup); -ACMD_FUNC(makeegg); -ACMD_FUNC(hatch); -ACMD_FUNC(petfriendly); -ACMD_FUNC(pethungry); -ACMD_FUNC(petrename); -ACMD_FUNC(recall); -ACMD_FUNC(recallall); -ACMD_FUNC(revive); -ACMD_FUNC(character_stats_all); -ACMD_FUNC(character_save); -ACMD_FUNC(night); -ACMD_FUNC(day); -ACMD_FUNC(doom); -ACMD_FUNC(doommap); -ACMD_FUNC(raise); -ACMD_FUNC(raisemap); -ACMD_FUNC(character_baselevel); -ACMD_FUNC(character_joblevel); -ACMD_FUNC(kick); -ACMD_FUNC(kickall); -ACMD_FUNC(allskill); -ACMD_FUNC(questskill); -ACMD_FUNC(charquestskill); -ACMD_FUNC(lostskill); -ACMD_FUNC(charlostskill); -ACMD_FUNC(spiritball); -ACMD_FUNC(party); -ACMD_FUNC(guild); -ACMD_FUNC(charskreset); -ACMD_FUNC(charstreset); -ACMD_FUNC(charreset); -ACMD_FUNC(charstpoint); -ACMD_FUNC(charmodel); -ACMD_FUNC(charskpoint); -ACMD_FUNC(agitstart); -ACMD_FUNC(agitend); -ACMD_FUNC(reloaditemdb); -ACMD_FUNC(reloadmobdb); -ACMD_FUNC(reloadskilldb); -ACMD_FUNC(reloadscript); -ACMD_FUNC(reloadgmdb); // by Yor -ACMD_FUNC(reloadatcommand); -ACMD_FUNC(reloadbattleconf); -ACMD_FUNC(reloadstatusdb); -ACMD_FUNC(reloadpcdb); -ACMD_FUNC(mapexit); -ACMD_FUNC(idsearch); -ACMD_FUNC(mapinfo); -ACMD_FUNC(dye); //** by fritz -ACMD_FUNC(hair_style); //** by fritz -ACMD_FUNC(hair_color); //** by fritz -ACMD_FUNC(stat_all); //** by fritz -ACMD_FUNC(char_change_sex); // by Yor -ACMD_FUNC(char_block); // by Yor -ACMD_FUNC(char_ban); // by Yor -ACMD_FUNC(char_unblock); // by Yor -ACMD_FUNC(char_unban); // by Yor -ACMD_FUNC(mount_peco); // by Valaris -ACMD_FUNC(char_mount_peco); // by Yor -ACMD_FUNC(guildspy); // [Syrus22] -ACMD_FUNC(partyspy); // [Syrus22] -ACMD_FUNC(repairall); // [Valaris] -ACMD_FUNC(guildrecall); // by Yor -ACMD_FUNC(partyrecall); // by Yor -ACMD_FUNC(nuke); // [Valaris] -ACMD_FUNC(enablenpc); -ACMD_FUNC(hidenpc); -ACMD_FUNC(disablenpc); -ACMD_FUNC(servertime); // by Yor -ACMD_FUNC(chardelitem); // by Yor -ACMD_FUNC(jail); // by Yor -ACMD_FUNC(unjail); // by Yor -ACMD_FUNC(disguise); // [Valaris] -ACMD_FUNC(undisguise); // by Yor -ACMD_FUNC(chardisguise); // Kalaspuff -ACMD_FUNC(charundisguise); // Kalaspuff -ACMD_FUNC(email); // by Yor -ACMD_FUNC(effect);//by Apple -ACMD_FUNC(character_cart_list); // by Yor -ACMD_FUNC(addwarp); // by MouseJstr -ACMD_FUNC(follow); // by MouseJstr -ACMD_FUNC(skillon); // by MouseJstr -ACMD_FUNC(skilloff); // by MouseJstr -ACMD_FUNC(killer); // by MouseJstr -ACMD_FUNC(npcmove); // by MouseJstr -ACMD_FUNC(killable); // by MouseJstr -ACMD_FUNC(charkillable); // by MouseJstr -ACMD_FUNC(dropall); // by MouseJstr -ACMD_FUNC(chardropall); // by MouseJstr -ACMD_FUNC(storeall); // by MouseJstr -ACMD_FUNC(charstoreall); // by MouseJstr -ACMD_FUNC(skillid); // by MouseJstr -ACMD_FUNC(useskill); // by MouseJstr -ACMD_FUNC(summon); -ACMD_FUNC(rain); -ACMD_FUNC(snow); -ACMD_FUNC(sakura); -ACMD_FUNC(fog); -ACMD_FUNC(leaves); -ACMD_FUNC(adjgmlvl); // by MouseJstr -ACMD_FUNC(adjcmdlvl); // by MouseJstr -ACMD_FUNC(trade); // by MouseJstr -ACMD_FUNC(send); // by davidsiaw -ACMD_FUNC(setbattleflag); // by MouseJstr -ACMD_FUNC(unmute); // [Valaris] -ACMD_FUNC(clearweather); // Dexity -ACMD_FUNC(uptime); // by MC Cameri -ACMD_FUNC(changesex); // by MC Cameri -ACMD_FUNC(mute); // celest -ACMD_FUNC(refresh); // by MC Cameri -ACMD_FUNC(petid); // by MC Cameri -ACMD_FUNC(identify); // by MC Cameri -ACMD_FUNC(gmotd); // Added by MC Cameri, created by davidsiaw -ACMD_FUNC(misceffect); // by MC Cameri -ACMD_FUNC(mobsearch); -ACMD_FUNC(cleanmap); -ACMD_FUNC(npctalk); -ACMD_FUNC(pettalk); -ACMD_FUNC(users); -ACMD_FUNC(autoloot); // by Upa-Kun - -#ifndef TXT_ONLY -ACMD_FUNC(checkmail); // [Valaris] -ACMD_FUNC(listmail); // [Valaris] -ACMD_FUNC(listnewmail); // [Valaris] -ACMD_FUNC(readmail); // [Valaris] -ACMD_FUNC(sendmail); // [Valaris] -ACMD_FUNC(sendprioritymail); // [Valaris] -ACMD_FUNC(deletemail); // [Valaris] -//ACMD_FUNC(sound); // [Valaris] -ACMD_FUNC(refreshonline); // [Valaris] -#endif /* TXT_ONLY */ - -ACMD_FUNC(skilltree); // by MouseJstr - -ACMD_FUNC(marry); // by MouseJstr -ACMD_FUNC(divorce); // by MouseJstr -ACMD_FUNC(rings); // by MouseJstr - -ACMD_FUNC(grind); // by MouseJstr -ACMD_FUNC(grind2); // by MouseJstr - -#ifdef DMALLOC -ACMD_FUNC(dmstart); // by MouseJstr -ACMD_FUNC(dmtick); // by MouseJstr -#endif - -ACMD_FUNC(jumptoid); // by Dino9021 -ACMD_FUNC(jumptoid2); // by Dino9021 -ACMD_FUNC(recallid); // by Dino9021 -ACMD_FUNC(recallid2); // by Dino9021 -ACMD_FUNC(kickid); // by Dino9021 -ACMD_FUNC(kickid2); // by Dino9021 -ACMD_FUNC(reviveid); // by Dino9021 -ACMD_FUNC(reviveid2); // by Dino9021 -ACMD_FUNC(killid); // by Dino9021 -ACMD_FUNC(killid2); // by Dino9021 -ACMD_FUNC(charkillableid); // by Dino9021 -ACMD_FUNC(charkillableid2); // by Dino9021 -ACMD_FUNC(sound); -ACMD_FUNC(undisguiseall); -ACMD_FUNC(disguiseall); -ACMD_FUNC(changelook); -ACMD_FUNC(mobinfo); //by Lupus -ACMD_FUNC(adopt); // by Veider - -/*========================================== - *AtCommandInfo atcommand_info[]構造体の定義 - *------------------------------------------ - */ - -// First char of commands is configured in atcommand_athena.conf. Leave @ in this list for default value. -// to set default level, read atcommand_athena.conf first please. -static AtCommandInfo atcommand_info[] = { - { AtCommand_Rura, "@rura", 40, atcommand_rura }, - { AtCommand_Warp, "@warp", 40, atcommand_rura }, - { AtCommand_Where, "@where", 1, atcommand_where }, - { AtCommand_JumpTo, "@jumpto", 20, atcommand_jumpto }, // + /shift - { AtCommand_JumpTo, "@warpto", 20, atcommand_jumpto }, - { AtCommand_JumpTo, "@goto", 20, atcommand_jumpto }, - { AtCommand_Jump, "@jump", 40, atcommand_jump }, - { AtCommand_Who, "@who", 20, atcommand_who }, - { AtCommand_Who, "@whois", 20, atcommand_who }, - { AtCommand_Who2, "@who2", 20, atcommand_who2 }, - { AtCommand_Who3, "@who3", 20, atcommand_who3 }, - { AtCommand_WhoMap, "@whomap", 20, atcommand_whomap }, - { AtCommand_WhoMap2, "@whomap2", 20, atcommand_whomap2 }, - { AtCommand_WhoMap3, "@whomap3", 20, atcommand_whomap3 }, - { AtCommand_WhoGM, "@whogm", 20, atcommand_whogm }, // by Yor - { AtCommand_Save, "@save", 40, atcommand_save }, - { AtCommand_Load, "@return", 40, atcommand_load }, - { AtCommand_Load, "@load", 40, atcommand_load }, - { AtCommand_Speed, "@speed", 40, atcommand_speed }, - { AtCommand_Storage, "@storage", 1, atcommand_storage }, - { AtCommand_GuildStorage, "@gstorage", 50, atcommand_guildstorage }, - { AtCommand_Option, "@option", 40, atcommand_option }, - { AtCommand_Hide, "@hide", 40, atcommand_hide }, // + /hide - { AtCommand_JobChange, "@jobchange", 40, atcommand_jobchange }, - { AtCommand_JobChange, "@job", 40, atcommand_jobchange }, - { AtCommand_Die, "@die", 1, atcommand_die }, - { AtCommand_Kill, "@kill", 60, atcommand_kill }, - { AtCommand_Alive, "@alive", 60, atcommand_alive }, - { AtCommand_Kami, "@kami", 40, atcommand_kami }, - { AtCommand_KamiB, "@kamib", 40, atcommand_kami }, - { AtCommand_Heal, "@heal", 40, atcommand_heal }, - { AtCommand_Item, "@item", 60, atcommand_item }, - { AtCommand_Item2, "@item2", 60, atcommand_item2 }, - { AtCommand_ItemReset, "@itemreset", 40, atcommand_itemreset }, - { AtCommand_ItemCheck, "@itemcheck", 60, atcommand_itemcheck }, - { AtCommand_BaseLevelUp, "@lvup", 60, atcommand_baselevelup }, - { AtCommand_BaseLevelUp, "@blevel", 60, atcommand_baselevelup }, - { AtCommand_BaseLevelUp, "@baselvlup", 60, atcommand_baselevelup }, - { AtCommand_JobLevelUp, "@jlevel", 60, atcommand_joblevelup }, - { AtCommand_JobLevelUp, "@joblvup", 60, atcommand_joblevelup }, - { AtCommand_JobLevelUp, "@joblvlup", 60, atcommand_joblevelup }, - { AtCommand_H, "@h", 20, atcommand_help }, - { AtCommand_Help, "@help", 20, atcommand_help }, - { AtCommand_GM, "@gm", 100, atcommand_gm }, - { AtCommand_PvPOff, "@pvpoff", 40, atcommand_pvpoff }, - { AtCommand_PvPOn, "@pvpon", 40, atcommand_pvpon }, - { AtCommand_GvGOff, "@gvgoff", 40, atcommand_gvgoff }, - { AtCommand_GvGOff, "@gpvpoff", 40, atcommand_gvgoff }, - { AtCommand_GvGOn, "@gvgon", 40, atcommand_gvgon }, - { AtCommand_GvGOn, "@gpvpon", 40, atcommand_gvgon }, - { AtCommand_Model, "@model", 20, atcommand_model }, - { AtCommand_Go, "@go", 10, atcommand_go }, - { AtCommand_Spawn, "@monster", 50, atcommand_spawn }, - { AtCommand_Spawn, "@spawn", 50, atcommand_spawn }, -// { AtCommand_Spawn, "@summon", 50, atcommand_spawn }, - { AtCommand_Monster, "@monster2", 50, atcommand_monster }, - { AtCommand_MonsterSmall, "@monstersmall", 50, atcommand_monstersmall }, - { AtCommand_MonsterBig, "@monsterbig", 50, atcommand_monsterbig }, - { AtCommand_KillMonster, "@killmonster", 60, atcommand_killmonster }, - { AtCommand_KillMonster2, "@killmonster2", 40, atcommand_killmonster2 }, - { AtCommand_Refine, "@refine", 60, atcommand_refine }, - { AtCommand_Produce, "@produce", 60, atcommand_produce }, - { AtCommand_Memo, "@memo", 40, atcommand_memo }, - { AtCommand_GAT, "@gat", 99, atcommand_gat }, // debug function - { AtCommand_Packet, "@packet", 99, atcommand_packet }, // debug function - { AtCommand_StatusPoint, "@stpoint", 60, atcommand_statuspoint }, - { AtCommand_SkillPoint, "@skpoint", 60, atcommand_skillpoint }, - { AtCommand_Zeny, "@zeny", 60, atcommand_zeny }, - { AtCommand_Strength, "@str", 60, atcommand_param }, - { AtCommand_Agility, "@agi", 60, atcommand_param }, - { AtCommand_Vitality, "@vit", 60, atcommand_param }, - { AtCommand_Intelligence, "@int", 60, atcommand_param }, - { AtCommand_Dexterity, "@dex", 60, atcommand_param }, - { AtCommand_Luck, "@luk", 60, atcommand_param }, - { AtCommand_GuildLevelUp, "@guildlvup", 60, atcommand_guildlevelup }, - { AtCommand_GuildLevelUp, "@guildlvlup", 60, atcommand_guildlevelup }, - { AtCommand_MakeEgg, "@makeegg", 60, atcommand_makeegg }, - { AtCommand_Hatch, "@hatch", 60, atcommand_hatch }, - { AtCommand_PetFriendly, "@petfriendly", 40, atcommand_petfriendly }, - { AtCommand_PetHungry, "@pethungry", 40, atcommand_pethungry }, - { AtCommand_PetRename, "@petrename", 1, atcommand_petrename }, - { AtCommand_Recall, "@recall", 60, atcommand_recall }, // + /recall - { AtCommand_Revive, "@revive", 60, atcommand_revive }, - { AtCommand_Night, "@night", 80, atcommand_night }, - { AtCommand_Day, "@day", 80, atcommand_day }, - { AtCommand_Doom, "@doom", 80, atcommand_doom }, - { AtCommand_DoomMap, "@doommap", 80, atcommand_doommap }, - { AtCommand_Raise, "@raise", 80, atcommand_raise }, - { AtCommand_RaiseMap, "@raisemap", 80, atcommand_raisemap }, - { AtCommand_CharacterBaseLevel, "@charbaselvl", 60, atcommand_character_baselevel }, - { AtCommand_CharacterJobLevel, "@charjlvl", 60, atcommand_character_joblevel }, - { AtCommand_Kick, "@kick", 20, atcommand_kick }, // + right click menu for GM "(name) force to quit" - { AtCommand_KickAll, "@kickall", 99, atcommand_kickall }, - { AtCommand_AllSkill, "@allskill", 60, atcommand_allskill }, - { AtCommand_AllSkill, "@allskills", 60, atcommand_allskill }, - { AtCommand_AllSkill, "@skillall", 60, atcommand_allskill }, - { AtCommand_AllSkill, "@skillsall", 60, atcommand_allskill }, - { AtCommand_QuestSkill, "@questskill", 40, atcommand_questskill }, - { AtCommand_CharQuestSkill, "@charquestskill", 60, atcommand_charquestskill }, - { AtCommand_LostSkill, "@lostskill", 40, atcommand_lostskill }, - { AtCommand_CharLostSkill, "@charlostskill", 60, atcommand_charlostskill }, - { AtCommand_SpiritBall, "@spiritball", 40, atcommand_spiritball }, - { AtCommand_Party, "@party", 1, atcommand_party }, - { AtCommand_Guild, "@guild", 50, atcommand_guild }, - { AtCommand_AgitStart, "@agitstart", 60, atcommand_agitstart }, - { AtCommand_AgitEnd, "@agitend", 60, atcommand_agitend }, - { AtCommand_MapExit, "@mapexit", 99, atcommand_mapexit }, - { AtCommand_IDSearch, "@idsearch", 60, atcommand_idsearch }, - { AtCommand_MapMove, "@mapmove", 40, atcommand_rura }, // /mm command - { AtCommand_Broadcast, "@broadcast", 40, atcommand_broadcast }, // /b and /nb command - { AtCommand_LocalBroadcast, "@localbroadcast", 40, atcommand_localbroadcast }, // /lb and /nlb command - { AtCommand_RecallAll, "@recallall", 80, atcommand_recallall }, - { AtCommand_CharSkReset, "@charskreset", 60, atcommand_charskreset }, - { AtCommand_CharStReset, "@charstreset", 60, atcommand_charstreset }, - { AtCommand_ReloadItemDB, "@reloaditemdb", 99, atcommand_reloaditemdb }, // admin command - { AtCommand_ReloadMobDB, "@reloadmobdb", 99, atcommand_reloadmobdb }, // admin command - { AtCommand_ReloadSkillDB, "@reloadskilldb", 99, atcommand_reloadskilldb }, // admin command - { AtCommand_ReloadScript, "@reloadscript", 99, atcommand_reloadscript }, // admin command - { AtCommand_ReloadGMDB, "@reloadgmdb", 99, atcommand_reloadgmdb }, // admin command - { AtCommand_ReloadAtcommand, "@reloadatcommand", 99, atcommand_reloadatcommand }, - { AtCommand_ReloadBattleConf, "@reloadbattleconf",99, atcommand_reloadbattleconf }, - { AtCommand_ReloadStatusDB, "@reloadstatusdb", 99, atcommand_reloadstatusdb }, - { AtCommand_ReloadPcDB, "@reloadpcdb", 99, atcommand_reloadpcdb }, - { AtCommand_CharModel, "@charmodel", 50, atcommand_charmodel }, - { AtCommand_CharSKPoint, "@charskpoint", 60, atcommand_charskpoint }, - { AtCommand_CharSTPoint, "@charstpoint", 60, atcommand_charstpoint }, - { AtCommand_MapInfo, "@mapinfo", 99, atcommand_mapinfo }, - { AtCommand_Dye, "@dye", 40, atcommand_dye }, // by fritz - { AtCommand_Dye, "@ccolor", 40, atcommand_dye }, // by fritz - { AtCommand_Hstyle, "@hairstyle", 40, atcommand_hair_style }, // by fritz - { AtCommand_Hstyle, "@hstyle", 40, atcommand_hair_style }, // by fritz - { AtCommand_Hcolor, "@haircolor", 40, atcommand_hair_color }, // by fritz - { AtCommand_Hcolor, "@hcolor", 40, atcommand_hair_color }, // by fritz - { AtCommand_StatAll, "@statall", 60, atcommand_stat_all }, // by fritz - { AtCommand_StatAll, "@statsall", 60, atcommand_stat_all }, - { AtCommand_StatAll, "@allstats", 60, atcommand_stat_all }, // by fritz - { AtCommand_StatAll, "@allstat", 60, atcommand_stat_all }, // by fritz -// { AtCommand_CharChangeSex, "@charchangesex", 60, atcommand_char_change_sex }, // by Yor - { AtCommand_CharBlock, "@block", 60, atcommand_char_block }, // by Yor - { AtCommand_CharBlock, "@charblock", 60, atcommand_char_block }, // by Yor - { AtCommand_CharBan, "@ban", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharBan, "@banish", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharBan, "@charban", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharBan, "@charbanish", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharUnBlock, "@unblock", 60, atcommand_char_unblock }, // by Yor - { AtCommand_CharUnBlock, "@charunblock", 60, atcommand_char_unblock }, // by Yor - { AtCommand_CharUnBan, "@unban", 60, atcommand_char_unban }, // by Yor - { AtCommand_CharUnBan, "@unbanish", 60, atcommand_char_unban }, // by Yor - { AtCommand_CharUnBan, "@charunban", 60, atcommand_char_unban }, // by Yor - { AtCommand_CharUnBan, "@charunbanish", 60, atcommand_char_unban }, // by Yor - { AtCommand_MountPeco, "@mountpeco", 20, atcommand_mount_peco }, // by Valaris - { AtCommand_CharMountPeco, "@charmountpeco", 50, atcommand_char_mount_peco }, // by Yor - { AtCommand_GuildSpy, "@guildspy", 60, atcommand_guildspy }, // [Syrus22] - { AtCommand_PartySpy, "@partyspy", 60, atcommand_partyspy }, // [Syrus22] - { AtCommand_RepairAll, "@repairall", 60, atcommand_repairall }, // [Valaris] - { AtCommand_GuildRecall, "@guildrecall", 60, atcommand_guildrecall }, // by Yor - { AtCommand_PartyRecall, "@partyrecall", 60, atcommand_partyrecall }, // by Yor - { AtCommand_Nuke, "@nuke", 60, atcommand_nuke }, // [Valaris] - { AtCommand_Enablenpc, "@enablenpc", 80, atcommand_enablenpc }, // [] - { AtCommand_Hidenpc, "@hidenpc", 80, atcommand_hidenpc }, // [] - { AtCommand_Disablenpc, "@disablenpc", 80, atcommand_disablenpc }, // [] - { AtCommand_ServerTime, "@time", 0, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@date", 0, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@server_date", 0, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@serverdate", 0, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@server_time", 0, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@servertime", 0, atcommand_servertime }, // by Yor - { AtCommand_CharDelItem, "@chardelitem", 60, atcommand_chardelitem }, // by Yor - { AtCommand_Jail, "@jail", 60, atcommand_jail }, // by Yor - { AtCommand_UnJail, "@unjail", 60, atcommand_unjail }, // by Yor - { AtCommand_UnJail, "@discharge", 60, atcommand_unjail }, // by Yor - { AtCommand_Disguise, "@disguise", 20, atcommand_disguise }, // [Valaris] - { AtCommand_UnDisguise, "@undisguise", 20, atcommand_undisguise }, // by Yor - { AtCommand_CharDisguise, "@chardisguise", 60, atcommand_chardisguise }, // Kalaspuff - { AtCommand_CharUnDisguise, "@charundisguise", 60, atcommand_charundisguise }, // Kalaspuff - { AtCommand_EMail, "@email", 0, atcommand_email }, // by Yor - { AtCommand_Effect, "@effect", 40, atcommand_effect }, // by Apple -// { AtCommand_Char_Item_List, "@charitemlist", 40, atcommand_character_item_list }, // by Yor, now #itemlist -// { AtCommand_Char_Storage_List, "@charstoragelist", 40, atcommand_character_storage_list }, // by Yor, now #storagelist - { AtCommand_Char_Cart_List, "@charcartlist", 40, atcommand_character_cart_list }, // by Yor - { AtCommand_Follow, "@follow", 10, atcommand_follow }, // by MouseJstr - { AtCommand_AddWarp, "@addwarp", 20, atcommand_addwarp }, // by MouseJstr - { AtCommand_SkillOn, "@skillon", 20, atcommand_skillon }, // by MouseJstr - { AtCommand_SkillOff, "@skilloff", 20, atcommand_skilloff }, // by MouseJstr - { AtCommand_Killer, "@killer", 60, atcommand_killer }, // by MouseJstr - { AtCommand_NpcMove, "@npcmove", 20, atcommand_npcmove }, // by MouseJstr - { AtCommand_Killable, "@killable", 40, atcommand_killable }, // by MouseJstr - { AtCommand_CharKillable, "@charkillable", 40, atcommand_charkillable }, // by MouseJstr - { AtCommand_Dropall, "@dropall", 40, atcommand_dropall }, // MouseJstr - { AtCommand_Chardropall, "@chardropall", 40, atcommand_chardropall }, // MouseJstr - { AtCommand_Storeall, "@storeall", 40, atcommand_storeall }, // MouseJstr - { AtCommand_Charstoreall, "@charstoreall", 40, atcommand_charstoreall }, // MouseJstr - { AtCommand_Skillid, "@skillid", 40, atcommand_skillid }, // MouseJstr - { AtCommand_Useskill, "@useskill", 40, atcommand_useskill }, // MouseJstr - { AtCommand_Rain, "@rain", 99, atcommand_rain }, - { AtCommand_Snow, "@snow", 99, atcommand_snow }, - { AtCommand_Sakura, "@sakura", 99, atcommand_sakura }, - { AtCommand_Fog, "@fog", 99, atcommand_fog }, - { AtCommand_Leaves, "@leaves", 99, atcommand_leaves }, -/* - { AtCommand_Shuffle, "@shuffle", 99, atcommand_shuffle }, - { AtCommand_Maintenance, "@maintenance", 99, atcommand_maintenance }, - { AtCommand_Misceffect, "@misceffect", 60, atcommand_misceffect }, -*/ - { AtCommand_Summon, "@summon", 60, atcommand_summon }, - { AtCommand_AdjGmLvl, "@adjgmlvl", 99, atcommand_adjgmlvl }, - { AtCommand_AdjCmdLvl, "@adjcmdlvl", 99, atcommand_adjcmdlvl }, - { AtCommand_Trade, "@trade", 60, atcommand_trade }, - { AtCommand_Send, "@send", 60, atcommand_send }, - { AtCommand_SetBattleFlag, "@setbattleflag", 60, atcommand_setbattleflag }, - { AtCommand_UnMute, "@unmute", 60, atcommand_unmute }, // [Valaris] - { AtCommand_Clearweather, "@clearweather", 99, atcommand_clearweather }, // Dexity - { AtCommand_UpTime, "@uptime", 0, atcommand_uptime }, // by MC Cameri -// { AtCommand_ChangeSex, "@changesex", 1, atcommand_changesex }, // by MC Cameri - { AtCommand_Mute, "@mute", 99, atcommand_mute }, // [celest] - { AtCommand_Mute, "@red", 99, atcommand_mute }, // [celest] - { AtCommand_WhoZeny, "@whozeny", 20, atcommand_whozeny }, // [Valaris] - { AtCommand_HappyHappyJoyJoy, "@happyhappyjoyjoy",40, atcommand_happyhappyjoyjoy }, // [Valaris] - { AtCommand_Refresh, "@refresh", 0, atcommand_refresh }, // by MC Cameri - { AtCommand_PetId, "@petid", 40, atcommand_petid }, // by MC Cameri - { AtCommand_Identify, "@identify", 40, atcommand_identify }, // by MC Cameri - { AtCommand_Gmotd, "@gmotd", 0, atcommand_gmotd }, // Added by MC Cameri, created by davidsiaw - { AtCommand_MiscEffect, "@misceffect", 50, atcommand_misceffect }, // by MC Cameri - { AtCommand_MobSearch, "@mobsearch", 0, atcommand_mobsearch }, - { AtCommand_CleanMap, "@cleanmap", 0, atcommand_cleanmap }, - { AtCommand_NpcTalk, "@npctalk", 0, atcommand_npctalk }, - { AtCommand_PetTalk, "@pettalk", 0, atcommand_pettalk }, - { AtCommand_Users, "@users", 0, atcommand_users }, - { AtCommand_ResetState, "/reset", 40, NULL }, - -#ifndef TXT_ONLY // sql-only commands - { AtCommand_CheckMail, "@checkmail", 1, atcommand_listmail }, // [Valaris] - { AtCommand_ListMail, "@listmail", 1, atcommand_listmail }, // [Valaris] - { AtCommand_ListNewMail, "@listnewmail", 1, atcommand_listmail }, // [Valaris] - { AtCommand_ReadMail, "@readmail", 1, atcommand_readmail }, // [Valaris] - { AtCommand_DeleteMail, "@deletemail", 1, atcommand_readmail }, // [Valaris] - { AtCommand_SendMail, "@sendmail", 1, atcommand_sendmail }, // [Valaris] - { AtCommand_SendPriorityMail, "@sendprioritymail",80, atcommand_sendmail }, // [Valaris] - { AtCommand_RefreshOnline, "@refreshonline", 99, atcommand_refreshonline }, // [Valaris] - -#endif /* TXT_ONLY */ - { AtCommand_SkillTree, "@skilltree", 40, atcommand_skilltree }, // [MouseJstr] - { AtCommand_Marry, "@marry", 40, atcommand_marry }, // [MouseJstr] - { AtCommand_Divorce, "@divorce", 40, atcommand_divorce }, // [MouseJstr] - { AtCommand_Rings, "@rings", 40, atcommand_rings }, // [MouseJstr] - { AtCommand_Grind, "@grind", 99, atcommand_grind }, // [MouseJstr] - { AtCommand_Grind2, "@grind2", 99, atcommand_grind2 }, // [MouseJstr] - -#ifdef DMALLOC - { AtCommand_DMStart, "@dmstart", 99, atcommand_dmstart }, // [MouseJstr] - { AtCommand_DMTick, "@dmtick", 99, atcommand_dmtick }, // [MouseJstr] -#endif - - { AtCommand_JumpToId, "@jumptoid", 20, atcommand_jumptoid }, // [Dino9021] - { AtCommand_JumpToId, "@warptoid", 20, atcommand_jumptoid }, // [Dino9021] - { AtCommand_JumpToId, "@gotoid", 20, atcommand_jumptoid }, // [Dino9021] - { AtCommand_JumpToId2, "@jumptoid2", 20, atcommand_jumptoid2 }, // [Dino9021] - { AtCommand_JumpToId2, "@warptoid2", 20, atcommand_jumptoid2 }, // [Dino9021] - { AtCommand_JumpToId2, "@gotoid2", 20, atcommand_jumptoid2 }, // [Dino9021] - { AtCommand_RecallId, "@recallid", 60, atcommand_recallid }, // [Dino9021] - { AtCommand_RecallId2, "@recallid2", 60, atcommand_recallid2 }, // [Dino9021] - { AtCommand_KickId, "@kickid", 99, atcommand_kickid }, // [Dino9021] - { AtCommand_KickId2, "@kickid2", 99, atcommand_kickid2 }, // [Dino9021] - { AtCommand_ReviveId, "@reviveid", 60, atcommand_reviveid }, // [Dino9021] - { AtCommand_ReviveId2, "@reviveid2", 60, atcommand_reviveid2 }, // [Dino9021] - { AtCommand_KillId, "@killid", 60, atcommand_killid }, // [Dino9021] - { AtCommand_KillId2, "@killid2", 60, atcommand_killid2 }, // [Dino9021] - { AtCommand_CharKillableId, "@charkillableid", 40, atcommand_charkillableid }, // [Dino9021] - { AtCommand_CharKillableId2, "@charkillableid2", 40, atcommand_charkillableid2 }, // [Dino9021] - { AtCommand_Sound, "@sound", 40, atcommand_sound }, - { AtCommand_UndisguiseAll, "@undisguiseall", 99, atcommand_undisguiseall }, - { AtCommand_DisguiseAll, "@disguiseall", 99, atcommand_disguiseall }, - { AtCommand_ChangeLook, "@changelook", 99, atcommand_changelook }, - { AtCommand_AutoLoot, "@autoloot", 10, atcommand_autoloot }, // Upa-Kun - { AtCommand_MobInfo, "@mobinfo", 1, atcommand_mobinfo }, // [Lupus] - { AtCommand_MobInfo, "@monsterinfo", 1, atcommand_mobinfo }, // [Lupus] - { AtCommand_MobInfo, "@mi", 1, atcommand_mobinfo }, // [Lupus] - { AtCommand_Adopt, "@adopt", 40, atcommand_adopt }, // [Veider] - -// add new commands before this line - { AtCommand_Unknown, NULL, 1, NULL } -}; - -/*========================================= - * Generic variables - *----------------------------------------- - */ -char atcmd_output[200]; -char atcmd_player_name[100]; - -/*==================================================== - * This function return the name of the job (by [Yor]) - *---------------------------------------------------- - */ -char * job_name(int class_) { - switch (class_) { - case 0: return "Novice"; - case 1: return "Swordsman"; - case 2: return "Mage"; - case 3: return "Archer"; - case 4: return "Acolyte"; - case 5: return "Merchant"; - case 6: return "Thief"; - case 7: return "Knight"; - case 8: return "Priest"; - case 9: return "Wizard"; - case 10: return "Blacksmith"; - case 11: return "Hunter"; - case 12: return "Assassin"; - case 13: return "Knight 2"; - case 14: return "Crusader"; - case 15: return "Monk"; - case 16: return "Sage"; - case 17: return "Rogue"; - case 18: return "Alchemist"; - case 19: return "Bard"; - case 20: return "Dancer"; - case 21: return "Crusader 2"; - case 22: return "Wedding"; - case 23: return "Super Novice"; - case 4001: return "Novice High"; - case 4002: return "Swordsman High"; - case 4003: return "Mage High"; - case 4004: return "Archer High"; - case 4005: return "Acolyte High"; - case 4006: return "Merchant High"; - case 4007: return "Thief High"; - case 4008: return "Lord Knight"; - case 4009: return "High Priest"; - case 4010: return "High Wizard"; - case 4011: return "Whitesmith"; - case 4012: return "Sniper"; - case 4013: return "Assassin Cross"; - case 4014: return "Peko Knight"; - case 4015: return "Paladin"; - case 4016: return "Champion"; - case 4017: return "Professor"; - case 4018: return "Stalker"; - case 4019: return "Creator"; - case 4020: return "Clown"; - case 4021: return "Gypsy"; - case 4022: return "Peko Paladin"; - case 4023: return "Baby Novice"; - case 4024: return "Baby Swordsman"; - case 4025: return "Baby Mage"; - case 4026: return "Baby Archer"; - case 4027: return "Baby Acolyte"; - case 4028: return "Baby Merchant"; - case 4029: return "Baby Thief"; - case 4030: return "Baby Knight"; - case 4031: return "Baby Priest"; - case 4032: return "Baby Wizard"; - case 4033: return "Baby Blacksmith"; - case 4034: return "Baby Hunter"; - case 4035: return "Baby Assassin"; - case 4036: return "Baby Peco Knight"; - case 4037: return "Baby Crusader"; - case 4038: return "Baby Monk"; - case 4039: return "Baby Sage"; - case 4040: return "Baby Rogue"; - case 4041: return "Baby Alchemist"; - case 4042: return "Baby Bard"; - case 4043: return "Baby Dancer"; - case 4044: return "Baby Peco Crusader"; - case 4045: return "Super Baby"; - } - return "Unknown Job"; -} - -/*========================================== - * estr_lower (replace strlwr, non ANSI function that doesn't exist in all C compilator) - *------------------------------------------ - */ -char *estr_lower(char *str) -{ - int i; - - for (i=0; str[i]; i++) - if ((str[i] >= 65) && (str[i] <= 90)) - str[i] += 32; - return str; -} - -// compare function for sorting high to lowest -int hightolow_compare (const void * a, const void * b) -{ - return ( *(int*)b - *(int*)a ); -} - -// compare function for sorting lowest to highest -int lowtohigh_compare (const void * a, const void * b) -{ - return ( *(int*)a - *(int*)b ); -} - -//----------------------------------------------------------- -// Return the message string of the specified number by [Yor] -//----------------------------------------------------------- -char * msg_txt(int msg_number) { - if (msg_number >= 0 && msg_number < MAX_MSG && - msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0') - return msg_table[msg_number]; - - return "??"; -} - -//------------------------------------------------------------ -// E-mail check: return 0 (not correct) or 1 (valid). by [Yor] -//------------------------------------------------------------ -int e_mail_check(char *email) { - char ch; - char* last_arobas; - - // athena limits - if (strlen(email) < 3 || strlen(email) > 39) - return 0; - - // part of RFC limits (official reference of e-mail description) - if (strchr(email, '@') == NULL || email[strlen(email)-1] == '@') - return 0; - - if (email[strlen(email)-1] == '.') - return 0; - - last_arobas = strrchr(email, '@'); - - if (strstr(last_arobas, "@.") != NULL || - strstr(last_arobas, "..") != NULL) - return 0; - - for(ch = 1; ch < 32; ch++) { - if (strchr(last_arobas, ch) != NULL) { - return 0; - break; - } - } - - if (strchr(last_arobas, ' ') != NULL || - strchr(last_arobas, ';') != NULL) - return 0; - - // all correct - return 1; -} - -/*========================================== - * get_atcommand_level @コマンドの必要レベルを取得 - *------------------------------------------ - */ -int get_atcommand_level(const AtCommandType type) { - int i; - - for (i = 0; atcommand_info[i].type != AtCommand_None; i++) - if (atcommand_info[i].type == type) - return atcommand_info[i].level; - - return 100; // 100: command can not be used -} - -/*========================================== - *is_atcommand @コマンドに存在するかどうか確認する - *------------------------------------------ - */ -AtCommandType -is_atcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl) { - const char* str = message; - int s_flag = 0; - AtCommandInfo info; - AtCommandType type; - - nullpo_retr(AtCommand_None, sd); - - if (!battle_config.allow_atcommand_when_mute && - sd->sc_count && sd->sc_data[SC_NOCHAT].timer != -1) { - return AtCommand_Unknown; - } - - if (!message || !*message) - return AtCommand_None; - - memset(&info, 0, sizeof(info)); - str += strlen(sd->status.name); - while (*str && (isspace(*str) || (s_flag == 0 && *str == ':'))) { - if (*str == ':') - s_flag = 1; - str++; - } - if (!*str) - return AtCommand_None; - - type = atcommand(sd, gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info); - if (type != AtCommand_None) { - char command[100]; - const char* p = str; - memset(command, '\0', sizeof(command)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - while (*p && !isspace(*p)) - p++; - if (p - str >= sizeof(command)) // too long - return AtCommand_Unknown; - strncpy(command, str, p - str); - while (isspace(*p)) - p++; - - if (type == AtCommand_Unknown || info.proc == NULL) { - sprintf(atcmd_output, msg_table[153], command); // %s is Unknown Command. - clif_displaymessage(fd, atcmd_output); - } else { - if (info.proc(fd, sd, command, p) != 0) { - // Command can not be executed - sprintf(atcmd_output, msg_table[154], command); // %s failed. - clif_displaymessage(fd, atcmd_output); - } - } - - return info.type; - } - - return AtCommand_None; -} - -/*========================================== - * - *------------------------------------------ - */ -AtCommandType atcommand(struct map_session_data* sd, const int level, const char* message, struct AtCommandInfo* info) { - char* p = (char *)message; // it's 'char' and not 'const char' to have possibility to modify the first character if necessary - - if (!info) - return AtCommand_None; - if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd) - return AtCommand_None; - if (!p || !*p) { - fprintf(stderr, "at command message is empty\n"); - return AtCommand_None; - } - - if (*p == command_symbol) { // check first char. - char command[101]; - int i = 0; - memset(info, 0, sizeof(AtCommandInfo)); - sscanf(p, "%100s", command); - command[sizeof(command)-1] = '\0'; - - while (atcommand_info[i].type != AtCommand_Unknown) { - if (strcmpi(command+1, atcommand_info[i].command+1) == 0 && level >= atcommand_info[i].level) { - p[0] = atcommand_info[i].command[0]; // set correct first symbol for after. - break; - } - i++; - } - - if (atcommand_info[i].type == AtCommand_Unknown) { - // doesn't return Unknown if player is normal player (display the text, not display: unknown command) - if (level == 0) - return AtCommand_None; - else - return AtCommand_Unknown; - } else if((log_config.gm) && (atcommand_info[i].level >= log_config.gm)) { - log_atcommand(sd, message); - } - memcpy(info, &atcommand_info[i], sizeof atcommand_info[i]); - } else { - return AtCommand_None; - } - - return info->type; -} - -/*========================================== - * - *------------------------------------------ - */ -static int atkillmonster_sub(struct block_list *bl, va_list ap) { - struct mob_data *md; - int flag; - - nullpo_retr(0, ap); - nullpo_retr(0, md=(struct mob_data *)bl); - flag = va_arg(ap, int); - - if (flag) - mob_damage(NULL, md, md->hp, 2); - else - mob_delete(md); - - return 0; -} -/*========================================== - * Mob search - *------------------------------------------ - */ -static int atmobsearch_sub(struct block_list *bl,va_list ap) -{ - int mob_id,fd; - static int number=0; - struct mob_data *md; - - nullpo_retr(0, bl); - - if(!ap){ - number=0; - return 0; - } - mob_id = va_arg(ap,int); - fd = va_arg(ap,int); - - md = (struct mob_data *)bl; - - if(md && fd && (mob_id==-1 || (md->class_==mob_id))){ - snprintf(atcmd_output, sizeof atcmd_output, "%2d[%3d:%3d] %s", - ++number,bl->x, bl->y,md->name); - clif_displaymessage(fd, atcmd_output); - } - return 0; -} -/*========================================== - * cleanmap - *------------------------------------------ - */ -static int atcommand_cleanmap_sub(struct block_list *bl,va_list ap) -{ - struct flooritem_data *fitem; - - nullpo_retr(0, bl); - - fitem = (struct flooritem_data *)bl; - if(fitem==NULL || fitem->bl.type!=BL_ITEM){ - if(battle_config.error_log) - printf("map_clearflooritem_timer : error\n"); - return 1; - } - delete_timer(fitem->cleartimer,map_clearflooritem_timer); - if(fitem->item_data.card[0] == (short)0xff00) - intif_delete_petdata(*((long *)(&fitem->item_data.card[1]))); - clif_clearflooritem(fitem,0); - map_delobject(fitem->bl.id); - - return 0; -} - -/*========================================== - * Read Message Data - *------------------------------------------ - */ -int msg_config_read(const char *cfgName) { - int msg_number; - char line[1024], w1[1024], w2[1024]; - FILE *fp; - static int called = 1; - - if ((fp = fopen(cfgName, "r")) == NULL) { - printf("Messages file not found: %s\n", cfgName); - return 1; - } - - if ((--called) == 0) - memset(&msg_table[0], 0, sizeof(msg_table[0]) * MAX_MSG); - while(fgets(line, sizeof(line)-1, fp)) { - if (line[0] == '/' && line[1] == '/') - continue; - if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) { - if (strcmpi(w1, "import") == 0) { - msg_config_read(w2); - } else { - msg_number = atoi(w1); - if (msg_number >= 0 && msg_number < MAX_MSG) { - if (msg_table[msg_number] != NULL) - aFree(msg_table[msg_number]); - msg_table[msg_number] = (char *)aCalloc(strlen(w2) + 1, sizeof (char)); - strcpy(msg_table[msg_number],w2); - // printf("message #%d: '%s'.\n", msg_number, msg_table[msg_number]); - } - } - } - } - fclose(fp); - - return 0; -} - -/*========================================== - * Cleanup Message Data - *------------------------------------------ - */ -void do_final_msg () { - int i; - for (i = 0; i < MAX_MSG; i++) - aFree(msg_table[i]); - return; -} - -/*========================================== - * - *------------------------------------------ - */ -static AtCommandInfo* get_atcommandinfo_byname(const char* name) { - int i; - - for (i = 0; atcommand_info[i].type != AtCommand_Unknown; i++) - if (strcmpi(atcommand_info[i].command + 1, name) == 0) - return &atcommand_info[i]; - - return NULL; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_config_read(const char *cfgName) { - char line[1024], w1[1024], w2[1024]; - AtCommandInfo* p; - FILE* fp; - - if ((fp = fopen(cfgName, "r")) == NULL) { - printf("At commands configuration file not found: %s\n", cfgName); - return 1; - } - - while (fgets(line, sizeof(line)-1, fp)) { - if (line[0] == '/' && line[1] == '/') - continue; - - if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2) - continue; - p = get_atcommandinfo_byname(w1); - if (p != NULL) { - p->level = atoi(w2); - if (p->level > 100) - p->level = 100; - else if (p->level < 0) - p->level = 0; - } - - if (strcmpi(w1, "import") == 0) - atcommand_config_read(w2); - else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 && - w2[0] != '/' && // symbol of standard ragnarok GM commands - w2[0] != '%' && // symbol of party chat speaking - w2[0] != '#') // symbol of charcommand - command_symbol = w2[0]; - } - fclose(fp); - - return 0; -} - - - -/*========================================== -// @ command processing functions - *------------------------------------------ - */ - -/*========================================== - * @send (used for testing packet sends from the client) - *------------------------------------------ - */ -int atcommand_send( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int a = atoi(message); - if (a) - { - unsigned char buf[1024]; - switch(a) - { - case 1: - WBUFW(buf,0)=0x18d; - case 2: - WBUFW(buf,0)=0x18e; - case 3: - WBUFW(buf,0)=0x18f; - case 4: - WBUFW(buf,0)=0x190; - } - } - return 0; -} - -// @rura -/*========================================== - * - *------------------------------------------ - */ -int atcommand_rura( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char map_name[100]; - int x = 0, y = 0; - int m; - - nullpo_retr(-1, sd); - - memset(map_name, '\0', sizeof(map_name)); - - if (!message || !*message || sscanf(message, "%99s %d %d", map_name, &x, &y) < 1) { - clif_displaymessage(fd, "Please, enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>)."); - return -1; - } - - if (x <= 0) - x = rand() % 399 + 1; - if (y <= 0) - y = rand() % 399 + 1; - - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - - if (x > 0 && x < 400 && y > 0 && y < 400) { - m = map_mapname2mapid(map_name); - if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - if (pc_setpos(sd, map_name, x, y, 3) == 0) - clif_displaymessage(fd, msg_table[0]); // Warped. - else { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[2]); // Coordinates out of range. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_where( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - memset(atcmd_player_name, '\0', sizeof atcmd_player_name); - if (sscanf(message, "%99[^\n]", atcmd_player_name) < 1) - return -1; - if(strncmp(sd->status.name,atcmd_player_name,24)==0) - return -1; - - if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) { - snprintf(atcmd_output, sizeof atcmd_output, "%s %d %d", - sd->mapname, sd->bl.x, sd->bl.y); - clif_displaymessage(fd, atcmd_output); - return -1; - } - snprintf(atcmd_output, sizeof atcmd_output, "%s %s %d %d", - atcmd_player_name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y); - clif_displaymessage(fd, atcmd_output); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_jumpto( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>)."); - return -1; - } - - memset(atcmd_player_name, '\0', sizeof atcmd_player_name); - if (sscanf(message, "%99[^\n]", atcmd_player_name) < 1) - return -1; - if(strncmp(sd->status.name,atcmd_player_name,24)==0) //Yourself mate? Tsk tsk tsk. - return -1; - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - pc_setpos(sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - sprintf(atcmd_output, msg_table[4], atcmd_player_name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_jump( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int x = 0, y = 0; - - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - sscanf(message, "%d %d", &x, &y); - - if (x <= 0) - x = rand() % 399 + 1; - if (y <= 0) - y = rand() % 399 + 1; - if (x > 0 && x < 400 && y > 0 && y < 400) { - if (sd->bl.m >= 0 && (map[sd->bl.m].flag.nowarp || map[sd->bl.m].flag.nowarpto) && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - pc_setpos(sd, sd->mapname, x, y, 3); - sprintf(atcmd_output, msg_table[5], x, y); // Jump to %d %d - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[2]); // Coordinates out of range. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_who( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i, j, count; - int pl_GM_level, GM_level; - char match_text[100]; - char player_name[24]; - - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(match_text, '\0', sizeof(match_text)); - memset(player_name, '\0', sizeof(player_name)); - - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - memcpy(player_name, pl_sd->status.name, 24); - for (j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) { // search with no case sensitive - if (pl_GM_level > 0) - sprintf(atcmd_output, "(CID:%d/AID:%d) Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.char_id, pl_sd->status.account_id, pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y); - else - sprintf(atcmd_output, "(CID:%d/AID:%d) Name: %s | Location: %s %d %d", pl_sd->status.char_id, pl_sd->status.account_id, pl_sd->status.name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[28]); // No player found. - else if (count == 1) - clif_displaymessage(fd, msg_table[29]); // 1 player found. - else { - sprintf(atcmd_output, msg_table[30], count); // %d players found. - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_who2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i, j, count; - int pl_GM_level, GM_level; - char match_text[100]; - char player_name[24]; - - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(match_text, '\0', sizeof(match_text)); - memset(player_name, '\0', sizeof(player_name)); - - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - memcpy(player_name, pl_sd->status.name, 24); - for (j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) { // search with no case sensitive - if (pl_GM_level > 0) - sprintf(atcmd_output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level); - else - sprintf(atcmd_output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[28]); // No player found. - else if (count == 1) - clif_displaymessage(fd, msg_table[29]); // 1 player found. - else { - sprintf(atcmd_output, msg_table[30], count); // %d players found. - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_who3( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char temp0[100]; - char temp1[100]; - struct map_session_data *pl_sd; - int i, j, count; - int pl_GM_level, GM_level; - char match_text[100]; - char player_name[24]; - struct guild *g; - struct party *p; - - nullpo_retr(-1, sd); - - memset(temp0, '\0', sizeof(temp0)); - memset(temp1, '\0', sizeof(temp1)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(match_text, '\0', sizeof(match_text)); - memset(player_name, '\0', sizeof(player_name)); - - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - memcpy(player_name, pl_sd->status.name, 24); - for (j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) { // search with no case sensitive - g = guild_search(pl_sd->status.guild_id); - if (g == NULL) - sprintf(temp1, "None"); - else - sprintf(temp1, "%s", g->name); - p = party_search(pl_sd->status.party_id); - if (p == NULL) - sprintf(temp0, "None"); - else - sprintf(temp0, "%s", p->name); - if (pl_GM_level > 0) - sprintf(atcmd_output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1); - else - sprintf(atcmd_output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[28]); // No player found. - else if (count == 1) - clif_displaymessage(fd, msg_table[29]); // 1 player found. - else { - sprintf(atcmd_output, msg_table[30], count); // %d players found. - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_whomap( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i, count; - int pl_GM_level, GM_level; - int map_id; - char map_name[100]; - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(map_name, '\0', sizeof(map_name)); - - if (!message || !*message) - map_id = sd->bl.m; - else { - sscanf(message, "%99s", map_name); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - if ((map_id = map_mapname2mapid(map_name)) < 0) - map_id = sd->bl.m; - } - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - if (pl_sd->bl.m == map_id) { - if (pl_GM_level > 0) - sprintf(atcmd_output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y); - else - sprintf(atcmd_output, "Name: %s | Location: %s %d %d", pl_sd->status.name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - - if (count == 0) - sprintf(atcmd_output, msg_table[54], map[map_id].name); // No player found in map '%s'. - else if (count == 1) - sprintf(atcmd_output, msg_table[55], map[map_id].name); // 1 player found in map '%s'. - else { - sprintf(atcmd_output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'. - } - clif_displaymessage(fd, atcmd_output); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_whomap2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i, count; - int pl_GM_level, GM_level; - int map_id = 0; - char map_name[100]; - - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(map_name, '\0', sizeof(map_name)); - - if (!message || !*message) - map_id = sd->bl.m; - else { - sscanf(message, "%99s", map_name); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - if ((map_id = map_mapname2mapid(map_name)) < 0) - map_id = sd->bl.m; - } - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - if (pl_sd->bl.m == map_id) { - if (pl_GM_level > 0) - sprintf(atcmd_output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level); - else - sprintf(atcmd_output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - - if (count == 0) - sprintf(atcmd_output, msg_table[54], map[map_id].name); // No player found in map '%s'. - else if (count == 1) - sprintf(atcmd_output, msg_table[55], map[map_id].name); // 1 player found in map '%s'. - else { - sprintf(atcmd_output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'. - } - clif_displaymessage(fd, atcmd_output); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_whomap3( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char temp0[100]; - char temp1[100]; - struct map_session_data *pl_sd; - int i, count; - int pl_GM_level, GM_level; - int map_id = 0; - char map_name[100]; - struct guild *g; - struct party *p; - - nullpo_retr(-1, sd); - - memset(temp0, '\0', sizeof(temp0)); - memset(temp1, '\0', sizeof(temp1)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(map_name, '\0', sizeof(map_name)); - - if (!message || !*message) - map_id = sd->bl.m; - else { - sscanf(message, "%99s", map_name); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - if ((map_id = map_mapname2mapid(map_name)) < 0) - map_id = sd->bl.m; - } - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - if (pl_sd->bl.m == map_id) { - g = guild_search(pl_sd->status.guild_id); - if (g == NULL) - sprintf(temp1, "None"); - else - sprintf(temp1, "%s", g->name); - p = party_search(pl_sd->status.party_id); - if (p == NULL) - sprintf(temp0, "None"); - else - sprintf(temp0, "%s", p->name); - if (pl_GM_level > 0) - sprintf(atcmd_output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1); - else - sprintf(atcmd_output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - - if (count == 0) - sprintf(atcmd_output, msg_table[54], map[map_id].name); // No player found in map '%s'. - else if (count == 1) - sprintf(atcmd_output, msg_table[55], map[map_id].name); // 1 player found in map '%s'. - else { - sprintf(atcmd_output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'. - } - clif_displaymessage(fd, atcmd_output); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_whogm( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char temp0[100]; - char temp1[100]; - struct map_session_data *pl_sd; - int i, j, count; - int pl_GM_level, GM_level; - char match_text[100]; - char player_name[24]; - struct guild *g; - struct party *p; - - nullpo_retr(-1, sd); - - memset(temp0, '\0', sizeof(temp0)); - memset(temp1, '\0', sizeof(temp1)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(match_text, '\0', sizeof(match_text)); - memset(player_name, '\0', sizeof(player_name)); - - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); - - count = 0; - GM_level = pc_isGM(sd); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (pl_GM_level > 0) { - if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level - memcpy(player_name, pl_sd->status.name, 24); - for (j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) { // search with no case sensitive - sprintf(atcmd_output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, " BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level); - clif_displaymessage(fd, atcmd_output); - g = guild_search(pl_sd->status.guild_id); - if (g == NULL) - sprintf(temp1, "None"); - else - sprintf(temp1, "%s", g->name); - p = party_search(pl_sd->status.party_id); - if (p == NULL) - sprintf(temp0, "None"); - else - sprintf(temp0, "%s", p->name); - sprintf(atcmd_output, " Party: '%s' | Guild: '%s'", temp0, temp1); - clif_displaymessage(fd, atcmd_output); - count++; - } - } - } - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[150]); // No GM found. - else if (count == 1) - clif_displaymessage(fd, msg_table[151]); // 1 GM found. - else { - sprintf(atcmd_output, msg_table[152], count); // %d GMs found. - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -int atcommand_whozeny( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i, j, count,c; - char match_text[100]; - char player_name[24]; - //int zeny[clif_countusers()]; - //int counted[clif_countusers()]; - int *zeny = (int *)aCallocA(clif_countusers(), sizeof(int)); - int *counted = (int *)aCallocA(clif_countusers(), sizeof(int)); - - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(match_text, '\0', sizeof(match_text)); - memset(player_name, '\0', sizeof(player_name)); - - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); - - count = 0; - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - memcpy(player_name, pl_sd->status.name, 24); - for (j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) { // search with no case sensitive - zeny[count]=pl_sd->status.zeny; - counted[i]=0; - count++; - } - } - } - - qsort(zeny, count, sizeof(int), hightolow_compare); - for (c = 0; c < count && c < 50; c++) { - if(!zeny[c]) - continue; - for (i = 0; i < fd_max; i++) { - if(!zeny[c]) - continue; - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && zeny[c] && counted[i]==0) { - if(pl_sd->status.zeny==zeny[c]) { - sprintf(atcmd_output, "Name: %s | Zeny: %d", pl_sd->status.name, pl_sd->status.zeny); - clif_displaymessage(fd, atcmd_output); - zeny[c]=0; - counted[i]=1; - } - } - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[28]); // No player found. - else if (count == 1) - clif_displaymessage(fd, msg_table[29]); // 1 player found. - else { - sprintf(atcmd_output, msg_table[30], count); // %d players found. - clif_displaymessage(fd, atcmd_output); - } - - aFree(zeny); - aFree(counted); - - return 0; -} - - -// cause random emote on all online players [Valaris] -int atcommand_happyhappyjoyjoy( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i,e; - - nullpo_retr(-1, sd); - - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - e=rand()%40; - if(e==34) - e = 0; - clif_emotion(&pl_sd->bl,e); - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_save( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - pc_setsavepoint(sd, sd->mapname, sd->bl.x, sd->bl.y); - if (sd->status.pet_id > 0 && sd->pd) - intif_save_petdata(sd->status.account_id, &sd->pet); - pc_makesavestatus(sd); - chrif_save(sd); - storage_storage_save(sd); - clif_displaymessage(fd, msg_table[6]); // Character data respawn point saved. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_load( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int m; - - nullpo_retr(-1, sd); - - m = map_mapname2mapid(sd->status.save_point.map); - if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[249]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 0); - clif_displaymessage(fd, msg_table[7]); // Warping to respawn point. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_speed( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int speed; - - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message) { - sprintf(atcmd_output, "Please, enter a speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - speed = atoi(message); - if (speed >= MIN_WALK_SPEED && speed <= MAX_WALK_SPEED) { - sd->speed = speed; - //sd->walktimer = x; - //この文を追加 by れ - clif_updatestatus(sd, SP_SPEED); - clif_displaymessage(fd, msg_table[8]); // Speed changed. - } else { - sprintf(atcmd_output, "Please, enter a valid speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_storage( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct storage *stor; //changes from Freya/Yor - nullpo_retr(-1, sd); - - if (sd->state.storage_flag == 1) { - clif_displaymessage(fd, msg_table[250]); - return -1; - } - - if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) { - clif_displaymessage(fd, msg_table[250]); - return -1; - } - - storage_storageopen(sd); - - return 0; -} - - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_guildstorage( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct storage *stor; //changes from Freya/Yor - nullpo_retr(-1, sd); - - if (sd->status.guild_id > 0) { - if (sd->state.storage_flag == 1) { - clif_displaymessage(fd, msg_table[251]); - return -1; - } - if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) { - clif_displaymessage(fd, msg_table[251]); - return -1; - } - storage_guild_storageopen(sd); - } else { - clif_displaymessage(fd, msg_table[252]); - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_option( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int param1 = 0, param2 = 0, param3 = 0; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %d %d", ¶m1, ¶m2, ¶m3) < 1 || param1 < 0 || param2 < 0 || param3 < 0) { - clif_displaymessage(fd, "Please, enter at least a option (usage: @option <param1:0+> <param2:0+> <param3:0+>)."); - return -1; - } - - sd->opt1 = param1; - sd->opt2 = param2; - if (!(sd->status.option & CART_MASK) && param3 & CART_MASK) { - clif_cart_itemlist(sd); - clif_cart_equiplist(sd); - clif_updatestatus(sd, SP_CARTINFO); - } - sd->status.option = param3; - // fix pecopeco display - if (sd->status.class_ == 13 || sd->status.class_ == 21 || sd->status.class_ == 4014 || sd->status.class_ == 4022) { - if (!pc_isriding(sd)) { // sd have the new value... - if (sd->status.class_ == 13) - sd->status.class_ = sd->view_class = 7; - else if (sd->status.class_ == 21) - sd->status.class_ = sd->view_class = 14; - else if (sd->status.class_ == 4014) - sd->status.class_ = sd->view_class = 4008; - else if (sd->status.class_ == 4022) - sd->status.class_ = sd->view_class = 4015; - } - } else { - if (pc_isriding(sd)) { // sd have the new value... - if (sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor]) - sd->status.option &= ~0x0020; - } else { - if (sd->status.class_ == 7) - sd->status.class_ = sd->view_class = 13; - else if (sd->status.class_ == 14) - sd->status.class_ = sd->view_class = 21; - else if (sd->status.class_ == 4008) - sd->status.class_ = sd->view_class = 4014; - else if (sd->status.class_ == 4015) - sd->status.class_ = sd->view_class = 4022; - else - sd->status.option &= ~0x0020; - } - } - } - - clif_changeoption(&sd->bl); - status_calc_pc(sd, 0); - clif_displaymessage(fd, msg_table[9]); // Options changed. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_hide( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (sd->status.option & OPTION_HIDE) { - sd->status.option &= ~OPTION_HIDE; - clif_displaymessage(fd, msg_table[10]); // Invisible: Off - } else { - sd->status.option |= OPTION_HIDE; - clif_displaymessage(fd, msg_table[11]); // Invisible: On - } - clif_changeoption(&sd->bl); - - return 0; -} - -/*========================================== - * 転職する upperを指定すると転生や養子にもなれる - *------------------------------------------ - */ -int atcommand_jobchange( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int job = 0, upper = 0; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) { - - int i, found = 0; - const struct { char name[16]; int id; } jobs[] = { - { "novice", 0 }, - { "swordsman", 1 }, - { "mage", 2 }, - { "archer", 3 }, - { "acolyte", 4 }, - { "merchant", 5 }, - { "thief", 6 }, - { "knight", 7 }, - { "priest", 8 }, - { "priestess", 8 }, - { "wizard", 9 }, - { "blacksmith", 10 }, - { "hunter", 11 }, - { "assassin", 12 }, - { "crusader", 14 }, - { "monk", 15 }, - { "sage", 16 }, - { "rogue", 17 }, - { "alchemist", 18 }, - { "bard", 19 }, - { "dancer", 20 }, - { "super novice", 23 }, - { "supernovice", 23 }, - { "high novice", 4001 }, - { "swordsman high", 4002 }, - { "mage high", 4003 }, - { "archer high", 4004 }, - { "acolyte high", 4005 }, - { "merchant high", 4006 }, - { "thief high", 4007 }, - { "lord knight", 4008 }, - { "high priest", 4009 }, - { "high priestess", 4009 }, - { "high wizard", 4010 }, - { "whitesmith", 4011 }, - { "sniper", 4012 }, - { "assassin cross", 4013 }, - { "paladin", 4015 }, - { "champion", 4016 }, - { "professor", 4017 }, - { "stalker", 4018 }, - { "creator", 4019 }, - { "clown", 4020 }, - { "gypsy", 4021 }, - { "baby novice", 4023 }, - { "baby swordsman", 4024 }, - { "baby mage", 4025 }, - { "baby archer", 4026 }, - { "baby acolyte", 4027 }, - { "baby merchant", 4028 }, - { "baby thief", 4029 }, - { "baby knight", 4030 }, - { "baby priest", 4031 }, - { "baby priestess", 4031 }, - { "baby wizard", 4032 }, - { "baby blacksmith",4033 }, - { "baby hunter", 4034 }, - { "baby assassin", 4035 }, - { "baby crusader", 4037 }, - { "baby monk", 4038 }, - { "baby sage", 4039 }, - { "baby rogue", 4040 }, - { "baby alchemist", 4041 }, - { "baby bard", 4042 }, - { "baby dancer", 4043 }, - { "super baby", 4045 }, - }; - - for (i=0; i < (int)(sizeof(jobs) / sizeof(jobs[0])); i++) { - if (strncmpi(message, jobs[i].name, 16) == 0) { - job = jobs[i].id; - upper = 0; - found = 1; - break; - } - } - - if (!found) { - clif_displaymessage(fd, "Please, enter job ID (usage: @job/@jobchange <job ID>)."); - return -1; - } - } - - if (job == 37 ||job == 45) - return 0; - - if ((job >= 0 && job < MAX_PC_CLASS)) { - int j; - - // fix pecopeco display - if ((job != 13 && job != 21 && job != 4014 && job != 4022)) { - if (pc_isriding(sd)) { - if (sd->status.class_ == 13) - sd->status.class_ = sd->view_class = 7; - if (sd->status.class_ == 21) - sd->status.class_ = sd->view_class = 14; - if (sd->status.class_ == 4014) - sd->status.class_ = sd->view_class = 4008; - if (sd->status.class_ == 4022) - sd->status.class_ = sd->view_class = 4015; - sd->status.option &= ~0x0020; - clif_changeoption(&sd->bl); - status_calc_pc(sd, 0); - } - } else { - if (!pc_isriding(sd)) { - if (job == 13) - job = 7; - if (job == 21) - job = 14; - if (job == 4014) - job = 4008; - if (job == 4022) - job = 4015; - } - } - for (j=0; j < MAX_INVENTORY; j++) { - if(sd->status.inventory[j].nameid>0 && sd->status.inventory[j].equip!=0) - pc_unequipitem(sd, j, 3); - } - if (pc_jobchange(sd, job, upper) == 0) - clif_displaymessage(fd, msg_table[12]); // Your job has been changed. - else { - clif_displaymessage(fd, msg_table[155]); // Impossible to change your job. - return -1; - } - } else { - clif_displaymessage(fd, "Please, enter a valid job ID (usage: @job/@jobchange <job ID>)."); - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_die( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - clif_specialeffect(&sd->bl,450,1); - pc_damage(NULL, sd, sd->status.hp + 1); - clif_displaymessage(fd, msg_table[13]); // A pity! You've died. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_kill( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @kill <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(fd, msg_table[14]); // Character killed. - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_alive( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (pc_isdead(sd)) { - sd->status.hp = sd->status.max_hp; - sd->status.sp = sd->status.max_sp; - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - pc_setstand(sd); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - clif_updatestatus(sd, SP_HP); - clif_updatestatus(sd, SP_SP); - clif_resurrection(&sd->bl, 1); - clif_displaymessage(fd, msg_table[16]); // You've been revived! It's a miracle! - return 0; - } - return -1; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_kami( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a message (usage: @kami <message>)."); - return -1; - } - - sscanf(message, "%199[^\n]", atcmd_output); - intif_GMmessage(atcmd_output, strlen(atcmd_output) + 1, (*(command + 5) == 'b') ? 0x10 : 0); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_heal( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int hp = 0, sp = 0; // [Valaris] thanks to fov - nullpo_retr(-1, sd); - - sscanf(message, "%d %d", &hp, &sp); - - if (hp == 0 && sp == 0) { - hp = sd->status.max_hp - sd->status.hp; - sp = sd->status.max_sp - sd->status.sp; - } else { - if (hp > 0 && (hp > sd->status.max_hp || hp > (sd->status.max_hp - sd->status.hp))) // fix positiv overflow - hp = sd->status.max_hp - sd->status.hp; - else if (hp < 0 && (hp < -sd->status.max_hp || hp < (1 - sd->status.hp))) // fix negativ overflow - hp = 1 - sd->status.hp; - if (sp > 0 && (sp > sd->status.max_sp || sp > (sd->status.max_sp - sd->status.sp))) // fix positiv overflow - sp = sd->status.max_sp - sd->status.sp; - else if (sp < 0 && (sp < -sd->status.max_sp || sp < (1 - sd->status.sp))) // fix negativ overflow - sp = 1 - sd->status.sp; - } - - if (hp > 0) // display like heal - clif_heal(fd, SP_HP, hp); - else if (hp < 0) // display like damage - clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0 , 4, 0); - if (sp > 0) // no display when we lost SP - clif_heal(fd, SP_SP, sp); - - if (hp != 0 || sp != 0) { - pc_heal(sd, hp, sp); - if (hp >= 0 && sp >= 0) - clif_displaymessage(fd, msg_table[17]); // HP, SP recovered. - else - clif_displaymessage(fd, msg_table[156]); // HP or/and SP modified. - } else { - clif_displaymessage(fd, msg_table[157]); // HP and SP are already with the good value. - return -1; - } - - return 0; -} - -/*========================================== - * @item command (usage: @item <name/id_of_item> <quantity>) (modified by [Yor] for pet_egg) - *------------------------------------------ - */ -int atcommand_item( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char item_name[100]; - int number = 0, item_id, flag; - struct item item_tmp; - struct item_data *item_data; - int get_count, i, pet_id; - nullpo_retr(-1, sd); - - memset(item_name, '\0', sizeof(item_name)); - - if (!message || !*message || sscanf(message, "%99s %d", item_name, &number) < 1) { - clif_displaymessage(fd, "Please, enter an item name/id (usage: @item <item name or ID> [quantity])."); - return -1; - } - - if (number <= 0) - number = 1; - - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) - item_id = item_data->nameid; - - if (item_id >= 500) { - get_count = number; - // check pet egg - pet_id = search_petDB_index(item_id, PET_EGG); - if (item_data->type == 4 || item_data->type == 5 || - item_data->type == 7 || item_data->type == 8) { - get_count = 1; - } - for (i = 0; i < number; i += get_count) { - // if pet egg - if (pet_id >= 0) { - sd->catch_target_class = pet_db[pet_id].class_; - intif_create_pet(sd->status.account_id, sd->status.char_id, - (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv, - (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate, - 100, 0, 1, pet_db[pet_id].jname); - // if not pet egg - } else { - memset(&item_tmp, 0, sizeof(item_tmp)); - item_tmp.nameid = item_id; - item_tmp.identify = 1; - if ((flag = pc_additem((struct map_session_data*)sd, &item_tmp, get_count))) - clif_additem((struct map_session_data*)sd, 0, 0, flag); - } - } - clif_displaymessage(fd, msg_table[18]); // Item created. - } else { - clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_item2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct item item_tmp; - struct item_data *item_data; - char item_name[100]; - int item_id, number = 0; - int identify = 0, refine = 0, attr = 0; - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - int flag; - int loop, get_count, i; - nullpo_retr(-1, sd); - - memset(item_name, '\0', sizeof(item_name)); - - if (!message || !*message || sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9) { - clif_displaymessage(fd, "Please, enter all informations (usage: @item2 <item name or ID> <quantity>"); - clif_displaymessage(fd, " <Identify_flag> <refine> <attribut> <Card1> <Card2> <Card3> <Card4>)."); - return -1; - } - - if (number <= 0) - number = 1; - - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) - item_id = item_data->nameid; - - if (item_id > 500) { - loop = 1; - get_count = number; - if (item_data->type == 4 || item_data->type == 5 || - item_data->type == 7 || item_data->type == 8) { - loop = number; - get_count = 1; - if (item_data->type == 7) { - identify = 1; - refine = 0; - } - if (item_data->type == 8) - refine = 0; - if (refine > 10) - refine = 10; - } else { - identify = 1; - refine = attr = 0; - } - for (i = 0; i < loop; i++) { - memset(&item_tmp, 0, sizeof(item_tmp)); - item_tmp.nameid = item_id; - item_tmp.identify = identify; - item_tmp.refine = refine; - item_tmp.attribute = attr; - item_tmp.card[0] = c1; - item_tmp.card[1] = c2; - item_tmp.card[2] = c3; - item_tmp.card[3] = c4; - if ((flag = pc_additem(sd, &item_tmp, get_count))) - clif_additem(sd, 0, 0, flag); - } - clif_displaymessage(fd, msg_table[18]); // Item created. - } else { - clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_itemreset( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - nullpo_retr(-1, sd); - - for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) - pc_delitem(sd, i, sd->status.inventory[i].amount, 0); - } - clif_displaymessage(fd, msg_table[20]); // All of your items have been removed. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_itemcheck( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - pc_checkitem(sd); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_baselevelup( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int level, i; - nullpo_retr(-1, sd); - - if (!message || !*message || (level = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a level adjustement (usage: @lvup/@blevel/@baselvlup <number of levels>)."); - return -1; - } - - if (level > 0) { - if (sd->status.base_level == battle_config.maximum_level) { // check for max level by Valaris - clif_displaymessage(fd, msg_table[47]); // Base level can't go any higher. - return -1; - } // End Addition - if ((unsigned int)level > battle_config.maximum_level || (unsigned int)level > (battle_config.maximum_level - sd->status.base_level)) // fix positiv overflow - level = battle_config.maximum_level - sd->status.base_level; - for (i = 1; i <= level; i++) - sd->status.status_point += (sd->status.base_level + i + 14) / 5; - sd->status.base_level += level; - clif_updatestatus(sd, SP_BASELEVEL); - clif_updatestatus(sd, SP_NEXTBASEEXP); - clif_updatestatus(sd, SP_STATUSPOINT); - status_calc_pc(sd, 0); - pc_heal(sd, sd->status.max_hp, sd->status.max_sp); - clif_misceffect(&sd->bl, 0); - clif_displaymessage(fd, msg_table[21]); // Base level raised. - } else { - if (sd->status.base_level == 1) { - clif_displaymessage(fd, msg_table[158]); // Base level can't go any lower. - return -1; - } - if (level < -(int)battle_config.maximum_level || level < (1 - (int)sd->status.base_level)) // fix negativ overflow - level = 1 - sd->status.base_level; - if (sd->status.status_point > 0) { - for (i = 0; i > level; i--) - sd->status.status_point -= (sd->status.base_level + i + 14) / 5; - if (sd->status.status_point < 0) - sd->status.status_point = 0; - clif_updatestatus(sd, SP_STATUSPOINT); - } // to add: remove status points from stats - sd->status.base_level += level; - clif_updatestatus(sd, SP_BASELEVEL); - clif_updatestatus(sd, SP_NEXTBASEEXP); - status_calc_pc(sd, 0); - clif_displaymessage(fd, msg_table[22]); // Base level lowered. - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_joblevelup( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - unsigned int up_level = 50; - int level; - struct pc_base_job s_class; - nullpo_retr(-1, sd); - s_class = pc_calc_base_job(sd->status.class_); - - if (!message || !*message || (level = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a level adjustement (usage: @joblvup/@jlevel/@joblvlup <number of levels>)."); - return -1; - } - - if (s_class.job == 0) - up_level -= 40; - // super novices can go up to 99 [celest] - else if (s_class.job == 23) - up_level += 49; - else if (sd->status.class_ > 4007 && sd->status.class_ < 4023) - up_level += 20; - - if (level > 0) { - if (sd->status.job_level == up_level) { - clif_displaymessage(fd, msg_table[23]); // Job level can't go any higher. - return -1; - } - if ((unsigned int)level > up_level || (unsigned int)level > (up_level - sd->status.job_level)) // fix positiv overflow - level = up_level - sd->status.job_level; - sd->status.job_level += level; - clif_updatestatus(sd, SP_JOBLEVEL); - clif_updatestatus(sd, SP_NEXTJOBEXP); - sd->status.skill_point += level; - clif_updatestatus(sd, SP_SKILLPOINT); - status_calc_pc(sd, 0); - clif_misceffect(&sd->bl, 1); - clif_displaymessage(fd, msg_table[24]); // Job level raised. - } else { - if (sd->status.job_level == 1) { - clif_displaymessage(fd, msg_table[159]); // Job level can't go any lower. - return -1; - } - if (level < -(int)up_level || level < (1 - (int)sd->status.job_level)) // fix negativ overflow - level = 1 - sd->status.job_level; - sd->status.job_level += level; - clif_updatestatus(sd, SP_JOBLEVEL); - clif_updatestatus(sd, SP_NEXTJOBEXP); - if (sd->status.skill_point > 0) { - sd->status.skill_point += level; - if (sd->status.skill_point < 0) - sd->status.skill_point = 0; - clif_updatestatus(sd, SP_SKILLPOINT); - } // to add: remove status points from skills - status_calc_pc(sd, 0); - clif_displaymessage(fd, msg_table[25]); // Job level lowered. - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_help( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char buf[2048], w1[2048], w2[2048]; - int i, gm_level; - FILE* fp; - nullpo_retr(-1, sd); - - memset(buf, '\0', sizeof(buf)); - - if ((fp = fopen(help_txt, "r")) != NULL) { - clif_displaymessage(fd, msg_table[26]); // Help commands: - gm_level = pc_isGM(sd); - while(fgets(buf, sizeof(buf) - 1, fp) != NULL) { - if (buf[0] == '/' && buf[1] == '/') - continue; - for (i = 0; buf[i] != '\0'; i++) { - if (buf[i] == '\r' || buf[i] == '\n') { - buf[i] = '\0'; - break; - } - } - if (sscanf(buf, "%2047[^:]:%2047[^\n]", w1, w2) < 2) - clif_displaymessage(fd, buf); - else if (gm_level >= atoi(w1)) - clif_displaymessage(fd, w2); - } - fclose(fp); - } else { - clif_displaymessage(fd, msg_table[27]); // File help.txt not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_gm( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char password[100]; - nullpo_retr(-1, sd); - - memset(password, '\0', sizeof(password)); - - if (!message || !*message || sscanf(message, "%99[^\n]", password) < 1) { - clif_displaymessage(fd, "Please, enter a password (usage: @gm <password>)."); - return -1; - } - - if (pc_isGM(sd)) { // a GM can not use this function. only a normal player (become gm is not for gm!) - clif_displaymessage(fd, msg_table[50]); // You already have some GM powers. - return -1; - } else - chrif_changegm(sd->status.account_id, password, strlen(password) + 1); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_pvpoff( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris] - clif_displaymessage(fd, msg_table[52]); // This option cannot be used in PK Mode. - return -1; - } - - if (map[sd->bl.m].flag.pvp) { - map[sd->bl.m].flag.pvp = 0; - clif_send0199(sd->bl.m, 0); - for (i = 0; i < fd_max; i++) { //人数分ループ - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - if (sd->bl.m == pl_sd->bl.m) { - clif_pvpset(pl_sd, 0, 0, 2); - if (pl_sd->pvp_timer != -1) { - delete_timer(pl_sd->pvp_timer, pc_calc_pvprank_timer); - pl_sd->pvp_timer = -1; - } - } - } - } - clif_displaymessage(fd, msg_table[31]); // PvP: Off. - } else { - clif_displaymessage(fd, msg_table[160]); // PvP is already Off. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_pvpon( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris] - clif_displaymessage(fd, msg_table[52]); // This option cannot be used in PK Mode. - return -1; - } - - if (!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.nopvp) { - map[sd->bl.m].flag.pvp = 1; - clif_send0199(sd->bl.m, 1); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - if (sd->bl.m == pl_sd->bl.m && pl_sd->pvp_timer == -1) { - pl_sd->pvp_timer = add_timer(gettick() + 200, - pc_calc_pvprank_timer, pl_sd->bl.id, 0); - pl_sd->pvp_rank = 0; - pl_sd->pvp_lastusers = 0; - pl_sd->pvp_point = 5; - } - } - } - clif_displaymessage(fd, msg_table[32]); // PvP: On. - } else { - clif_displaymessage(fd, msg_table[161]); // PvP is already On. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_gvgoff( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.gvg) { - map[sd->bl.m].flag.gvg = 0; - clif_send0199(sd->bl.m, 0); - clif_displaymessage(fd, msg_table[33]); // GvG: Off. - } else { - clif_displaymessage(fd, msg_table[162]); // GvG is already Off. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_gvgon( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (!map[sd->bl.m].flag.gvg) { - map[sd->bl.m].flag.gvg = 1; - clif_send0199(sd->bl.m, 3); - clif_displaymessage(fd, msg_table[34]); // GvG: On. - } else { - clif_displaymessage(fd, msg_table[163]); // GvG is already On. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_model( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int hair_style = 0, hair_color = 0, cloth_color = 0; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d %d %d", &hair_style, &hair_color, &cloth_color) < 1) { - sprintf(atcmd_output, "Please, enter at least a value (usage: @model <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d>).", - MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE && - hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR && - cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) { - //服の色変更 - if (cloth_color != 0 && sd->status.sex == 1 && (sd->status.class_ == 12 || sd->status.class_ == 17)) { - //服の色未実装職の判定 - clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class. - return -1; - } else { - pc_changelook(sd, LOOK_HAIR, hair_style); - pc_changelook(sd, LOOK_HAIR_COLOR, hair_color); - pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color); - clif_displaymessage(fd, msg_table[36]); // Appearence changed. - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - - return 0; -} - -/*========================================== - * @dye && @ccolor - *------------------------------------------ - */ -int atcommand_dye(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int cloth_color = 0; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) { - sprintf(atcmd_output, "Please, enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).", MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) { - pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color); - clif_displaymessage(fd, msg_table[36]); // Appearence changed. - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - - return 0; -} - -/*========================================== - * @hairstyle && @hstyle - *------------------------------------------ - */ -int atcommand_hair_style(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int hair_style = 0; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) { - sprintf(atcmd_output, "Please, enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) { - if (hair_style != 0 && sd->status.sex == 1 && (sd->status.class_ == 12 || sd->status.class_ == 17)) { - clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class. - return -1; - } else { - pc_changelook(sd, LOOK_HAIR, hair_style); - clif_displaymessage(fd, msg_table[36]); // Appearence changed. - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - - return 0; -} - -/*========================================== - * @charhairstyle by [MouseJstr] - *------------------------------------------ - */ -int -atcommand_charhairstyle(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - return 0; -} - -/*========================================== - * @haircolor && @hcolor - *------------------------------------------ - */ -int atcommand_hair_color(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int hair_color = 0; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) { - sprintf(atcmd_output, "Please, enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).", MIN_HAIR_COLOR, MAX_HAIR_COLOR); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) { - if (hair_color != 0 && sd->status.sex == 1 && (sd->status.class_ == 12 || sd->status.class_ == 17)) { - clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class. - return -1; - } else { - pc_changelook(sd, LOOK_HAIR_COLOR, hair_color); - clif_displaymessage(fd, msg_table[36]); // Appearence changed. - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - - return 0; -} - -/*========================================== - * @go [city_number/city_name]: improved by [yor] to add city names and help - *------------------------------------------ - */ -int atcommand_go( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - int town; - char map_name[100]; - int m; - - const struct { char map[16]; int x, y; } data[] = { - { "prontera.gat", 156, 191 }, // 0=Prontera - { "morocc.gat", 156, 93 }, // 1=Morroc - { "geffen.gat", 119, 59 }, // 2=Geffen - { "payon.gat", 162, 233 }, // 3=Payon - { "alberta.gat", 192, 147 }, // 4=Alberta - { "izlude.gat", 128, 114 }, // 5=Izlude - { "aldebaran.gat",140, 131 }, // 6=Al de Baran - { "xmas.gat", 147, 134 }, // 7=Lutie - { "comodo.gat", 209, 143 }, // 8=Comodo - { "yuno.gat", 157, 51 }, // 9=Yuno - { "amatsu.gat", 198, 84 }, // 10=Amatsu - { "gonryun.gat", 160, 120 }, // 11=Gon Ryun - { "umbala.gat", 89, 157 }, // 12=Umbala - { "niflheim.gat", 21, 153 }, // 13=Niflheim - { "louyang.gat", 217, 40 }, // 14=Lou Yang - { "new_1-1.gat", 53, 111 }, // 15=Start point - { "sec_pri.gat", 23, 61 }, // 16=Prison - { "jawaii.gat", 249, 127 }, // 17=Jawaii - { "ayothaya.gat", 151, 117 }, // 18=Ayothaya - }; - - nullpo_retr(-1, sd); - - if(map[sd->bl.m].flag.nogo) { - clif_displaymessage(sd->fd,"You can not use @go on this map."); - return 0; - } - - memset(map_name, '\0', sizeof(map_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - // get the number - town = atoi(message); - - // if no value, display all value - if (!message || !*message || sscanf(message, "%99s", map_name) < 1 || town < -3 || town >= (int)(sizeof(data) / sizeof(data[0]))) { - clif_displaymessage(fd, msg_table[38]); // Invalid location number or name. - clif_displaymessage(fd, msg_table[82]); // Please, use one of this number/name: - clif_displaymessage(fd, "-3=(Memo point 2) 4=Alberta 11=Gon Ryun"); - clif_displaymessage(fd, "-2=(Memo point 1) 5=Izlude 12=Umbala"); - clif_displaymessage(fd, "-1=(Memo point 0) 6=Al de Baran 13=Niflheim"); - clif_displaymessage(fd, " 0=Prontera 7=Lutie 14=Lou Yang"); - clif_displaymessage(fd, " 1=Morroc 8=Comodo 15=Start point"); - clif_displaymessage(fd, " 2=Geffen 9=Yuno 16=Prison"); - clif_displaymessage(fd, " 3=Payon 10=Amatsu 17=Jawaii"); - clif_displaymessage(fd, " 18=Ayothaya"); - return -1; - } else { - // get possible name of the city and add .gat if not in the name - map_name[sizeof(map_name)-1] = '\0'; - for (i = 0; map_name[i]; i++) - map_name[i] = tolower(map_name[i]); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - // try to see if it's a name, and not a number (try a lot of possibilities, write errors and abbreviations too) - if (strncmp(map_name, "prontera.gat", 3) == 0) { // 3 first characters - town = 0; - } else if (strncmp(map_name, "morocc.gat", 3) == 0) { // 3 first characters - town = 1; - } else if (strncmp(map_name, "geffen.gat", 3) == 0) { // 3 first characters - town = 2; - } else if (strncmp(map_name, "payon.gat", 3) == 0 || // 3 first characters - strncmp(map_name, "paion.gat", 3) == 0) { // writing error (3 first characters) - town = 3; - } else if (strncmp(map_name, "alberta.gat", 3) == 0) { // 3 first characters - town = 4; - } else if (strncmp(map_name, "izlude.gat", 3) == 0 || // 3 first characters - strncmp(map_name, "islude.gat", 3) == 0) { // writing error (3 first characters) - town = 5; - } else if (strncmp(map_name, "aldebaran.gat", 3) == 0 || // 3 first characters - strcmp(map_name, "al.gat") == 0) { // al (de baran) - town = 6; - } else if (strncmp(map_name, "lutie.gat", 3) == 0 || // name of the city, not name of the map (3 first characters) - strcmp(map_name, "christmas.gat") == 0 || // name of the symbol - strncmp(map_name, "xmas.gat", 3) == 0 || // 3 first characters - strncmp(map_name, "x-mas.gat", 3) == 0) { // writing error (3 first characters) - town = 7; - } else if (strncmp(map_name, "comodo.gat", 3) == 0) { // 3 first characters - town = 8; - } else if (strncmp(map_name, "yuno.gat", 3) == 0) { // 3 first characters - town = 9; - } else if (strncmp(map_name, "amatsu.gat", 3) == 0 || // 3 first characters - strncmp(map_name, "ammatsu.gat", 3) == 0) { // writing error (3 first characters) - town = 10; - } else if (strncmp(map_name, "gonryun.gat", 3) == 0) { // 3 first characters - town = 11; - } else if (strncmp(map_name, "umbala.gat", 3) == 0) { // 3 first characters - town = 12; - } else if (strncmp(map_name, "niflheim.gat", 3) == 0) { // 3 first characters - town = 13; - } else if (strncmp(map_name, "louyang.gat", 3) == 0) { // 3 first characters - town = 14; - } else if (strncmp(map_name, "new_1-1.gat", 3) == 0 || // 3 first characters (or "newbies") - strncmp(map_name, "startpoint.gat", 3) == 0 || // name of the position (3 first characters) - strncmp(map_name, "begining.gat", 3) == 0) { // name of the position (3 first characters) - town = 15; - } else if (strncmp(map_name, "sec_pri.gat", 3) == 0 || // 3 first characters - strncmp(map_name, "prison.gat", 3) == 0 || // name of the position (3 first characters) - strncmp(map_name, "jails.gat", 3) == 0) { // name of the position - town = 16; - } else if (strncmp(map_name, "jawaii.gat", 3) == 0 || // 3 first characters - strncmp(map_name, "jawai.gat", 3) == 0) { // writing error (3 first characters) - town = 17; - } else if (strncmp(map_name, "ayothaya.gat", 4) == 0 || // 3 first characters - strncmp(map_name, "ayotaya.gat", 4) == 0) { // writing error (3 first characters) - town = 18; - } - - if (town >= -3 && town <= -1) { - if (sd->status.memo_point[-town-1].map[0]) { - m = map_mapname2mapid(sd->status.memo_point[-town-1].map); - if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - if (pc_setpos(sd, sd->status.memo_point[-town-1].map, sd->status.memo_point[-town-1].x, sd->status.memo_point[-town-1].y, 3) == 0) { - clif_displaymessage(fd, msg_table[0]); // Warped. - } else { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - } else { - sprintf(atcmd_output, msg_table[164], -town-1); // Your memo point #%d doesn't exist. - clif_displaymessage(fd, atcmd_output); - return -1; - } - } else if (town >= 0 && town < (int)(sizeof(data) / sizeof(data[0]))) { - m = map_mapname2mapid((char *)data[town].map); - if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - if (pc_setpos(sd, (char *)data[town].map, data[town].x, data[town].y, 3) == 0) { - clif_displaymessage(fd, msg_table[0]); // Warped. - } else { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - } else { // if you arrive here, you have an error in town variable when reading of names - clif_displaymessage(fd, msg_table[38]); // Invalid location number or name. - return -1; - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_monster( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char name[100]; - char monster[100]; - int mob_id; - int number = 0; - int x = 0, y = 0; - int count; - int i, j, k; - int mx, my, range; - nullpo_retr(-1, sd); - - memset(name, '\0', sizeof(name)); - memset(monster, '\0', sizeof(monster)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || - (sscanf(message, "\"%[^\"]\" %99s %d %d %d", name, monster, &number, &x, &y) < 2 && - sscanf(message, "%99s \"%[^\"]\" %d %d %d", monster, name, &number, &x, &y) < 2 && - sscanf(message, "%99s %99s %d %d %d", name, monster, &number, &x, &y) < 2)) { - clif_displaymessage(fd, msg_table[80]); // Give a display name and monster name/id please. - return -1; - } - - if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = mobdb_checkid(atoi(monster)); - - if (mob_id == 0) { - clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name. - return -1; - } - - if (mob_id == 1288) { - clif_displaymessage(fd, msg_table[83]); // Cannot spawn emperium. - return -1; - } - - if (number <= 0) - number = 1; - - if (strlen(name) < 1) - strcpy(name, "--ja--"); - - // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive - if (battle_config.atc_spawn_quantity_limit >= 1 && number > battle_config.atc_spawn_quantity_limit) - number = battle_config.atc_spawn_quantity_limit; - - if (battle_config.etc_log) - printf("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, x, y); - - count = 0; - range = (int)sqrt(number) / 2; - range = range * 2 + 5; // calculation of an odd number (+ 4 area around) - for (i = 0; i < number; i++) { - j = 0; - k = 0; - while(j++ < 8 && k == 0) { // try 8 times to spawn the monster (needed for close area) - if (x <= 0) - mx = sd->bl.x + (rand() % range - (range / 2)); - else - mx = x; - if (y <= 0) - my = sd->bl.y + (rand() % range - (range / 2)); - else - my = y; - k = mob_once_spawn((struct map_session_data*)sd, "this", mx, my, name, mob_id, 1, ""); - } - count += (k != 0) ? 1 : 0; - } - - if (count != 0) - if (number == count) - clif_displaymessage(fd, msg_table[39]); // All monster summoned! - else { - sprintf(atcmd_output, msg_table[240], count); // %d monster(s) summoned! - clif_displaymessage(fd, atcmd_output); - } - else { - clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_spawn( - const int fd, struct map_session_data* sd, - const char* command, const char* message) { - char name[100]; - char monster[100]; - int mob_id; - int number = 0; - int x = 0, y = 0; - int count; - int i, j, k; - int mx, my, range; - - nullpo_retr(-1, sd); - memset(name, '\0', sizeof(name)); - memset(monster, '\0', sizeof(monster)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || - (sscanf(message, "\"%[^\"]\" %99s %d %d %d", name, monster, &number, &x, &y) < 2 && - sscanf(message, "%99s \"%[^\"]\" %d %d %d", monster, name, &number, &x, &y) < 2 && - sscanf(message, "%99s %d %99s %d %d", monster, &number, name, &x, &y) < 1)) { - clif_displaymessage(fd, msg_table[143]); // Give a monster name/id please. - return -1; - } - - // If monster identifier/name argument is a name - if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = mobdb_checkid(atoi(monster)); - - if (mob_id == 0) { - clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name. - return -1; - } - - if (mob_id == 1288) { - clif_displaymessage(fd, msg_table[83]); // Cannot spawn emperium. - return -1; - } - - if (number <= 0) - number = 1; - - if (strlen(name) < 1) - strcpy(name, "--ja--"); - - // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive - if (battle_config.atc_spawn_quantity_limit >= 1 && number > battle_config.atc_spawn_quantity_limit) - number = battle_config.atc_spawn_quantity_limit; - - if (battle_config.etc_log) - printf("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, x, y); - - count = 0; - range = (int)sqrt(number) / 2; - range = range * 2 + 5; // calculation of an odd number (+ 4 area around) - for (i = 0; i < number; i++) { - j = 0; - k = 0; - while(j++ < 8 && k == 0) { // try 8 times to spawn the monster (needed for close area) - if (x <= 0) - mx = sd->bl.x + (rand() % range - (range / 2)); - else - mx = x; - if (y <= 0) - my = sd->bl.y + (rand() % range - (range / 2)); - else - my = y; - k = mob_once_spawn((struct map_session_data*)sd, "this", mx, my, name, mob_id, 1, ""); - } - count += (k != 0) ? 1 : 0; - } - - if (count != 0) - if (number == count) - clif_displaymessage(fd, msg_table[39]); // All monster summoned! - else { - sprintf(atcmd_output, msg_table[240], count); // %d monster(s) summoned! - clif_displaymessage(fd, atcmd_output); - } - else { - clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name. - return -1; - } - - return 0; -} -// small monster spawning [Valaris] -int atcommand_monstersmall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) { - char name[100] = ""; - char monster[100] = ""; - int mob_id = 0; - int number = 0; - int x = 0; - int y = 0; - int count; - int i; - - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(fd, "Give a monster name/id please."); - return 0; - } - - if (sscanf(message, "\"%[^\"]\" %99s %d %d %d", name, monster, &number, &x, &y) < 2 && - sscanf(message, "%99s \"%[^\"]\" %d %d %d", monster, name, &number, &x, &y) < 2 && - sscanf(message, "%99s %d %99s %d %d", monster, &number, name, &x, &y) < 1) { - clif_displaymessage(fd, "Give a monster name/id please."); - return 0; - } - - // If monster identifier/name argument is a name - if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = atoi(monster); - - if (mob_id == 0) { - clif_displaymessage(fd, "Monster name hasn't been found."); - return 0; - } - - if (mob_id == 1288) { - clif_displaymessage(fd, "Cannot spawn emperium."); - return 0; - } - - if (mob_id > 2000) { - clif_displaymessage(fd, "Invalid monster ID"); // Invalid Monster ID. - return 0; - } - - if (number <= 0) - number = 1; - - if (strlen(name) < 1) - strcpy(name, "--ja--"); - - // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive - if (battle_config.atc_spawn_quantity_limit >= 1 && number > battle_config.atc_spawn_quantity_limit) - number = battle_config.atc_spawn_quantity_limit; - - count = 0; - for (i = 0; i < number; i++) { - int mx, my; - if (x <= 0) - mx = sd->bl.x + (rand() % 11 - 5); - else - mx = x; - if (y <= 0) - my = sd->bl.y + (rand() % 11 - 5); - else - my = y; - count += (mob_once_spawn((struct map_session_data*)sd, "this", mx, my, name, mob_id+2000, 1, "") != 0) ? 1 : 0; - } - - if (count != 0) - clif_displaymessage(fd, msg_table[39]); // Monster Summoned!! - else - clif_displaymessage(fd, msg_table[40]); // Invalid Monster ID. - - return 0; -} -// big monster spawning [Valaris] -int atcommand_monsterbig( - const int fd, struct map_session_data* sd, - const char* command, const char* message) { - char name[100] = ""; - char monster[100] = ""; - int mob_id = 0; - int number = 0; - int x = 0; - int y = 0; - int count; - int i; - - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(fd, "Give a monster name/id please."); - return 0; - } - - if (sscanf(message, "\"%[^\"]\" %99s %d %d %d", name, monster, &number, &x, &y) < 2 && - sscanf(message, "%99s \"%[^\"]\" %d %d %d", monster, name, &number, &x, &y) < 2 && - sscanf(message, "%99s %d %99s %d %d", monster, &number, name, &x, &y) < 1) { - clif_displaymessage(fd, "Give a monster name/id please."); - return 0; - } - - // If monster identifier/name argument is a name - if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = atoi(monster); - - if (mob_id == 0) { - clif_displaymessage(fd, "Monster name hasn't been found."); - return 0; - } - - if (mob_id == 1288) { - clif_displaymessage(fd, "Cannot spawn emperium."); - return 0; - } - - if (mob_id > 2000) { - clif_displaymessage(fd, "Invalid monster ID"); // Invalid Monster ID. - return 0; - } - - if (number <= 0) - number = 1; - - if (strlen(name) < 1) - strcpy(name, "--ja--"); - - // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive - if (battle_config.atc_spawn_quantity_limit >= 1 && number > battle_config.atc_spawn_quantity_limit) - number = battle_config.atc_spawn_quantity_limit; - - count = 0; - for (i = 0; i < number; i++) { - int mx, my; - if (x <= 0) - mx = sd->bl.x + (rand() % 11 - 5); - else - mx = x; - if (y <= 0) - my = sd->bl.y + (rand() % 11 - 5); - else - my = y; - count += (mob_once_spawn((struct map_session_data*)sd, "this", mx, my, name, mob_id+4000, 1, "") != 0) ? 1 : 0; - } - - if (count != 0) - clif_displaymessage(fd, msg_table[39]); // Monster Summoned!! - else - clif_displaymessage(fd, msg_table[40]); // Invalid Monster ID. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -void atcommand_killmonster_sub( - const int fd, struct map_session_data* sd, const char* message, - const int drop) -{ - int map_id; - char map_name[100]; - - if (!sd) return; - - memset(map_name, '\0', sizeof(map_name)); - - if (!message || !*message || sscanf(message, "%99s", map_name) < 1) - map_id = sd->bl.m; - else { - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - if ((map_id = map_mapname2mapid(map_name)) < 0) - map_id = sd->bl.m; - } - - map_foreachinarea(atkillmonster_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_MOB, drop); - - clif_displaymessage(fd, msg_table[165]); // All monsters killed! - - return; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_killmonster( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - if (!sd) return 0; - atcommand_killmonster_sub(fd, sd, message, 1); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_killmonster2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - if (!sd) return 0; - atcommand_killmonster_sub(fd, sd, message, 0); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_refine( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i, position = 0, refine = 0, current_position, final_refine; - int count; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d %d", &position, &refine) < 2) { - clif_displaymessage(fd, "Please, enter a position and a amount (usage: @refine <equip position> <+/- amount>)."); - return -1; - } - - if (refine < -10) - refine = -10; - else if (refine > 10) - refine = 10; - else if (refine == 0) - refine = 1; - - count = 0; - for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid && // 該当個所の装備を精錬する - (sd->status.inventory[i].equip & position || - (sd->status.inventory[i].equip && !position))) { - final_refine = sd->status.inventory[i].refine + refine; - if (final_refine > 10) - final_refine = 10; - else if (final_refine < 0) - final_refine = 0; - if (sd->status.inventory[i].refine != final_refine) { - sd->status.inventory[i].refine = final_refine; - current_position = sd->status.inventory[i].equip; - pc_unequipitem(sd, i, 3); - clif_refine(fd, sd, 0, i, sd->status.inventory[i].refine); - clif_delitem(sd, i, 1); - clif_additem(sd, i, 1, 0); - pc_equipitem(sd, i, current_position); - clif_misceffect((struct block_list*)&sd->bl, 3); - count++; - } - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[166]); // No item has been refined! - else if (count == 1) - clif_displaymessage(fd, msg_table[167]); // 1 item has been refined! - else { - sprintf(atcmd_output, msg_table[168], count); // %d items have been refined! - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_produce( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char item_name[100]; - int item_id, attribute = 0, star = 0; - int flag = 0; - struct item_data *item_data; - struct item tmp_item; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(item_name, '\0', sizeof(item_name)); - - if (!message || !*message || sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1) { - clif_displaymessage(fd, "Please, enter at least an item name/id (usage: @produce <equip name or equip ID> <element> <# of very's>)."); - return -1; - } - - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) - item_id = item_data->nameid; - - if (itemdb_exists(item_id) && - (item_id <= 500 || item_id > 1099) && - (item_id < 4001 || item_id > 4148) && - (item_id < 7001 || item_id > 10019) && - itemdb_isequip(item_id)) { - if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE) - attribute = ATTRIBUTE_NORMAL; - if (star < MIN_STAR || star > MAX_STAR) - star = 0; - memset(&tmp_item, 0, sizeof tmp_item); - tmp_item.nameid = item_id; - tmp_item.amount = 1; - tmp_item.identify = 1; - tmp_item.card[0] = 0x00ff; - tmp_item.card[1] = ((star * 5) << 8) + attribute; - *((unsigned long *)(&tmp_item.card[2])) = sd->char_id; - clif_produceeffect(sd, 0, item_id); // 製造エフェクトパケット - clif_misceffect(&sd->bl, 3); // 他人にも成功を通知 - if ((flag = pc_additem(sd, &tmp_item, 1))) - clif_additem(sd, 0, 0, flag); - } else { - if (battle_config.error_log) - printf("@produce NOT WEAPON [%d]\n", item_id); - if (item_id != 0 && itemdb_exists(item_id)) - sprintf(atcmd_output, msg_table[169], item_id, item_data->name); // This item (%d: '%s') is not an equipment. - else - sprintf(atcmd_output, msg_table[170]); // This item is not an equipment. - clif_displaymessage(fd, atcmd_output); - return -1; - } - - return 0; -} - -/*========================================== - * Sub-function to display actual memo points - *------------------------------------------ - */ -void atcommand_memo_sub(struct map_session_data* sd) { - int i; - - if (!sd) return; - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - clif_displaymessage(sd->fd, "Your actual memo positions are (except respawn point):"); - for (i = MIN_PORTAL_MEMO; i <= MAX_PORTAL_MEMO; i++) { - if (sd->status.memo_point[i].map[0]) - sprintf(atcmd_output, "%d - %s (%d,%d)", i, sd->status.memo_point[i].map, sd->status.memo_point[i].x, sd->status.memo_point[i].y); - else - sprintf(atcmd_output, msg_table[171], i); // %d - void - clif_displaymessage(sd->fd, atcmd_output); - } - - return; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_memo( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int position = 0; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d", &position) < 1) - atcommand_memo_sub(sd); - else { - if (position >= MIN_PORTAL_MEMO && position <= MAX_PORTAL_MEMO) { - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[253]); - return -1; - } - if (sd->status.memo_point[position].map[0]) { - sprintf(atcmd_output, msg_table[172], position, sd->status.memo_point[position].map, sd->status.memo_point[position].x, sd->status.memo_point[position].y); // You replace previous memo position %d - %s (%d,%d). - clif_displaymessage(fd, atcmd_output); - } - memcpy(sd->status.memo_point[position].map, map[sd->bl.m].name, 24); - sd->status.memo_point[position].x = sd->bl.x; - sd->status.memo_point[position].y = sd->bl.y; - clif_skill_memo(sd, 0); - if (pc_checkskill(sd, AL_WARP) <= (position + 1)) - clif_displaymessage(fd, msg_table[173]); // Note: you don't have the 'Warp' skill level to use it. - atcommand_memo_sub(sd); - } else { - sprintf(atcmd_output, "Please, enter a valid position (usage: @memo <memo_position:%d-%d>).", MIN_PORTAL_MEMO, MAX_PORTAL_MEMO); - clif_displaymessage(fd, atcmd_output); - atcommand_memo_sub(sd); - return -1; - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_gat( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int y; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - for (y = 2; y >= -2; y--) { - sprintf(atcmd_output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X", - map[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y, - map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE)); - - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_packet( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int x = 0, y = 0; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %d", &x, &y) < 2) { - clif_displaymessage(fd, "Please, enter a status type/flag (usage: @packet <status type> <flag>)."); - return -1; - } - - clif_status_change(&sd->bl, x, y); - - return 0; -} - -/*========================================== - * @stpoint (Rewritten by [Yor]) - *------------------------------------------ - */ -int atcommand_statuspoint( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int point, new_status_point; - - if (!message || !*message || (point = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a number (usage: @stpoint <number of points>)."); - return -1; - } - - new_status_point = (int)sd->status.status_point + point; - if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow - new_status_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_status_point < 0)) // fix negativ overflow - new_status_point = 0; - - if (new_status_point != (int)sd->status.status_point) { - sd->status.status_point = (short)new_status_point; - clif_updatestatus(sd, SP_STATUSPOINT); - clif_displaymessage(fd, msg_table[174]); // Number of status points changed! - } else { - if (point < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - - return 0; -} - -/*========================================== - * @skpoint (Rewritten by [Yor]) - *------------------------------------------ - */ -int atcommand_skillpoint( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int point, new_skill_point; - nullpo_retr(-1, sd); - - if (!message || !*message || (point = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a number (usage: @skpoint <number of points>)."); - return -1; - } - - new_skill_point = (int)sd->status.skill_point + point; - if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow - new_skill_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_skill_point < 0)) // fix negativ overflow - new_skill_point = 0; - - if (new_skill_point != (int)sd->status.skill_point) { - sd->status.skill_point = (short)new_skill_point; - clif_updatestatus(sd, SP_SKILLPOINT); - clif_displaymessage(fd, msg_table[175]); // Number of skill points changed! - } else { - if (point < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - - return 0; -} - -/*========================================== - * @zeny (Rewritten by [Yor]) - *------------------------------------------ - */ -int atcommand_zeny( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int zeny, new_zeny; - nullpo_retr(-1, sd); - - if (!message || !*message || (zeny = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter an amount (usage: @zeny <amount>)."); - return -1; - } - - new_zeny = sd->status.zeny + zeny; - if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow - new_zeny = MAX_ZENY; - else if (zeny < 0 && (zeny < -MAX_ZENY || new_zeny < 0)) // fix negativ overflow - new_zeny = 0; - - if (new_zeny != sd->status.zeny) { - sd->status.zeny = new_zeny; - clif_updatestatus(sd, SP_ZENY); - clif_displaymessage(fd, msg_table[176]); // Number of zenys changed! - } else { - if (zeny < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_param( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i, index, value = 0, new_value; - const char* param[] = { "@str", "@agi", "@vit", "@int", "@dex", "@luk", NULL }; - short* status[] = { - &sd->status.str, &sd->status.agi, &sd->status.vit, - &sd->status.int_, &sd->status.dex, &sd->status.luk - }; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) { - sprintf(atcmd_output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustement>)."); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - index = -1; - for (i = 0; param[i] != NULL; i++) { - if (strcmpi(command, param[i]) == 0) { - index = i; - break; - } - } - if (index < 0 || index > MAX_STATUS_TYPE) { // normaly impossible... - sprintf(atcmd_output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustement>)."); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - new_value = (int)*status[index] + value; - if (value > 0 && ((unsigned int)value > battle_config.max_parameter || (unsigned int)new_value > battle_config.max_parameter)) // fix positiv overflow - new_value = battle_config.max_parameter; - else if (value < 0 && (value < -(int)battle_config.max_parameter || new_value < 1)) // fix negativ overflow - new_value = 1; - - if (new_value != (int)*status[index]) { - *status[index] = new_value; - clif_updatestatus(sd, SP_STR + index); - clif_updatestatus(sd, SP_USTR + index); - status_calc_pc(sd, 0); - clif_displaymessage(fd, msg_table[42]); // Stat changed. - } else { - if (value < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -//** Stat all by fritz (rewritten by [Yor]) -int atcommand_stat_all( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int index, count, value = 0, new_value; - short* status[] = { - &sd->status.str, &sd->status.agi, &sd->status.vit, - &sd->status.int_, &sd->status.dex, &sd->status.luk - }; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) - value = battle_config.max_parameter; - - count = 0; - for (index = 0; index < (int)(sizeof(status) / sizeof(status[0])); index++) { - - new_value = (int)*status[index] + value; - if (value > 0 && ((unsigned int)value > battle_config.max_parameter || (unsigned int)new_value > battle_config.max_parameter)) // fix positiv overflow - new_value = battle_config.max_parameter; - else if (value < 0 && (value < -(int)battle_config.max_parameter || new_value < 1)) // fix negativ overflow - new_value = 1; - - if (new_value != (int)*status[index]) { - *status[index] = new_value; - clif_updatestatus(sd, SP_STR + index); - clif_updatestatus(sd, SP_USTR + index); - status_calc_pc(sd, 0); - count++; - } - } - - if (count > 0) // if at least 1 stat modified - clif_displaymessage(fd, msg_table[84]); // All stats changed! - else { - if (value < 0) - clif_displaymessage(fd, msg_table[177]); // Impossible to decrease a stat. - else - clif_displaymessage(fd, msg_table[178]); // Impossible to increase a stat. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_guildlevelup( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int level = 0; - short added_level; - struct guild *guild_info; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) { - clif_displaymessage(fd, "Please, enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>)."); - return -1; - } - - if (sd->status.guild_id <= 0 || (guild_info = guild_search(sd->status.guild_id)) == NULL) { - clif_displaymessage(fd, msg_table[43]); // You're not in a guild. - return -1; - } - if (strcmp(sd->status.name, guild_info->master) != 0) { - clif_displaymessage(fd, msg_table[44]); // You're not the master of your guild. - return -1; - } - - added_level = (short)level; - if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow - added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv; - else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow - added_level = 1 - guild_info->guild_lv; - - if (added_level != 0) { - intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, 2); - clif_displaymessage(fd, msg_table[179]); // Guild level changed. - } else { - clif_displaymessage(fd, msg_table[45]); // Guild level change failed. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_makeegg( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct item_data *item_data; - int id, pet_id; - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a monter/egg name/id (usage: @makeegg <pet_id>)."); - return -1; - } - - if ((item_data = itemdb_searchname(message)) != NULL) // for egg name - id = item_data->nameid; - else if ((id = mobdb_searchname(message)) == 0) // for monster name - id = atoi(message); - - pet_id = search_petDB_index(id, PET_CLASS); - if (pet_id < 0) - pet_id = search_petDB_index(id, PET_EGG); - if (pet_id >= 0) { - sd->catch_target_class = pet_db[pet_id].class_; - intif_create_pet( - sd->status.account_id, sd->status.char_id, - (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv, - (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate, - 100, 0, 1, pet_db[pet_id].jname); - } else { - clif_displaymessage(fd, msg_table[180]); // The monter/egg name/id doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_hatch( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (sd->status.pet_id <= 0) - clif_sendegg(sd); - else { - clif_displaymessage(fd, msg_table[181]); // You already have a pet. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_petfriendly( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int friendly; - int t; - nullpo_retr(-1, sd); - - if (!message || !*message || (friendly = atoi(message)) < 0) { - clif_displaymessage(fd, "Please, enter a valid value (usage: @petfriendly <0-1000>)."); - return -1; - } - - if (sd->status.pet_id > 0 && sd->pd) { - if (friendly >= 0 && friendly <= 1000) { - if (friendly != sd->pet.intimate) { - t = sd->pet.intimate; - sd->pet.intimate = friendly; - clif_send_petstatus(sd); - if (battle_config.pet_status_support) { - if ((sd->pet.intimate > 0 && t <= 0) || - (sd->pet.intimate <= 0 && t > 0)) { - if (sd->bl.prev != NULL) - status_calc_pc(sd, 0); - else - status_calc_pc(sd, 2); - } - } - clif_displaymessage(fd, msg_table[182]); // Pet friendly value changed! - } else { - clif_displaymessage(fd, msg_table[183]); // Pet friendly is already the good value. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[184]); // Sorry, but you have no pet. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_pethungry( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int hungry; - nullpo_retr(-1, sd); - - if (!message || !*message || (hungry = atoi(message)) < 0) { - clif_displaymessage(fd, "Please, enter a valid number (usage: @pethungry <0-100>)."); - return -1; - } - - if (sd->status.pet_id > 0 && sd->pd) { - if (hungry >= 0 && hungry <= 100) { - if (hungry != sd->pet.hungry) { - sd->pet.hungry = hungry; - clif_send_petstatus(sd); - clif_displaymessage(fd, msg_table[185]); // Pet hungry value changed! - } else { - clif_displaymessage(fd, msg_table[186]); // Pet hungry is already the good value. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[184]); // Sorry, but you have no pet. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_petrename( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (sd->status.pet_id > 0 && sd->pd) { - if (sd->pet.rename_flag != 0) { - sd->pet.rename_flag = 0; - intif_save_petdata(sd->status.account_id, &sd->pet); - clif_send_petstatus(sd); - clif_displaymessage(fd, msg_table[187]); // You can now rename your pet. - } else { - clif_displaymessage(fd, msg_table[188]); // You can already rename your pet. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[184]); // Sorry, but you have no pet. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int -atcommand_recall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @recall <char name>)."); - return -1; - } - - memset(atcmd_player_name, '\0', sizeof atcmd_player_name); - if(sscanf(message, "%99[^\n]", atcmd_player_name) < 1) - return -1; - if(strncmp(sd->status.name,atcmd_player_name,24)==0) - return -1; - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map."); - return -1; - } - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp this player from its actual map."); - return -1; - } - pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2); - sprintf(atcmd_output, msg_table[46], atcmd_player_name); // %s recalled! - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_revive( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @revive <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isdead(pl_sd)) { - pl_sd->status.hp = pl_sd->status.max_hp; - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - pc_setstand(pl_sd); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(pl_sd, battle_config.pc_invincible_time); - clif_updatestatus(pl_sd, SP_HP); - clif_updatestatus(pl_sd, SP_SP); - clif_resurrection(&pl_sd->bl, 1); - clif_displaymessage(fd, msg_table[51]); // Character revived. - return 0; - } - return -1; - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * charchangesex command (usage: charchangesex <player_name>) - *------------------------------------------ - */ -int atcommand_char_change_sex( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charchangesex <name>)."); - return -1; - } - - // check player name - if (strlen(atcmd_player_name) < 4) { - clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters. - return -1; - } else if (strlen(atcmd_player_name) > 23) { - clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum. - return -1; - } else { - chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex - clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it. - } - - return 0; -} - -/*========================================== - * charblock command (usage: charblock <player_name>) - * This command do a definitiv ban on a player - *------------------------------------------ - */ -int atcommand_char_block( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charblock/@block <name>)."); - return -1; - } - - // check player name - if (strlen(atcmd_player_name) < 4) { - clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters. - return -1; - } else if (strlen(atcmd_player_name) > 23) { - clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum. - return -1; - } else { - chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block - clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it. - } - - return 0; -} - -/*========================================== - * charban command (usage: charban <time> <player_name>) - * This command do a limited ban on a player - * Time is done as follows: - * Adjustment value (-1, 1, +1, etc...) - * Modified element: - * a or y: year - * m: month - * j or d: day - * h: hour - * mn: minute - * s: second - * <example> @ban +1m-2mn1s-6y test_player - * this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time. - *------------------------------------------ - */ -int atcommand_char_ban( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char * modif_p; - int year, month, day, hour, minute, second, value; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%s %99[^\n]", atcmd_output, atcmd_player_name) < 2) { - clif_displaymessage(fd, "Please, enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <name>)."); - return -1; - } - - atcmd_output[sizeof(atcmd_output)-1] = '\0'; - - modif_p = atcmd_output; - year = month = day = hour = minute = second = 0; - while (modif_p[0] != '\0') { - value = atoi(modif_p); - if (value == 0) - modif_p++; - else { - if (modif_p[0] == '-' || modif_p[0] == '+') - modif_p++; - while (modif_p[0] >= '0' && modif_p[0] <= '9') - modif_p++; - if (modif_p[0] == 's') { - second = value; - modif_p++; - } else if (modif_p[0] == 'm' && modif_p[1] == 'n') { - minute = value; - modif_p = modif_p + 2; - } else if (modif_p[0] == 'h') { - hour = value; - modif_p++; - } else if (modif_p[0] == 'd' || modif_p[0] == 'j') { - day = value; - modif_p++; - } else if (modif_p[0] == 'm') { - month = value; - modif_p++; - } else if (modif_p[0] == 'y' || modif_p[0] == 'a') { - year = value; - modif_p++; - } else if (modif_p[0] != '\0') { - modif_p++; - } - } - } - if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) { - clif_displaymessage(fd, msg_table[85]); // Invalid time for ban command. - return -1; - } - - // check player name - if (strlen(atcmd_player_name) < 4) { - clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters. - return -1; - } else if (strlen(atcmd_player_name) > 23) { - clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum. - return -1; - } else { - chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban - clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it. - } - - return 0; -} - -/*========================================== - * charunblock command (usage: charunblock <player_name>) - *------------------------------------------ - */ -int atcommand_char_unblock( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charunblock <player_name>)."); - return -1; - } - - // check player name - if (strlen(atcmd_player_name) < 4) { - clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters. - return -1; - } else if (strlen(atcmd_player_name) > 23) { - clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum. - return -1; - } else { - // send answer to login server via char-server - chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock - clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it. - } - - return 0; -} - -/*========================================== - * charunban command (usage: charunban <player_name>) - *------------------------------------------ - */ -int atcommand_char_unban( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charunban <player_name>)."); - return -1; - } - - // check player name - if (strlen(atcmd_player_name) < 4) { - clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters. - return -1; - } else if (strlen(atcmd_player_name) > 23) { - clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum. - return -1; - } else { - // send answer to login server via char-server - chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban - clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it. - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_night( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - if (night_flag != 1) { - night_flag = 1; // 0=day, 1=night [Yor] - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && !map[sd->bl.m].flag.indoors) { - //pl_sd->opt2 |= STATE_BLIND; - //clif_changeoption(&pl_sd->bl); - if (battle_config.night_darkness_level > 0) - clif_specialeffect(&pl_sd->bl, 474 + battle_config.night_darkness_level, 0); - else { - //clif_specialeffect(&pl_sd->bl, 483, 0); // default darkness level - pl_sd->opt2 |= STATE_BLIND; - clif_changeoption(&pl_sd->bl); - } - clif_displaymessage(pl_sd->fd, msg_table[59]); // Night has fallen. - } - } - } else { - clif_displaymessage(fd, msg_table[89]); // Sorry, it's already the night. Impossible to execute the command. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_day( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - if (night_flag != 0) { - night_flag = 0; // 0=day, 1=night [Yor] - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - if (battle_config.night_darkness_level > 0) - clif_refresh (pl_sd); - else { - pl_sd->opt2 &= ~STATE_BLIND; - clif_changeoption(&pl_sd->bl); - } - clif_displaymessage(pl_sd->fd, msg_table[60]); // Day has arrived. - } - } - } else { - clif_displaymessage(fd, msg_table[90]); // Sorry, it's already the day. Impossible to execute the command. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_doom( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - clif_specialeffect(&sd->bl,450,2); - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && i != fd && - pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can doom only lower or same gm level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(pl_sd->fd, msg_table[61]); // The holy messenger has given judgement. - } - } - clif_displaymessage(fd, msg_table[62]); // Judgement was made. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_doommap( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - clif_specialeffect(&sd->bl,450,3); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && i != fd && sd->bl.m == pl_sd->bl.m && - pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can doom only lower or same gm level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); -// clif_specialeffect(&pl_sd->bl,450,1); - clif_displaymessage(pl_sd->fd, msg_table[61]); // The holy messenger has given judgement. - } - } - clif_displaymessage(fd, msg_table[62]); // Judgement was made. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static void atcommand_raise_sub(struct map_session_data* sd) -{ - if (sd && sd->state.auth && pc_isdead(sd)) { - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - sd->status.hp = sd->status.max_hp; - sd->status.sp = sd->status.max_sp; - pc_setstand(sd); - clif_updatestatus(sd, SP_HP); - clif_updatestatus(sd, SP_SP); - clif_resurrection(&sd->bl, 1); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - clif_displaymessage(sd->fd, msg_table[63]); // Mercy has been shown. - } -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_raise( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - nullpo_retr(-1, sd); - - for (i = 0; i < fd_max; i++) { - if (session[i]) - atcommand_raise_sub((struct map_session_data *) session[i]->session_data); - } - clif_displaymessage(fd, msg_table[64]); // Mercy has been granted. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_raisemap( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - - nullpo_retr(-1, sd); - - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && sd->bl.m == pl_sd->bl.m) - atcommand_raise_sub(pl_sd); - } - clif_displaymessage(fd, msg_table[64]); // Mercy has been granted. - - return 0; -} - -/*========================================== - * atcommand_character_baselevel @charbaselvlで対象キャラのレベルを上げる - *------------------------------------------ -*/ -int atcommand_character_baselevel( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int level = 0, i; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, atcmd_player_name) < 2 || level == 0) { - clif_displaymessage(fd, "Please, enter a level adjustement and a player name (usage: @charbaselvl <#> <nickname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change base level only lower or same gm level - - if (level > 0) { - if (pl_sd->status.base_level == battle_config.maximum_level) { // check for max level by Valaris - clif_displaymessage(fd, msg_table[91]); // Character's base level can't go any higher. - return 0; - } // End Addition - if ((unsigned int)level > battle_config.maximum_level || (unsigned int)level > (battle_config.maximum_level - pl_sd->status.base_level)) // fix positiv overflow - level = battle_config.maximum_level - pl_sd->status.base_level; - for (i = 1; i <= level; i++) - pl_sd->status.status_point += (pl_sd->status.base_level + i + 14) / 5; - pl_sd->status.base_level += level; - clif_updatestatus(pl_sd, SP_BASELEVEL); - clif_updatestatus(pl_sd, SP_NEXTBASEEXP); - clif_updatestatus(pl_sd, SP_STATUSPOINT); - status_calc_pc(pl_sd, 0); - pc_heal(pl_sd, pl_sd->status.max_hp, pl_sd->status.max_sp); - clif_misceffect(&pl_sd->bl, 0); - clif_displaymessage(fd, msg_table[65]); // Character's base level raised. - } else { - if (pl_sd->status.base_level == 1) { - clif_displaymessage(fd, msg_table[193]); // Character's base level can't go any lower. - return -1; - } - if (level < -(int)battle_config.maximum_level || level < (1 - (int)pl_sd->status.base_level)) // fix negativ overflow - level = 1 - pl_sd->status.base_level; - if (pl_sd->status.status_point > 0) { - for (i = 0; i > level; i--) - pl_sd->status.status_point -= (pl_sd->status.base_level + i + 14) / 5; - if (pl_sd->status.status_point < 0) - pl_sd->status.status_point = 0; - clif_updatestatus(pl_sd, SP_STATUSPOINT); - } // to add: remove status points from stats - pl_sd->status.base_level += level; - clif_updatestatus(pl_sd, SP_BASELEVEL); - clif_updatestatus(pl_sd, SP_NEXTBASEEXP); - status_calc_pc(pl_sd, 0); - clif_displaymessage(fd, msg_table[66]); // Character's base level lowered. - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; //正常終了 -} - -/*========================================== - * atcommand_character_joblevel @charjoblvlで対象キャラのJobレベルを上げる - *------------------------------------------ - */ -int atcommand_character_joblevel( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - unsigned int max_level = 50; - int level = 0; - //転生や養子の場合の元の職業を算出する - struct pc_base_job pl_s_class; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, atcmd_player_name) < 2 || level == 0) { - clif_displaymessage(fd, "Please, enter a level adjustement and a player name (usage: @charjlvl <#> <nickname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - pl_s_class = pc_calc_base_job(pl_sd->status.class_); - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job level only lower or same gm level - if (pl_s_class.job == 0) - max_level -= 40; - // super novices can go up to 99 [celest] - else if (pl_s_class.job == 23) - max_level += 49; - else if (pl_sd->status.class_ > 4007 && pl_sd->status.class_ < 4023) - max_level += 20; - - if (level > 0) { - if (pl_sd->status.job_level == max_level) { - clif_displaymessage(fd, msg_table[67]); // Character's job level can't go any higher. - return -1; - } - if (pl_sd->status.job_level + level > max_level) - level = max_level - pl_sd->status.job_level; - pl_sd->status.job_level += level; - clif_updatestatus(pl_sd, SP_JOBLEVEL); - clif_updatestatus(pl_sd, SP_NEXTJOBEXP); - pl_sd->status.skill_point += level; - clif_updatestatus(pl_sd, SP_SKILLPOINT); - status_calc_pc(pl_sd, 0); - clif_misceffect(&pl_sd->bl, 1); - clif_displaymessage(fd, msg_table[68]); // character's job level raised. - } else { - if (pl_sd->status.job_level == 1) { - clif_displaymessage(fd, msg_table[194]); // Character's job level can't go any lower. - return -1; - } - if (pl_sd->status.job_level + level < 1) - level = 1 - pl_sd->status.job_level; - pl_sd->status.job_level += level; - clif_updatestatus(pl_sd, SP_JOBLEVEL); - clif_updatestatus(pl_sd, SP_NEXTJOBEXP); - if (pl_sd->status.skill_point > 0) { - pl_sd->status.skill_point += level; - if (pl_sd->status.skill_point < 0) - pl_sd->status.skill_point = 0; - clif_updatestatus(pl_sd, SP_SKILLPOINT); - } // to add: remove status points from skills - status_calc_pc(pl_sd, 0); - clif_displaymessage(fd, msg_table[69]); // Character's job level lowered. - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_kick( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @kick <charname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level - clif_GM_kick(sd, pl_sd, 1); - else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_kickall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && - pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kick only lower or same gm level - if (sd->status.account_id != pl_sd->status.account_id) - clif_GM_kick(sd, pl_sd, 0); - } - } - - clif_displaymessage(fd, msg_table[195]); // All players have been kicked! - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_allskill( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - pc_allskillup(sd); // all skills - sd->status.skill_point = 0; // 0 skill points - clif_updatestatus(sd, SP_SKILLPOINT); // update - clif_displaymessage(fd, msg_table[76]); // You have received all skills. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_questskill( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int skill_id; - nullpo_retr(-1, sd); - - if (!message || !*message || (skill_id = atoi(message)) < 0) { - clif_displaymessage(fd, "Please, enter a quest skill number (usage: @questskill <#:0+>)."); - return -1; - } - - if (skill_id >= 0 && skill_id < MAX_SKILL_DB) { - if (skill_get_inf2(skill_id) & 0x01) { - if (pc_checkskill(sd, skill_id) == 0) { - pc_skill(sd, skill_id, 1, 0); - clif_displaymessage(fd, msg_table[70]); // You have learned the skill. - } else { - clif_displaymessage(fd, msg_table[196]); // You already have this quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[197]); // This skill number doesn't exist or isn't a quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[198]); // This skill number doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_charquestskill( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int skill_id = 0; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill_id, atcmd_player_name) < 2 || skill_id < 0) { - clif_displaymessage(fd, "Please, enter a quest skill number and a player name (usage: @charquestskill <#:0+> <char_name>)."); - return -1; - } - - if (skill_id >= 0 && skill_id < MAX_SKILL_DB) { - if (skill_get_inf2(skill_id) & 0x01) { - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_checkskill(pl_sd, skill_id) == 0) { - pc_skill(pl_sd, skill_id, 1, 0); - clif_displaymessage(fd, msg_table[199]); // This player has learned the skill. - } else { - clif_displaymessage(fd, msg_table[200]); // This player already has this quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[197]); // This skill number doesn't exist or isn't a quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[198]); // This skill number doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_lostskill( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int skill_id; - nullpo_retr(-1, sd); - - if (!message || !*message || (skill_id = atoi(message)) < 0) { - clif_displaymessage(fd, "Please, enter a quest skill number (usage: @lostskill <#:0+>)."); - return -1; - } - - if (skill_id >= 0 && skill_id < MAX_SKILL) { - if (skill_get_inf2(skill_id) & 0x01) { - if (pc_checkskill(sd, skill_id) > 0) { - sd->status.skill[skill_id].lv = 0; - sd->status.skill[skill_id].flag = 0; - clif_skillinfoblock(sd); - clif_displaymessage(fd, msg_table[71]); // You have forgotten the skill. - } else { - clif_displaymessage(fd, msg_table[201]); // You don't have this quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[197]); // This skill number doesn't exist or isn't a quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[198]); // This skill number doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_charlostskill( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int skill_id = 0; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill_id, atcmd_player_name) < 2 || skill_id < 0) { - clif_displaymessage(fd, "Please, enter a quest skill number and a player name (usage: @charlostskill <#:0+> <char_name>)."); - return -1; - } - - if (skill_id >= 0 && skill_id < MAX_SKILL) { - if (skill_get_inf2(skill_id) & 0x01) { - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_checkskill(pl_sd, skill_id) > 0) { - pl_sd->status.skill[skill_id].lv = 0; - pl_sd->status.skill[skill_id].flag = 0; - clif_skillinfoblock(pl_sd); - clif_displaymessage(fd, msg_table[202]); // This player has forgotten the skill. - } else { - clif_displaymessage(fd, msg_table[203]); // This player doesn't have this quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[197]); // This skill number doesn't exist or isn't a quest skill. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[198]); // This skill number doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_spiritball( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int number; - nullpo_retr(-1, sd); - - if (!message || !*message || (number = atoi(message)) < 0) { - clif_displaymessage(fd, "Please, enter a spirit ball number (usage: @spiritball <number: 0-1000>)."); - return -1; - } - - // set max number to avoid server/client crash (500 create big balls of several balls: no visial difference with more) - if (number > 500) - number = 500; - - if (number >= 0 && number <= 0x7FFF) { - if (sd->spiritball != number || number > 499) { - if (sd->spiritball > 0) - pc_delspiritball(sd, sd->spiritball, 1); - sd->spiritball = number; - clif_spiritball(sd); - // no message, player can look the difference - if (number > 1000) - clif_displaymessage(fd, msg_table[204]); // WARNING: more than 1000 spiritballs can CRASH your server and/or client! - } else { - clif_displaymessage(fd, msg_table[205]); // You already have this number of spiritballs. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_party( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char party[100]; - nullpo_retr(-1, sd); - - memset(party, '\0', sizeof(party)); - - if (!message || !*message || sscanf(message, "%99[^\n]", party) < 1) { - clif_displaymessage(fd, "Please, enter a party name (usage: @party <party_name>)."); - return -1; - } - - party_create(sd, party, 0, 0); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_guild( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char guild[100]; - int prev; - nullpo_retr(-1, sd); - - memset(guild, '\0', sizeof(guild)); - - if (!message || !*message || sscanf(message, "%99[^\n]", guild) < 1) { - clif_displaymessage(fd, "Please, enter a guild name (usage: @guild <guild_name>)."); - return -1; - } - - prev = battle_config.guild_emperium_check; - battle_config.guild_emperium_check = 0; - guild_create(sd, guild); - battle_config.guild_emperium_check = prev; - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_agitstart( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (agit_flag == 1) { - clif_displaymessage(fd, msg_table[73]); // Already it has started siege warfare. - return -1; - } - - agit_flag = 1; - guild_agit_start(); - clif_displaymessage(fd, msg_table[72]); // Guild siege warfare start! - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_agitend( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (agit_flag == 0) { - clif_displaymessage(fd, msg_table[75]); // Siege warfare hasn't started yet. - return -1; - } - - agit_flag = 0; - guild_agit_end(); - clif_displaymessage(fd, msg_table[74]); // Guild siege warfare end! - - return 0; -} - -/*========================================== - * @mapexitでマップサーバーを終了させる - *------------------------------------------ - */ -int atcommand_mapexit( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - if (sd->status.account_id != pl_sd->status.account_id) - clif_GM_kick(sd, pl_sd, 0); - } - } - clif_GM_kick(sd, sd, 0); - - flush_fifos(); - - runflag = 0; - - return 0; -} - -/*========================================== - * idsearch <part_of_name>: revrited by [Yor] - *------------------------------------------ - */ -int atcommand_idsearch( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char item_name[100]; - unsigned int i, match; - struct item_data *item; - nullpo_retr(-1, sd); - - memset(item_name, '\0', sizeof(item_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99s", item_name) < 0) { - clif_displaymessage(fd, "Please, enter a part of item name (usage: @idsearch <part_of_item_name>)."); - return -1; - } - - sprintf(atcmd_output, msg_table[77], item_name); // The reference result of '%s' (name: id): - clif_displaymessage(fd, atcmd_output); - match = 0; - for(i = 0; i < 20000; i++) { - if ((item = itemdb_exists(i)) != NULL && strstr(item->jname, item_name) != NULL) { - match++; - sprintf(atcmd_output, msg_table[78], item->jname, item->nameid); // %s: %d - clif_displaymessage(fd, atcmd_output); - } - } - sprintf(atcmd_output, msg_table[79], match); // It is %d affair above. - clif_displaymessage(fd, atcmd_output); - - return 0; -} - -/*========================================== - * Character Skill Reset - *------------------------------------------ - */ -int atcommand_charskreset( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charskreset <charname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset skill points only lower or same gm level - pc_resetskill(pl_sd); - sprintf(atcmd_output, msg_table[206], atcmd_player_name); // '%s' skill points reseted! - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * Character Stat Reset - *------------------------------------------ - */ -int atcommand_charstreset( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charstreset <charname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset stats points only lower or same gm level - pc_resetstate(pl_sd); - sprintf(atcmd_output, msg_table[207], atcmd_player_name); // '%s' stats points reseted! - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * Character Model by chbrules - *------------------------------------------ - */ -int atcommand_charmodel( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int hair_style = 0, hair_color = 0, cloth_color = 0; - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%d %d %d %99[^\n]", &hair_style, &hair_color, &cloth_color, atcmd_player_name) < 4 || hair_style < 0 || hair_color < 0 || cloth_color < 0) { - sprintf(atcmd_output, "Please, enter a valid model and a player name (usage: @charmodel <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d> <name>).", - MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); - clif_displaymessage(fd, atcmd_output); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE && - hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR && - cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) { - - if (cloth_color != 0 && - pl_sd->status.sex == 1 && - (pl_sd->status.class_ == 12 || pl_sd->status.class_ == 17)) { - clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class. - return -1; - } else { - pc_changelook(pl_sd, LOOK_HAIR, hair_style); - pc_changelook(pl_sd, LOOK_HAIR_COLOR, hair_color); - pc_changelook(pl_sd, LOOK_CLOTHES_COLOR, cloth_color); - clif_displaymessage(fd, msg_table[36]); // Appearence changed. - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * Character Skill Point (Rewritten by [Yor]) - *------------------------------------------ - */ -int atcommand_charskpoint( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int new_skill_point; - int point = 0; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &point, atcmd_player_name) < 2 || point == 0) { - clif_displaymessage(fd, "Please, enter a number and a player name (usage: @charskpoint <amount> <name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - new_skill_point = (int)pl_sd->status.skill_point + point; - if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow - new_skill_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_skill_point < 0)) // fix negativ overflow - new_skill_point = 0; - if (new_skill_point != (int)pl_sd->status.skill_point) { - pl_sd->status.skill_point = new_skill_point; - clif_updatestatus(pl_sd, SP_SKILLPOINT); - clif_displaymessage(fd, msg_table[209]); // Character's number of skill points changed! - } else { - if (point < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * Character Status Point (rewritten by [Yor]) - *------------------------------------------ - */ -int atcommand_charstpoint( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int new_status_point; - int point = 0; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &point, atcmd_player_name) < 2 || point == 0) { - clif_displaymessage(fd, "Please, enter a number and a player name (usage: @charstpoint <amount> <name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - new_status_point = (int)pl_sd->status.status_point + point; - if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow - new_status_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_status_point < 0)) // fix negativ overflow - new_status_point = 0; - if (new_status_point != (int)pl_sd->status.status_point) { - pl_sd->status.status_point = new_status_point; - clif_updatestatus(pl_sd, SP_STATUSPOINT); - clif_displaymessage(fd, msg_table[210]); // Character's number of status points changed! - } else { - if (point < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * Recall All Characters Online To Your Location - *------------------------------------------ - */ -int atcommand_recallall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - int count; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map."); - return -1; - } - - count = 0; - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && sd->status.account_id != pl_sd->status.account_id && - pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) - count++; - else - pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2); - } - } - - clif_displaymessage(fd, msg_table[92]); // All characters recalled! - if (count) { - sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count); - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * Recall online characters of a guild to your location - *------------------------------------------ - */ -int atcommand_guildrecall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - char guild_name[100]; - struct guild *g; - int count; - nullpo_retr(-1, sd); - - memset(guild_name, '\0', sizeof(guild_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", guild_name) < 1) { - clif_displaymessage(fd, "Please, enter a guild name/id (usage: @guildrecall <guild_name/id>)."); - return -1; - } - - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map."); - return -1; - } - - if ((g = guild_searchname(guild_name)) != NULL || // name first to avoid error when name begin with a number - (g = guild_search(atoi(message))) != NULL) { - count = 0; - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && - sd->status.account_id != pl_sd->status.account_id && - pl_sd->status.guild_id == g->guild_id) { - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) - count++; - else - pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2); - } - } - sprintf(atcmd_output, msg_table[93], g->name); // All online characters of the %s guild are near you. - clif_displaymessage(fd, atcmd_output); - if (count) { - sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count); - clif_displaymessage(fd, atcmd_output); - } - } else { - clif_displaymessage(fd, msg_table[94]); // Incorrect name/ID, or no one from the guild is online. - return -1; - } - - return 0; -} - -/*========================================== - * Recall online characters of a party to your location - *------------------------------------------ - */ -int atcommand_partyrecall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - struct map_session_data *pl_sd; - char party_name[100]; - struct party *p; - int count; - nullpo_retr(-1, sd); - - memset(party_name, '\0', sizeof(party_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", party_name) < 1) { - clif_displaymessage(fd, "Please, enter a party name/id (usage: @partyrecall <party_name/id>)."); - return -1; - } - - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map."); - return -1; - } - - if ((p = party_searchname(party_name)) != NULL || // name first to avoid error when name begin with a number - (p = party_search(atoi(message))) != NULL) { - count = 0; - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && - sd->status.account_id != pl_sd->status.account_id && - pl_sd->status.party_id == p->party_id) { - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) - count++; - else - pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2); - } - } - sprintf(atcmd_output, msg_table[95], p->name); // All online characters of the %s party are near you. - clif_displaymessage(fd, atcmd_output); - if (count) { - sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count); - clif_displaymessage(fd, atcmd_output); - } - } else { - clif_displaymessage(fd, msg_table[96]); // Incorrect name or ID, or no one from the party is online. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_reloaditemdb( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - itemdb_reload(); - clif_displaymessage(fd, msg_table[97]); // Item database reloaded. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_reloadmobdb( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - mob_reload(); - read_petdb(); - clif_displaymessage(fd, msg_table[98]); // Monster database reloaded. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_reloadskilldb( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - skill_reload(); - clif_displaymessage(fd, msg_table[99]); // Skill database reloaded. - - return 0; -} - -/*========================================== - * @reloadatcommand - * atcommand_athena.conf のリロード - *------------------------------------------ - */ -int -atcommand_reloadatcommand( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - atcommand_config_read(ATCOMMAND_CONF_FILENAME); - clif_displaymessage(fd, msg_table[254]); - return 0; -} -/*========================================== - * @reloadbattleconf - * battle_athena.conf のリロード - *------------------------------------------ - */ -int -atcommand_reloadbattleconf( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - battle_config_read(BATTLE_CONF_FILENAME); - clif_displaymessage(fd, msg_table[255]); - return 0; -} -/*========================================== - * @reloadstatusdb - * job_db1.txt job_db2.txt job_db2-2.txt - * refine_db.txt size_fix.txt - * のリロード - *------------------------------------------ - */ -int -atcommand_reloadstatusdb( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - status_readdb(); - clif_displaymessage(fd, msg_table[256]); - return 0; -} -/*========================================== - * @reloadpcdb - * exp.txt skill_tree.txt attr_fix.txt - * のリロード - *------------------------------------------ - */ -int -atcommand_reloadpcdb( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - pc_readdb(); - clif_displaymessage(fd, msg_table[257]); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -void rehash(void) -{ - int map_id; - - for (map_id = 0; map_id < map_num; map_id++) { - map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_MOB); - map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_NPC); - } -} -int atcommand_reloadscript( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - atcommand_broadcast( fd, sd, "@broadcast", "eAthena Server is Rehashing..." ); - atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" ); - - rehash(); - - atcommand_broadcast( fd, sd, "@broadcast", "Reloading NPCs..." ); - //do_init_npc(); - do_init_script(); - npc_reload(); - npc_event_do_oninit(); - - clif_displaymessage(fd, msg_table[100]); // Scripts reloaded. - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_reloadgmdb( // by [Yor] - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - chrif_reloadGMdb(); - - clif_displaymessage(fd, msg_table[101]); // Login-server asked to reload GM accounts and their level. - - return 0; -} - -/*========================================== - * @mapinfo <map name> [0-3] by MC_Cameri - * => Shows information about the map [map name] - * 0 = no additional information - * 1 = Show users in that map and their location - * 2 = Shows NPCs in that map - * 3 = Shows the shops/chats in that map (not implemented) - *------------------------------------------ - */ -int atcommand_mapinfo( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - struct npc_data *nd = NULL; - struct chat_data *cd = NULL; - char direction[12]; - int m_id, i, chat_num, list = 0; - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(direction, '\0', sizeof(direction)); - - sscanf(message, "%d %99[^\n]", &list, atcmd_player_name); - - if (list < 0 || list > 3) { - clif_displaymessage(fd, "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map])."); - return -1; - } - - if (atcmd_player_name[0] == '\0') - strcpy(atcmd_player_name, sd->mapname); - if (strstr(atcmd_player_name, ".gat") == NULL && strstr(atcmd_player_name, ".afm") == NULL && strlen(atcmd_player_name) < 13) // 16 - 4 (.gat) - strcat(atcmd_player_name, ".gat"); - - if ((m_id = map_mapname2mapid(atcmd_player_name)) < 0) { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - - clif_displaymessage(fd, "------ Map Info ------"); - sprintf(atcmd_output, "Map Name: %s", atcmd_player_name); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "Players In Map: %d", map[m_id].users); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "NPCs In Map: %d", map[m_id].npc_num); - clif_displaymessage(fd, atcmd_output); - chat_num = 0; - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && - (cd = (struct chat_data*)map_id2bl(pl_sd->chatID))) { - chat_num++; - } - } - sprintf(atcmd_output, "Chats In Map: %d", chat_num); - clif_displaymessage(fd, atcmd_output); - clif_displaymessage(fd, "------ Map Flags ------"); - sprintf(atcmd_output, "Player vs Player: %s | No Guild: %s | No Party: %s", - (map[m_id].flag.pvp) ? "True" : "False", - (map[m_id].flag.pvp_noguild) ? "True" : "False", - (map[m_id].flag.pvp_noparty) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "Guild vs Guild: %s | No Party: %s", (map[m_id].flag.gvg) ? "True" : "False", (map[m_id].flag.gvg_noparty) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Dead Branch: %s", (map[m_id].flag.nobranch) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Memo: %s", (map[m_id].flag.nomemo) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Penalty: %s", (map[m_id].flag.nopenalty) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Return: %s", (map[m_id].flag.noreturn) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Save: %s", (map[m_id].flag.nosave) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Teleport: %s", (map[m_id].flag.noteleport) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Monster Teleport: %s", (map[m_id].flag.monster_noteleport) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, "No Zeny Penalty: %s", (map[m_id].flag.nozenypenalty) ? "True" : "False"); - clif_displaymessage(fd, atcmd_output); - - switch (list) { - case 0: - // Do nothing. It's list 0, no additional display. - break; - case 1: - clif_displaymessage(fd, "----- Players in Map -----"); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && strcmp(pl_sd->mapname, atcmd_player_name) == 0) { - sprintf(atcmd_output, "Player '%s' (session #%d) | Location: %d,%d", - pl_sd->status.name, i, pl_sd->bl.x, pl_sd->bl.y); - clif_displaymessage(fd, atcmd_output); - } - } - break; - case 2: - clif_displaymessage(fd, "----- NPCs in Map -----"); - for (i = 0; i < map[m_id].npc_num;) { - nd = map[m_id].npc[i]; - switch(nd->dir) { - case 0: strcpy(direction, "North"); break; - case 1: strcpy(direction, "North West"); break; - case 2: strcpy(direction, "West"); break; - case 3: strcpy(direction, "South West"); break; - case 4: strcpy(direction, "South"); break; - case 5: strcpy(direction, "South East"); break; - case 6: strcpy(direction, "East"); break; - case 7: strcpy(direction, "North East"); break; - case 9: strcpy(direction, "North"); break; - default: strcpy(direction, "Unknown"); break; - } - sprintf(atcmd_output, "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d", - ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y); - clif_displaymessage(fd, atcmd_output); - } - break; - case 3: - clif_displaymessage(fd, "----- Chats in Map -----"); - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && - (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) && - strcmp(pl_sd->mapname, atcmd_player_name) == 0 && - cd->usersd[0] == pl_sd) { - sprintf(atcmd_output, "Chat %d: %s | Player: %s | Location: %d %d", - i, cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, " Users: %d/%d | Password: %s | Public: %s", - cd->users, cd->limit, cd->pass, (cd->pub) ? "Yes" : "No"); - clif_displaymessage(fd, atcmd_output); - } - } - break; - default: // normally impossible to arrive here - clif_displaymessage(fd, "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map])."); - return -1; - break; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_mount_peco( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(fd, msg_table[212]); // Cannot mount a Peco while in disguise. - return -1; - } - - if (!pc_isriding(sd)) { // if actually no peco - if (sd->status.class_ == 7 || sd->status.class_ == 14 || sd->status.class_ == 4008 || sd->status.class_ == 4015) { - if (sd->status.class_ == 7) - sd->status.class_ = sd->view_class = 13; - else if (sd->status.class_ == 14) - sd->status.class_ = sd->view_class = 21; - else if (sd->status.class_ == 4008) - sd->status.class_ = sd->view_class = 4014; - else if (sd->status.class_ == 4015) - sd->status.class_ = sd->view_class = 4022; - pc_setoption(sd, sd->status.option | 0x0020); - clif_displaymessage(fd, msg_table[102]); // Mounted Peco. - } else { - clif_displaymessage(fd, msg_table[213]); // You can not mount a peco with your job. - return -1; - } - } else { - if (sd->status.class_ == 13) - sd->status.class_ = sd->view_class = 7; - else if (sd->status.class_ == 21) - sd->status.class_ = sd->view_class = 14; - else if (sd->status.class_ == 4014) - sd->status.class_ = sd->view_class = 4008; - else if (sd->status.class_ == 4022) - sd->status.class_ = sd->view_class = 4015; - pc_setoption(sd, sd->status.option & ~0x0020); - clif_displaymessage(fd, msg_table[214]); // Unmounted Peco. - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_char_mount_peco( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charmountpeco <char_name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pl_sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(fd, msg_table[215]); // This player cannot mount a Peco while in disguise. - return -1; - } - - if (!pc_isriding(pl_sd)) { // if actually no peco - if (pl_sd->status.class_ == 7 || pl_sd->status.class_ == 14 || pl_sd->status.class_ == 4008 || pl_sd->status.class_ == 4015) { - if (pl_sd->status.class_ == 7) - pl_sd->status.class_ = pl_sd->view_class = 13; - else if (pl_sd->status.class_ == 14) - pl_sd->status.class_ = pl_sd->view_class = 21; - else if (pl_sd->status.class_ == 4008) - pl_sd->status.class_ = pl_sd->view_class = 4014; - else if (pl_sd->status.class_ == 4015) - pl_sd->status.class_ = pl_sd->view_class = 4022; - pc_setoption(pl_sd, pl_sd->status.option | 0x0020); - clif_displaymessage(fd, msg_table[216]); // Now, this player mounts a peco. - } else { - clif_displaymessage(fd, msg_table[217]); // This player can not mount a peco with his/her job. - return -1; - } - } else { - if (pl_sd->status.class_ == 13) - pl_sd->status.class_ = pl_sd->view_class = 7; - else if (pl_sd->status.class_ == 21) - pl_sd->status.class_ = pl_sd->view_class = 14; - else if (pl_sd->status.class_ == 4014) - pl_sd->status.class_ = pl_sd->view_class = 4008; - else if (pl_sd->status.class_ == 4022) - pl_sd->status.class_ = pl_sd->view_class = 4015; - pc_setoption(pl_sd, pl_sd->status.option & ~0x0020); - clif_displaymessage(fd, msg_table[218]); // Now, this player has not more peco. - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - *Spy Commands by Syrus22 - *------------------------------------------ - */ -int atcommand_guildspy( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char guild_name[100]; - struct guild *g; - nullpo_retr(-1, sd); - - memset(guild_name, '\0', sizeof(guild_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", guild_name) < 1) { - clif_displaymessage(fd, "Please, enter a guild name/id (usage: @guildspy <guild_name/id>)."); - return -1; - } - - if ((g = guild_searchname(guild_name)) != NULL || // name first to avoid error when name begin with a number - (g = guild_search(atoi(message))) != NULL) { - if (sd->guildspy == g->guild_id) { - sd->guildspy = 0; - sprintf(atcmd_output, msg_table[103], g->name); // No longer spying on the %s guild. - clif_displaymessage(fd, atcmd_output); - } else { - sd->guildspy = g->guild_id; - sprintf(atcmd_output, msg_table[104], g->name); // Spying on the %s guild. - clif_displaymessage(fd, atcmd_output); - } - } else { - clif_displaymessage(fd, msg_table[94]); // Incorrect name/ID, or no one from the guild is online. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_partyspy( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char party_name[100]; - struct party *p; - nullpo_retr(-1, sd); - - memset(party_name, '\0', sizeof(party_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", party_name) < 1) { - clif_displaymessage(fd, "Please, enter a party name/id (usage: @partyspy <party_name/id>)."); - return -1; - } - - if ((p = party_searchname(party_name)) != NULL || // name first to avoid error when name begin with a number - (p = party_search(atoi(message))) != NULL) { - if (sd->partyspy == p->party_id) { - sd->partyspy = 0; - sprintf(atcmd_output, msg_table[105], p->name); // No longer spying on the %s party. - clif_displaymessage(fd, atcmd_output); - } else { - sd->partyspy = p->party_id; - sprintf(atcmd_output, msg_table[106], p->name); // Spying on the %s party. - clif_displaymessage(fd, atcmd_output); - } - } else { - clif_displaymessage(fd, msg_table[96]); // Incorrect name or ID, or no one from the party is online. - return -1; - } - - return 0; -} - -/*========================================== - * @repairall [Valaris] - *------------------------------------------ - */ -int atcommand_repairall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int count, i; - nullpo_retr(-1, sd); - - count = 0; - for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid && sd->status.inventory[i].attribute == 1) { - sd->status.inventory[i].attribute = 0; - clif_produceeffect(sd, 0, sd->status.inventory[i].nameid); - count++; - } - } - - if (count > 0) { - clif_misceffect(&sd->bl, 3); - clif_equiplist(sd); - clif_displaymessage(fd, msg_table[107]); // All items have been repaired. - } else { - clif_displaymessage(fd, msg_table[108]); // No item need to be repaired. - return -1; - } - - return 0; -} - -// Removed @nuke for now in favor of alchemist marine sphere skill [Valaris] -int atcommand_nuke( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @nuke <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same GM level - skill_castend_damage_id(&pl_sd->bl, &pl_sd->bl, NPC_SELFDESTRUCTION, 99, gettick(), 0); - clif_displaymessage(fd, msg_table[109]); // Player has been nuked! - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_enablenpc(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char NPCname[100]; - nullpo_retr(-1, sd); - - memset(NPCname, '\0', sizeof(NPCname)); - - if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) { - clif_displaymessage(fd, "Please, enter a NPC name (usage: @enablenpc <NPC_name>)."); - return -1; - } - - if (npc_name2id(NPCname) != NULL) { - npc_enable(NPCname, 1); - clif_displaymessage(fd, msg_table[110]); // Npc Enabled. - } else { - clif_displaymessage(fd, msg_table[111]); // This NPC doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int atcommand_hidenpc(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char NPCname[100]; - nullpo_retr(-1, sd); - - memset(NPCname, '\0', sizeof(NPCname)); - - if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) { - clif_displaymessage(fd, "Please, enter a NPC name (usage: @npcoff <NPC_name>)."); - return -1; - } - - if (npc_name2id(NPCname) != NULL) { - npc_enable(NPCname, 0); - clif_displaymessage(fd, msg_table[112]); // Npc Disabled. - } else { - clif_displaymessage(fd, msg_table[111]); // This NPC doesn't exist. - return -1; - } - - return 0; -} - -int atcommand_disablenpc(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct npc_data *nd; - char NPCname[100]; - nullpo_retr(-1, sd); - - memset(NPCname, '\0', sizeof(NPCname)); - - if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) { - clif_displaymessage(fd, "Please, enter a NPC name (usage: @npcoff <NPC_name>)."); - return -1; - } - - if ((nd = npc_name2id(NPCname)) != NULL) { - npc_unload(nd); - clif_displaymessage(fd, msg_table[112]); // Npc Disabled. - } else { - clif_displaymessage(fd, msg_table[111]); // This NPC doesn't exist. - return -1; - } - - return 0; -} - -/*========================================== - * time in txt for time command (by [Yor]) - *------------------------------------------ - */ -char * txt_time(unsigned int duration) { - int days, hours, minutes, seconds; - char temp[256]; - static char temp1[256]; - - memset(temp, '\0', sizeof(temp)); - memset(temp1, '\0', sizeof(temp1)); - - if (duration < 0) - duration = 0; - - days = duration / (60 * 60 * 24); - duration = duration - (60 * 60 * 24 * days); - hours = duration / (60 * 60); - duration = duration - (60 * 60 * hours); - minutes = duration / 60; - seconds = duration - (60 * minutes); - - if (days < 2) - sprintf(temp, msg_table[219], days); // %d day - else - sprintf(temp, msg_table[220], days); // %d days - if (hours < 2) - sprintf(temp1, msg_table[221], temp, hours); // %s %d hour - else - sprintf(temp1, msg_table[222], temp, hours); // %s %d hours - if (minutes < 2) - sprintf(temp, msg_table[223], temp1, minutes); // %s %d minute - else - sprintf(temp, msg_table[224], temp1, minutes); // %s %d minutes - if (seconds < 2) - sprintf(temp1, msg_table[225], temp, seconds); // %s and %d second - else - sprintf(temp1, msg_table[226], temp, seconds); // %s and %d seconds - - return temp1; -} - -/*========================================== - * @time/@date/@server_date/@serverdate/@server_time/@servertime: Display the date/time of the server (by [Yor] - * Calculation management of GM modification (@day/@night GM commands) is done - *------------------------------------------ - */ -int atcommand_servertime(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct TimerData * timer_data; - struct TimerData * timer_data2; - time_t time_server; // variable for number of seconds (used with time() function) - struct tm *datetime; // variable for time in structure ->tm_mday, ->tm_sec, ... - char temp[256]; - nullpo_retr(-1, sd); - - memset(temp, '\0', sizeof(temp)); - - time(&time_server); // get time in seconds since 1/1/1970 - datetime = localtime(&time_server); // convert seconds in structure - // like sprintf, but only for date/time (Sunday, November 02 2003 15:12:52) - strftime(temp, sizeof(temp)-1, msg_table[230], datetime); // Server time (normal time): %A, %B %d %Y %X. - clif_displaymessage(fd, temp); - - if (battle_config.night_duration == 0 && battle_config.day_duration == 0) { - if (night_flag == 0) - clif_displaymessage(fd, msg_table[231]); // Game time: The game is in permanent daylight. - else - clif_displaymessage(fd, msg_table[232]); // Game time: The game is in permanent night. - } else if (battle_config.night_duration == 0) - if (night_flag == 1) { // we start with night - timer_data = get_timer(day_timer_tid); - sprintf(temp, msg_table[233], txt_time((timer_data->tick - gettick()) / 1000)); // Game time: The game is actualy in night for %s. - clif_displaymessage(fd, temp); - clif_displaymessage(fd, msg_table[234]); // Game time: After, the game will be in permanent daylight. - } else - clif_displaymessage(fd, msg_table[231]); // Game time: The game is in permanent daylight. - else if (battle_config.day_duration == 0) - if (night_flag == 0) { // we start with day - timer_data = get_timer(night_timer_tid); - sprintf(temp, msg_table[235], txt_time((timer_data->tick - gettick()) / 1000)); // Game time: The game is actualy in daylight for %s. - clif_displaymessage(fd, temp); - clif_displaymessage(fd, msg_table[236]); // Game time: After, the game will be in permanent night. - } else - clif_displaymessage(fd, msg_table[232]); // Game time: The game is in permanent night. - else { - if (night_flag == 0) { - timer_data = get_timer(night_timer_tid); - timer_data2 = get_timer(day_timer_tid); - sprintf(temp, msg_table[235], txt_time((timer_data->tick - gettick()) / 1000)); // Game time: The game is actualy in daylight for %s. - clif_displaymessage(fd, temp); - if (timer_data->tick > timer_data2->tick) - sprintf(temp, msg_table[237], txt_time((timer_data->interval - abs(timer_data->tick - timer_data2->tick)) / 1000)); // Game time: After, the game will be in night for %s. - else - sprintf(temp, msg_table[237], txt_time(abs(timer_data->tick - timer_data2->tick) / 1000)); // Game time: After, the game will be in night for %s. - clif_displaymessage(fd, temp); - sprintf(temp, msg_table[238], txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s. - clif_displaymessage(fd, temp); - } else { - timer_data = get_timer(day_timer_tid); - timer_data2 = get_timer(night_timer_tid); - sprintf(temp, msg_table[233], txt_time((timer_data->tick - gettick()) / 1000)); // Game time: The game is actualy in night for %s. - clif_displaymessage(fd, temp); - if (timer_data->tick > timer_data2->tick) - sprintf(temp, msg_table[239], txt_time((timer_data->interval - abs(timer_data->tick - timer_data2->tick)) / 1000)); // Game time: After, the game will be in daylight for %s. - else - sprintf(temp, msg_table[239], txt_time(abs(timer_data->tick - timer_data2->tick) / 1000)); // Game time: After, the game will be in daylight for %s. - clif_displaymessage(fd, temp); - sprintf(temp, msg_table[238], txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s. - clif_displaymessage(fd, temp); - } - } - - return 0; -} - -/*========================================== - * @chardelitem <item_name_or_ID> <quantity> <player> (by [Yor] - * removes <quantity> item from a character - * item can be equiped or not. - * Inspired from a old command created by RoVeRT - *------------------------------------------ - */ -int atcommand_chardelitem(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - char item_name[100]; - int i, number = 0, item_id, item_position, count; - struct item_data *item_data; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(item_name, '\0', sizeof(item_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message || sscanf(message, "%s %d %99[^\n]", item_name, &number, atcmd_player_name) < 3 || number < 1) { - clif_displaymessage(fd, "Please, enter an item name/id, a quantity and a player name (usage: @chardelitem <item_name_or_ID> <quantity> <player>)."); - return -1; - } - - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) - item_id = item_data->nameid; - - if (item_id > 500) { - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level - item_position = pc_search_inventory(pl_sd, item_id); - if (item_position >= 0) { - count = 0; - for(i = 0; i < number && item_position >= 0; i++) { - pc_delitem(pl_sd, item_position, 1, 0); - count++; - item_position = pc_search_inventory(pl_sd, item_id); // for next loop - } - sprintf(atcmd_output, msg_table[113], count); // %d item(s) removed by a GM. - clif_displaymessage(pl_sd->fd, atcmd_output); - if (number == count) - sprintf(atcmd_output, msg_table[114], count); // %d item(s) removed from the player. - else - sprintf(atcmd_output, msg_table[115], count, count, number); // %d item(s) removed. Player had only %d on %d items. - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[116]); // Character does not have the item. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name. - return -1; - } - - return 0; -} - -/*========================================== - * @jail <char_name> by [Yor] - * Special warp! No check with nowarp and nowarpto flag - *------------------------------------------ - */ -int atcommand_jail( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int x, y; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @jail <char_name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can jail only lower or same GM - switch(rand() % 2) { - case 0: - x = 24; - y = 75; - break; - default: - x = 49; - y = 75; - break; - } - if (pc_setpos(pl_sd, "sec_pri.gat", x, y, 3) == 0) { - pc_setsavepoint(pl_sd, "sec_pri.gat", x, y); // Save Char Respawn Point in the jail room [Lupus] - clif_displaymessage(pl_sd->fd, msg_table[117]); // GM has send you in jails. - clif_displaymessage(fd, msg_table[118]); // Player warped in jails. - } else { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * @unjail/@discharge <char_name> by [Yor] - * Special warp! No check with nowarp and nowarpto flag - *------------------------------------------ - */ -int atcommand_unjail( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @unjail/@discharge <char_name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can jail only lower or same GM - if (pl_sd->bl.m != map_mapname2mapid("sec_pri.gat")) { - clif_displaymessage(fd, msg_table[119]); // This player is not in jails. - return -1; - } else if (pc_setpos(pl_sd, "prontera.gat", 0, 0, 3) == 0) { //old coords: 156,191 - pc_setsavepoint(pl_sd, "prontera.gat", 0, 0); // Save char respawn point in Prontera - clif_displaymessage(pl_sd->fd, msg_table[120]); // GM has discharge you. - clif_displaymessage(fd, msg_table[121]); // Player warped to Prontera. - } else { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * @disguise <mob_id> by [Valaris] (simplified by [Yor]) - *------------------------------------------ - */ -int atcommand_disguise( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int mob_id = 0; - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a Monster/NPC name/id (usage: @disguise <monster_name_or_monster_ID>)."); - return -1; - } - - if ((mob_id = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = atoi(message); - - if ((mob_id >= 46 && mob_id <= 125) || (mob_id >= 700 && mob_id <= 718) || // NPC - (mob_id >= 721 && mob_id <= 755) || (mob_id >= 757 && mob_id <= 811) || // NPC - (mob_id >= 813 && mob_id <= 834) || // NPC - (mob_id > 1000 && mob_id < 1582)) { // monsters - if (pc_isriding(sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(fd, msg_table[227]); // Cannot wear disguise while riding a Peco. - return -1; - } - sd->disguiseflag = 1; // set to override items with disguise script [Valaris] - sd->disguise = mob_id; - pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3); - clif_displaymessage(fd, msg_table[122]); // Disguise applied. - } else { - clif_displaymessage(fd, msg_table[123]); // Monster/NPC name/id hasn't been found. - return -1; - } - - return 0; -} - -/*========================================== - * DisguiseAll - *------------------------------------------ - */ - -int atcommand_disguiseall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int mob_id=0, i=0; - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a Monster/NPC name/id (usage: @disguiseall <monster_name_or_monster_ID>)."); - return -1; - } - - if ((mob_id = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = atoi(message); - - if ((mob_id >= 46 && mob_id <= 125) || (mob_id >= 700 && mob_id <= 718) || // NPC - (mob_id >= 721 && mob_id <= 755) || (mob_id >= 757 && mob_id <= 811) || // NPC - (mob_id >= 813 && mob_id <= 834) || // NPC - (mob_id > 1000 && mob_id < 1582)) { // monsters - for(i=0; i < fd_max; i++) { - if(session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - if(pc_isriding(pl_sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(fd, msg_table[227]); // Cannot wear disguise while riding a Peco. - } else { - pl_sd->disguiseflag = 1; // set to override items with disguise script [Valaris] - pl_sd->disguise = mob_id; - pc_setpos(pl_sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - } - } - } - clif_displaymessage(fd, msg_table[122]); // Disguise applied. - } else { - return -1; - } - - return 0; -} - -/*========================================== - * @undisguise by [Yor] - *------------------------------------------ - */ -int atcommand_undisguise( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (sd->disguise) { - clif_clearchar(&sd->bl, 9); - sd->disguise = 0; - pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3); - clif_displaymessage(fd, msg_table[124]); // Undisguise applied. - } else { - clif_displaymessage(fd, msg_table[125]); // You're not disguised. - return -1; - } - - return 0; -} - -/*========================================== - * UndisguiseAll - *------------------------------------------ - */ -int atcommand_undisguiseall( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int i; - nullpo_retr(-1, sd); - - for(i=0; i < fd_max; i++) { - if(session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && pl_sd->disguise) { - clif_clearchar(&pl_sd->bl, 9); - pl_sd->disguise = 0; - pc_setpos(pl_sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - } - } - clif_displaymessage(fd, msg_table[124]); // Undisguise applied. - - return 0; -} - -/*========================================== - * @broadcast by [Valaris] - *------------------------------------------ - */ -int atcommand_broadcast( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a message (usage: @broadcast <message>)."); - return -1; - } - - sprintf(atcmd_output, "%s : %s", sd->status.name, message); - intif_GMmessage(atcmd_output, strlen(atcmd_output) + 1, 0); - - return 0; -} - -/*========================================== - * @localbroadcast by [Valaris] - *------------------------------------------ - */ -int atcommand_localbroadcast( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a message (usage: @localbroadcast <message>)."); - return -1; - } - - sprintf(atcmd_output, "%s : %s", sd->status.name, message); - - clif_GMmessage(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 1); // 1: ALL_SAMEMAP - - return 0; -} - -/*========================================== - * @chardisguise <mob_id> <character> by Kalaspuff (based off Valaris' and Yor's work) - *------------------------------------------ - */ -int atcommand_chardisguise( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int mob_id; - char mob_name[100]; - struct map_session_data* pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(mob_name, '\0', sizeof(mob_name)); - - if (!message || !*message || sscanf(message, "%s %99[^\n]", mob_name, atcmd_player_name) < 2) { - clif_displaymessage(fd, "Please, enter a Monster/NPC name/id and a player name (usage: @chardisguise <monster_name_or_monster_ID> <char name>)."); - return -1; - } - - if ((mob_id = mobdb_searchname(mob_name)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = atoi(mob_name); - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can disguise only lower or same level - if ((mob_id >= 46 && mob_id <= 125) || (mob_id >= 700 && mob_id <= 718) || // NPC - (mob_id >= 721 && mob_id <= 755) || (mob_id >= 757 && mob_id <= 811) || // NPC - (mob_id >= 813 && mob_id <= 834) || // NPC - (mob_id > 1000 && mob_id < 1521)) { // monsters - if (pc_isriding(pl_sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(fd, msg_table[228]); // Character cannot wear disguise while riding a Peco. - return -1; - } - pl_sd->disguiseflag = 1; // set to override items with disguise script [Valaris] - pl_sd->disguise = mob_id; - pc_setpos(pl_sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - clif_displaymessage(fd, msg_table[140]); // Character's disguise applied. - } else { - clif_displaymessage(fd, msg_table[123]); // Monster/NPC name/id hasn't been found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * @charundisguise <character> by Kalaspuff (based off Yor's work) - *------------------------------------------ - */ -int atcommand_charundisguise( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data* pl_sd; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charundisguise <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can undisguise only lower or same level - if (pl_sd->disguise) { - clif_clearchar(&pl_sd->bl, 9); - pl_sd->disguise = 0; - pc_setpos(pl_sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - clif_displaymessage(fd, msg_table[141]); // Character's undisguise applied. - } else { - clif_displaymessage(fd, msg_table[142]); // Character is not disguised. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * @email <actual@email> <new@email> by [Yor] - *------------------------------------------ - */ -int atcommand_email( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char actual_email[100]; - char new_email[100]; - nullpo_retr(-1, sd); - - memset(actual_email, '\0', sizeof(actual_email)); - memset(new_email, '\0', sizeof(new_email)); - - if (!message || !*message || sscanf(message, "%99s %99s", actual_email, new_email) < 2) { - clif_displaymessage(fd, "Please enter 2 emails (usage: @email <actual@email> <new@email>)."); - return -1; - } - - if (e_mail_check(actual_email) == 0) { - clif_displaymessage(fd, msg_table[144]); // Invalid actual email. If you have default e-mail, give a@a.com. - return -1; - } else if (e_mail_check(new_email) == 0) { - clif_displaymessage(fd, msg_table[145]); // Invalid new email. Please enter a real e-mail. - return -1; - } else if (strcmpi(new_email, "a@a.com") == 0) { - clif_displaymessage(fd, msg_table[146]); // New email must be a real e-mail. - return -1; - } else if (strcmpi(actual_email, new_email) == 0) { - clif_displaymessage(fd, msg_table[147]); // New email must be different of the actual e-mail. - return -1; - } else { - chrif_changeemail(sd->status.account_id, actual_email, new_email); - clif_displaymessage(fd, msg_table[148]); // Information sended to login-server via char-server. - } - - return 0; -} - -/*========================================== - *@effect - *------------------------------------------ - */ -int atcommand_effect( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int type = 0, flag = 0, i; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %d", &type,&flag) < 2) { - clif_displaymessage(fd, "Please, enter at least a option (usage: @effect <type+>)."); - return -1; - } - if(flag <=0){ - clif_specialeffect(&sd->bl, type, flag); - clif_displaymessage(fd, msg_table[229]); // Your effect has changed. - } - else{ - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - clif_specialeffect(&pl_sd->bl, type, flag); - clif_displaymessage(pl_sd->fd, msg_table[229]); // Your effect has changed. - } - } - } - - return 0; -} - -/*========================================== - * @charcartlist <character>: Displays the items list of a player's cart. - *------------------------------------------ - */ -int -atcommand_character_cart_list( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char outputtmp[200]; - struct map_session_data *pl_sd; - struct item_data *item_data, *item_temp; - int i, j, count, counter, counter2; - nullpo_retr(-1, sd); - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(outputtmp, '\0', sizeof(outputtmp)); - - if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: @charitemlist <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level - counter = 0; - count = 0; - for (i = 0; i < MAX_CART; i++) { - if (pl_sd->status.cart[i].nameid > 0 && (item_data = itemdb_search(pl_sd->status.cart[i].nameid)) != NULL) { - counter = counter + pl_sd->status.cart[i].amount; - count++; - if (count == 1) { - sprintf(atcmd_output, "------ Cart items list of '%s' ------", pl_sd->status.name); - clif_displaymessage(fd, atcmd_output); - } - if (pl_sd->status.cart[i].refine) - sprintf(atcmd_output, "%d %s %+d (%s %+d, id: %d)", pl_sd->status.cart[i].amount, item_data->name, pl_sd->status.cart[i].refine, item_data->jname, pl_sd->status.cart[i].refine, pl_sd->status.cart[i].nameid); - else - sprintf(atcmd_output, "%d %s (%s, id: %d)", pl_sd->status.cart[i].amount, item_data->name, item_data->jname, pl_sd->status.cart[i].nameid); - clif_displaymessage(fd, atcmd_output); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - counter2 = 0; - for (j = 0; j < item_data->slot; j++) { - if (pl_sd->status.cart[i].card[j]) { - if ( (item_temp = itemdb_search(pl_sd->status.cart[i].card[j])) != NULL) { - if (atcmd_output[0] == '\0') - sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); - else - sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); - strcat(atcmd_output, outputtmp); - } - } - } - if (atcmd_output[0] != '\0') { - atcmd_output[strlen(atcmd_output) - 2] = ')'; - atcmd_output[strlen(atcmd_output) - 1] = '\0'; - clif_displaymessage(fd, atcmd_output); - } - } - } - if (count == 0) - clif_displaymessage(fd, "No item found in the cart of this player."); - else { - sprintf(atcmd_output, "%d item(s) found in %d kind(s) of items.", counter, count); - clif_displaymessage(fd, atcmd_output); - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * @killer by MouseJstr - * enable killing players even when not in pvp - *------------------------------------------ - */ -int -atcommand_killer( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - sd->special_state.killer = !sd->special_state.killer; - - if(sd->special_state.killer) - clif_displaymessage(fd, msg_table[241]); - else - clif_displaymessage(fd, msg_table[242]); - - return 0; -} - -/*========================================== - * @killable by MouseJstr - * enable other people killing you - *------------------------------------------ - */ -int -atcommand_killable( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - sd->special_state.killable = !sd->special_state.killable; - - if(sd->special_state.killable) - clif_displaymessage(fd, msg_table[242]); - else - clif_displaymessage(fd, msg_table[241]); - - return 0; -} - -/*========================================== - * @charkillable by MouseJstr - * enable another player to be killed - *------------------------------------------ - */ -int -atcommand_charkillable( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - - if((pl_sd=map_nick2sd((char *) message)) == NULL) - return -1; - - pl_sd->special_state.killable = !pl_sd->special_state.killable; - - if(pl_sd->special_state.killable) - clif_displaymessage(fd, "The player is now killable"); - else - clif_displaymessage(fd, "The player is no longer killable"); - - return 0; -} - - -/*========================================== - * @skillon by MouseJstr - * turn skills on for the map - *------------------------------------------ - */ -int -atcommand_skillon( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - map[sd->bl.m].flag.noskill = 0; - clif_displaymessage(fd, msg_table[244]); - return 0; -} - -/*========================================== - * @skilloff by MouseJstr - * Turn skills off on the map - *------------------------------------------ - */ -int -atcommand_skilloff( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - map[sd->bl.m].flag.noskill = 1; - clif_displaymessage(fd, msg_table[243]); - return 0; -} - -/*========================================== - * @npcmove by MouseJstr - * - * move a npc - *------------------------------------------ - */ -int -atcommand_npcmove(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int x = 0, y = 0; - struct npc_data *nd = 0; - nullpo_retr(-1, sd); - - - if (!message || !*message) - return -1; - - memset(atcmd_player_name, '\0', sizeof atcmd_player_name); - - if (sscanf(message, "%d %d %99[^\n]", &x, &y, atcmd_player_name) < 3) { - clif_displaymessage(fd, "Usage: @npcmove <X> <Y> <npc_name>"); - return -1; - } - - nullpo_retr(-1, (nd = npc_name2id(atcmd_player_name))); - - npc_enable(atcmd_player_name, 0); - nd->bl.x = x; - nd->bl.y = y; - npc_enable(atcmd_player_name, 1); - - return 0; -} - -/*========================================== - * @addwarp by MouseJstr - * - * Create a new static warp point. - *------------------------------------------ - */ -int -atcommand_addwarp(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char w1[64], w3[64], w4[64]; - int x,y,ret; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - - if (sscanf(message, "%99s %d %d[^\n]", atcmd_player_name, &x, &y ) < 3) - return -1; - - sprintf(w1,"%s,%d,%d", sd->mapname, sd->bl.x, sd->bl.y); - sprintf(w3,"%s%d%d%d%d", atcmd_player_name,sd->bl.x, sd->bl.y, x, y); - sprintf(w4,"1,1,%s.gat,%d,%d", atcmd_player_name, x, y); - - ret = npc_parse_warp(w1, "warp", w3, w4); - - sprintf(atcmd_output, "New warp NPC => %s",w3); - - clif_displaymessage(fd, atcmd_output); - - return ret; -} - -/*========================================== - * @follow by [MouseJstr] - * - * Follow a player .. staying no more then 5 spaces away - *------------------------------------------ - */ -int -atcommand_follow(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if((pl_sd=map_nick2sd((char *) message)) != NULL) - pc_follow(sd, pl_sd->bl.id); - else - return 1; - return 0; -} - - -/*========================================== - * @dropall by [MouseJstr] - * - * Drop all your possession on the ground - *------------------------------------------ - */ -int -atcommand_dropall(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - nullpo_retr(-1, sd); - for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].amount) { - if(sd->status.inventory[i].equip != 0) - pc_unequipitem(sd, i, 3); - pc_dropitem(sd, i, sd->status.inventory[i].amount); - } - } - return 0; -} -/*========================================== - * @chardropall by [MouseJstr] - * - * Throw all the characters possessions on the ground. Normally - * done in response to them being disrespectful of a GM - *------------------------------------------ - */ -int -atcommand_chardropall(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if((pl_sd=map_nick2sd((char *) message)) == NULL) - return -1; - for (i = 0; i < MAX_INVENTORY; i++) { - if (pl_sd->status.inventory[i].amount) { - if(pl_sd->status.inventory[i].equip != 0) - pc_unequipitem(pl_sd, i, 3); - pc_dropitem(pl_sd, i, pl_sd->status.inventory[i].amount); - } - } - - clif_displaymessage(pl_sd->fd, "Ever play 52 card pickup?"); - clif_displaymessage(fd, "It is done"); - //clif_displaymessage(fd, "It is offical.. your a jerk"); - - return 0; -} -/*========================================== - * @storeall by [MouseJstr] - * - * Put everything into storage to simplify your inventory to make - * debugging easie - *------------------------------------------ - */ -int -atcommand_storeall(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - nullpo_retr(-1, sd); - if (storage_storageopen(sd) == 1) { - clif_displaymessage(fd, "run this command again.."); - return 0; - } - for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].amount) { - if(sd->status.inventory[i].equip != 0) - pc_unequipitem(sd, i, 3); - storage_storageadd(sd, i, sd->status.inventory[i].amount); - } - } - storage_storageclose(sd); - - clif_displaymessage(fd, "It is done"); - return 0; -} -/*========================================== - * @charstoreall by [MouseJstr] - * - * A way to screw with players who piss you off - *------------------------------------------ - */ -int -atcommand_charstoreall(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i; - struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if((pl_sd=map_nick2sd((char *) message)) == NULL) - return -1; - - if (storage_storageopen(pl_sd) == 1) { - clif_displaymessage(fd, "Had to open the characters storage window..."); - clif_displaymessage(fd, "run this command again.."); - return 0; - } - for (i = 0; i < MAX_INVENTORY; i++) { - if (pl_sd->status.inventory[i].amount) { - if(pl_sd->status.inventory[i].equip != 0) - pc_unequipitem(pl_sd, i, 3); - storage_storageadd(pl_sd, i, sd->status.inventory[i].amount); - } - } - storage_storageclose(pl_sd); - - clif_displaymessage(pl_sd->fd, "Everything you own has been put away for safe keeping."); - clif_displaymessage(pl_sd->fd, "go to the nearest kafka to retrieve it.."); - clif_displaymessage(pl_sd->fd, " -- the management"); - - clif_displaymessage(fd, "It is done"); - - return 0; -} -/*========================================== - * @skillid by [MouseJstr] - * - * lookup a skill by name - *------------------------------------------ - */ -int -atcommand_skillid(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int skillen = 0, idx = 0; - nullpo_retr(-1, sd); - if (!message || !*message) - return -1; - skillen = strlen(message); - while (skill_names[idx].id != 0) { - if ((strnicmp(skill_names[idx].name, message, skillen) == 0) || - (strnicmp(skill_names[idx].desc, message, skillen) == 0)) { - sprintf(atcmd_output, "skill %d: %s", skill_names[idx].id, skill_names[idx].desc); - clif_displaymessage(fd, atcmd_output); - } - idx++; - } - return 0; -} - -/*========================================== - * @useskill by [MouseJstr] - * - * A way of using skills without having to find them in the skills menu - *------------------------------------------ - */ -int -atcommand_useskill(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - int skillnum; - int skilllv; - int inf; - char target[255]; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if(sscanf(message, "%d %d %99[^\n]", &skillnum, &skilllv, target) != 3) { - clif_displaymessage(fd, "Usage: @useskill <skillnum> <skillv> <target>"); - return -1; - } - if((pl_sd=map_nick2sd(target)) == NULL) { - return -1; - } - - inf = skill_get_inf(skillnum); - - if ((inf == 2) || (inf == 1)) - skill_use_pos(sd, pl_sd->bl.x, pl_sd->bl.y, skillnum, skilllv); - else - skill_use_id(sd, pl_sd->bl.id, skillnum, skilllv); - - return 0; -} - -/*========================================== - * @skilltree by [MouseJstr] - * - * prints the skill tree for a player required to get to a skill - *------------------------------------------ - */ -int -atcommand_skilltree(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - int skillnum, skillidx = -1; - int meets = 1, j, c=0, s=0; - struct pc_base_job s_class; - char target[255], *tbl; - struct skill_tree_entry *ent; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - - if(sscanf(message, "%d %[^\r\n]", &skillnum, target) != 2) { - clif_displaymessage(fd, "Usage: @skilltree <skillnum> <target>"); - return -1; - } - if((pl_sd=map_nick2sd(target)) == NULL) - return -1; - - s_class = pc_calc_base_job(pl_sd->status.class_); - c = s_class.job; - s = s_class.upper; - - c = pc_calc_skilltree_normalize_job(c, pl_sd); - - tbl = job_name(c); - - sprintf(atcmd_output, "Player is using %s %s skill tree (%d basic points)", - s_class.upper ? "upper" : "lower", - tbl, pc_checkskill(pl_sd, 1)); - clif_displaymessage(fd, atcmd_output); - - for (j = 0; skill_tree[s][c][j].id != 0; j++) { - if (skill_tree[s][c][j].id == skillnum) { - skillidx = j; - break; - } - } - - if (skillidx == -1) { - sprintf(atcmd_output, "I do not believe the player can use that skill"); - clif_displaymessage(fd, atcmd_output); - return 0; - } - - ent = &skill_tree[s][c][skillidx]; - - for(j=0;j<5;j++) - if( ent->need[j].id && - pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv) - { - int idx = 0; - char *desc; - while (skill_names[idx].id != 0 && skill_names[idx].id != ent->need[j].id) - idx++; - if (skill_names[idx].id == 0) - desc = "Unknown skill"; - else - desc = skill_names[idx].desc; - sprintf(atcmd_output, "player requires level %d of skill %s", - ent->need[j].lv, desc); - clif_displaymessage(fd, atcmd_output); - meets = 0; - } - - if (meets == 1) { - sprintf(atcmd_output, "I believe the player meets all the requirements for that skill"); - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * @marry by [MouseJstr], fixed by Lupus - * - * Marry two players - *------------------------------------------ - */ -int -atcommand_marry(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd1 = NULL; - struct map_session_data *pl_sd2 = NULL; - char player1[255], player2[255]; - - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%[^,],%[^\r\n]", player1, player2) != 2) { - clif_displaymessage(fd, "Usage: @marry <player1>,<player2>."); - return -1; - } - - if((pl_sd1=map_nick2sd((char *) player1)) == NULL) { - sprintf(player2, "Cannot find player '%s' online", player1); - clif_displaymessage(fd, player2); - return -1; - } - - if((pl_sd2=map_nick2sd((char *) player2)) == NULL) { - sprintf(player1, "Cannot find player '%s' online", player2); - clif_displaymessage(fd, player1); - return -1; - } - - if (pc_marriage(pl_sd1, pl_sd2) == 0) { - clif_displaymessage(fd, "They are married.. wish them well"); - clif_wedding_effect(&sd->bl); //wedding effect and music [Lupus] - return 0; - } - return -1; -} - -/*========================================== - * @divorce by [MouseJstr], fixed by [Lupus] - * - * divorce two players - *------------------------------------------ - */ -int -atcommand_divorce(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%[^\r\n]", atcmd_player_name) != 1) { - clif_displaymessage(fd, "Usage: @divorce <player>."); - return -1; - } - - if((pl_sd=map_nick2sd((char *) atcmd_player_name)) != NULL) { - if (pc_divorce(pl_sd) != 0) { - sprintf(atcmd_output, "The divorce has failed.. Cannot find player '%s' or his(her) partner online.", atcmd_player_name); - clif_displaymessage(fd, atcmd_output); - return -1; - } else { - sprintf(atcmd_output, "'%s' and his(her) partner are now divorced.", atcmd_player_name); - clif_displaymessage(fd, atcmd_output); - return 0; - } - } - sprintf(atcmd_output, "Cannot find player '%s' online", atcmd_player_name); - clif_displaymessage(fd, atcmd_output); - return -1; -} - -/*========================================== - * @rings by [MouseJstr] - * - * Give two players rings - *------------------------------------------ - */ -int -atcommand_rings(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct item item_tmp; - int flag; - - memset(&item_tmp, 0, sizeof(item_tmp)); - - item_tmp.nameid = 2634; - item_tmp.identify = 1; - - if ((flag = pc_additem((struct map_session_data*)sd, &item_tmp, 1))) - clif_additem((struct map_session_data*)sd, 0, 0, flag); - - item_tmp.nameid = 2635; - item_tmp.identify = 1; - if ((flag = pc_additem((struct map_session_data*)sd, &item_tmp, 1))) - clif_additem((struct map_session_data*)sd, 0, 0, flag); - - clif_displaymessage(fd, "You have rings! Give them to the lovers."); - - return 0; -} - -#ifdef DMALLOC -unsigned long dmark_; -int -atcommand_dmstart(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - dmark_ = dmalloc_mark(); - - clif_displaymessage(fd, "debug mark set"); - - return 0; -} - -int -atcommand_dmtick(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - dmalloc_log_changed ( dmark_, 1, 0, 1 ) ; - dmark_ = dmalloc_mark(); - clif_displaymessage(fd, "malloc changes logged"); - - return 0; -} -#endif - -/*========================================== - * @grind by [MouseJstr] - *------------------------------------------ - */ -int -atcommand_grind(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - int skillnum; - int inf; - char target[255]; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if(sscanf(message, "%s", target) != 1) { - clif_displaymessage(fd, "Usage: @grind <target>"); - return -1; - } - if((pl_sd=map_nick2sd(target)) == NULL) - return -1; - - for (skillnum = 1; skillnum < 500; skillnum++) { - sd->status.sp = sd->status.max_sp; - atcommand_alive(fd, sd, command, message); - - inf = skill_get_inf(skillnum); - - if ((inf == 2) || (inf == 1)) - skill_use_pos(sd, pl_sd->bl.x+5, pl_sd->bl.y+5, skillnum, 1); - else - skill_use_id(sd, pl_sd->bl.id, skillnum, 1); - } - - return 0; -} - -/*========================================== - * @grind2 by [MouseJstr] - *------------------------------------------ - */ -int -atcommand_grind2(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i, x, y, id; - - for (i = 1000; i <2000; i++) { - x = sd->bl.x + (rand() % 10 - 5); - y = sd->bl.y + (rand() % 10 - 5); - id = mob_once_spawn(sd, "this", x, y, "--ja--", i, 1, ""); - } - - return 0; -} - -/*========================================== - * @changelook by [Celest] - *------------------------------------------ - */ -int -atcommand_changelook(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i, j = 0, k = 0; - int pos[6] = { LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HEAD_BOTTOM,LOOK_WEAPON,LOOK_SHIELD,LOOK_SHOES }; - - if((i = sscanf(message, "%d %d", &j, &k)) < 1) { - clif_displaymessage(fd, "Usage: @changelook [<position>] <view id> -- [] = optional"); - clif_displaymessage(fd, "Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield"); - return -1; - } else if (i == 2) { - if (j < 1) j = 1; - else if (j > 6) j = 6; // 6 = Shoes - for beta clients only perhaps - j = pos[j - 1]; - } else if (i == 1) { // position not defined, use HEAD_TOP as default - k = j; // swap - j = LOOK_HEAD_TOP; - } - - clif_changelook(&sd->bl,j,k); - - return 0; -} - -/*========================================== - *Turns on/off AutoLoot for a specific player - *------------------------------------------ - *by Upa-Kun - */ -int -atcommand_autoloot( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - if (sd->autoloot) - { - sd->autoloot = 0; - clif_displaymessage(fd, "Autoloot is now off."); - } - else - { - sd->autoloot = 1; - clif_displaymessage(fd, "Autoloot is now on."); - } - return 0; -} - - -/*========================================== - * It is made to rain. - *------------------------------------------ - */ -int -atcommand_rain( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int effno = 0; - nullpo_retr(-1, sd); - effno = 161; - if (map[sd->bl.m].flag.rain) { - map[sd->bl.m].flag.rain=0; - clif_displaymessage(fd, "The rain has stopped."); - } else { - map[sd->bl.m].flag.rain=1; - clif_specialeffect(&sd->bl,effno,2); - clif_displaymessage(fd, "It is made to rain."); - } - return 0; -} -/*========================================== - * It is made to snow. - *------------------------------------------ - */ -int -atcommand_snow( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int effno = 0; - effno = 162; - nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.snow) { - map[sd->bl.m].flag.snow=0; - clif_displaymessage(fd, "Snow has stopped falling."); - } else { - map[sd->bl.m].flag.snow=1; - clif_specialeffect(&sd->bl,effno,2); - clif_displaymessage(fd, "It is made to snow."); - } - - return 0; -} - -/*========================================== - * Cherry tree snowstorm is made to fall. (Sakura) - *------------------------------------------ - */ -int -atcommand_sakura( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int effno = 0; - effno = 163; - nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.sakura) { - map[sd->bl.m].flag.sakura=0; - clif_displaymessage(fd, "Cherry tree leaves is made to fall."); - } else { - map[sd->bl.m].flag.sakura=1; - clif_specialeffect(&sd->bl,effno,2); - clif_displaymessage(fd, "Cherry tree leaves is made to fall."); - } - return 0; -} - -/*========================================== - * Fog hangs over. - *------------------------------------------ - */ -int -atcommand_fog( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int effno = 0; - effno = 233; - nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.fog) { - map[sd->bl.m].flag.fog=0; - clif_displaymessage(fd, "The fog has gone."); - } else { - map[sd->bl.m].flag.fog=1; - clif_specialeffect(&sd->bl,effno,2); - clif_displaymessage(fd, "Fog hangs over."); - } - - return 0; -} - -/*========================================== - * Fallen leaves fall. - *------------------------------------------ - */ -int -atcommand_leaves( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int effno = 0; - effno = 333; - nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.leaves) { - map[sd->bl.m].flag.leaves=0; - clif_displaymessage(fd, "Leaves no longer fall."); - } else { - map[sd->bl.m].flag.leaves=1; - clif_specialeffect(&sd->bl,effno,2); - clif_displaymessage(fd, "Fallen leaves fall."); - } - - return 0; -} - -/*========================================== - * Clearing Weather Effects by Dexity - *------------------------------------------ - */ -int -atcommand_clearweather( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - //int effno = 0; - nullpo_retr(-1, sd); - map[sd->bl.m].flag.rain=0; - map[sd->bl.m].flag.snow=0; - map[sd->bl.m].flag.sakura=0; - map[sd->bl.m].flag.fog=0; - map[sd->bl.m].flag.leaves=0; - //clif_specialeffect(&sd->bl,effno,2); // not required. [celest] - return 0; -} - -/*=============================================================== - * Sound Command - plays a sound for everyone! [Codemaster] - *--------------------------------------------------------------- - */ -int -atcommand_sound( - const int fd, struct map_session_data *sd, - const char *command, const char *message) -{ - char sound_file[100]; - - if(!message || !*message || sscanf(message, "%99[^\n]", sound_file) < 1) { - clif_displaymessage(fd, "Please, enter a sound filename. (usage: @sound <filename>)"); - return -1; - } - - memset(sound_file, '\0', sizeof(sound_file)); - if(sscanf(message, "%99[^\n]", sound_file) < 1) - return -1; - - if(strstr(sound_file, ".wav") == NULL) - strcat(sound_file, ".wav"); - - clif_soundeffectall(&sd->bl, sound_file,0); - - return 0; -} - -/*========================================== - * MOB Search - *------------------------------------------ - */ -int -atcommand_mobsearch( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char mob_name[100]; - int mob_id,map_id = 0; - - nullpo_retr(-1, sd); - - if (sscanf(message, "%99[^\n]", mob_name) < 0) - return -1; - - if ((mob_id = atoi(mob_name)) == 0) - mob_id = mobdb_searchname(mob_name); - if(mob_id !=-1 && (mob_id <= 1000 || mob_id >= 2000)){ - snprintf(atcmd_output, sizeof atcmd_output, "Invalid mob id %s!",mob_name); - clif_displaymessage(fd, atcmd_output); - return 0; - } - if(mob_id == atoi(mob_name) && mob_db[mob_id].jname) - strcpy(mob_name,mob_db[mob_id].jname); // --ja-- -// strcpy(mob_name,mob_db[mob_id].name); // --en-- - - map_id = sd->bl.m; - - snprintf(atcmd_output, sizeof atcmd_output, "Mob Search... %s %s", - mob_name, sd->mapname); - clif_displaymessage(fd, atcmd_output); - - map_foreachinarea(atmobsearch_sub, map_id, 0, 0, - map[map_id].xs, map[map_id].ys, BL_MOB, mob_id, fd); - - atmobsearch_sub(&sd->bl,0); // 番号リセット - - return 0; -} -/*========================================== - * ドロップアイテムの掃除 - *------------------------------------------ - */ -int -atcommand_cleanmap( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i=0; - map_foreachinarea(atcommand_cleanmap_sub,sd->bl.m, - sd->bl.x-AREA_SIZE*2,sd->bl.y-AREA_SIZE*2, - sd->bl.x+AREA_SIZE*2,sd->bl.y+AREA_SIZE*2, - BL_ITEM,sd,&i); - clif_displaymessage(fd, "All dropped items have been cleaned up."); - return 0; -} - -/*========================================== - * NPC/PETに話させる - *------------------------------------------ - */ -int -atcommand_npctalk( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char name[100],mes[100]; - struct npc_data *nd; - - if (sscanf(message, "%s %99[^\n]", name, mes) < 2) - return -1; - - if (!(nd = npc_name2id(name))) - return -1; - - clif_message(&nd->bl, mes); - return 0; -} -int -atcommand_pettalk( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char mes[100],temp[100]; - struct pet_data *pd; - - nullpo_retr(-1, sd); - - if(!sd->status.pet_id || !(pd=sd->pd)) - return -1; - - if (sscanf(message, "%99[^\n]", mes) < 1) - return -1; - - snprintf(temp, sizeof temp ,"%s : %s",sd->pet.name,mes); - clif_message(&pd->bl, temp); - - return 0; -} - -/*========================================== - * @users - * サーバー内の人数マップを表示させる - * 手抜きのため汚くなっているのは仕様です。 - *------------------------------------------ - */ - -static struct dbt *users_db; -static int users_all; - -static int atcommand_users_sub1(struct map_session_data* sd,va_list va) { - int users = (int)strdb_search(users_db,sd->mapname) + 1; - users_all++; - strdb_insert(users_db,sd->mapname,(void *)users); - return 0; -} - -static int atcommand_users_sub2(void* key,void* val,va_list va) { - char buf[256]; - struct map_session_data* sd = va_arg(va,struct map_session_data*); - sprintf(buf,"%s : %d (%d%%)",(char *)key,(int)val,(int)val * 100 / users_all); - clif_displaymessage(sd->fd,buf); - return 0; -} - -int -atcommand_users( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char buf[256]; - users_all = 0; - users_db = strdb_init(24); - clif_foreachclient(atcommand_users_sub1); - strdb_foreach(users_db,atcommand_users_sub2,sd); - sprintf(buf,"all : %d",users_all); - clif_displaymessage(fd,buf); - strdb_final(users_db,NULL); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int -atcommand_summon( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char name[100]; - int mob_id = 0; - int x = 0; - int y = 0; - int id = 0; - struct mob_data *md; - unsigned int tick=gettick(); - - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if (sscanf(message, "%99s", name) < 1) - return -1; - - if ((mob_id = atoi(name)) == 0) - mob_id = mobdb_searchname(name); - if(mob_id == 0) - return -1; - - x = sd->bl.x + (rand() % 10 - 5); - y = sd->bl.y + (rand() % 10 - 5); - - id = mob_once_spawn(sd,"this", x, y, "--ja--", mob_id, 1, ""); - if((md=(struct mob_data *)map_id2bl(id))){ - md->master_id=sd->bl.id; - md->state.special_mob_ai=1; - md->mode=mob_db[md->class_].mode|0x04; - md->deletetimer=add_timer(tick+60000,mob_timer_delete,id,0); - clif_misceffect2(&md->bl,344); - } - clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,x,y,tick); - - return 0; -} - - -/*========================================== - * @adjcmdlvl by [MouseJstr] - * - * Temp adjust the GM level required to use a GM command - * - * Used during beta testing to allow players to use GM commands - * for short periods of time - *------------------------------------------ - */ -int -atcommand_adjcmdlvl( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i, newlev; - char cmd[100]; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %s", &newlev, cmd) != 2) { - clif_displaymessage(fd, "Usage: @adjcmdlvl <lvl> <command>."); - return -1; - } - - for (i = 0; atcommand_info[i].type != AtCommand_None; i++) - if (strcmpi(cmd, atcommand_info[i].command+1) == 0) { - atcommand_info[i].level = newlev; - clif_displaymessage(fd, "@command level changed."); - return 0; - } - - clif_displaymessage(fd, "@command not found."); - return -1; -} - -/*========================================== - * @adjgmlvl by [MouseJstr] - * - * Create a temp GM - * - * Used during beta testing to allow players to use GM commands - * for short periods of time - *------------------------------------------ - */ -int -atcommand_adjgmlvl( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int newlev; - char user[100]; - struct map_session_data *pl_sd; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %[^\r\n]", &newlev, user) != 2) { - clif_displaymessage(fd, "Usage: @adjgmlvl <lvl> <user>."); - return -1; - } - - if((pl_sd=map_nick2sd((char *) user)) == NULL) - return -1; - - pc_set_gm_level(pl_sd->status.account_id, newlev); - - return 0; -} - - -/*========================================== - * @trade by [MouseJstr] - * - * Open a trade window with a remote player - * - * If I have to jump to a remote player one more time, I am - * gonna scream! - *------------------------------------------ - */ -int -atcommand_trade( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if((pl_sd=map_nick2sd((char *) message)) != NULL) { - trade_traderequest(sd, pl_sd->bl.id); - return 0; - } - return -1; -} - -/*========================================== - * @setbattleflag by [MouseJstr] - * - * set a battle_config flag without having to reboot - */ -int -atcommand_setbattleflag( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char flag[128], value[128]; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%s %s", flag, value) != 2) { - clif_displaymessage(fd, "Usage: @setbattleflag <flag> <value>."); - return -1; - } - - if (battle_set_value(flag, value) == 0) - clif_displaymessage(fd, "unknown battle_config flag"); - else - clif_displaymessage(fd, "battle_config set as requested"); - - return 0; -} - - -/*=========================== - * @unmute [Valaris] - *=========================== -*/ -int atcommand_unmute( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); - if (!message || !*message) - return -1; - - if((pl_sd=map_nick2sd((char *) message)) != NULL) { - if(pl_sd->sc_data[SC_NOCHAT].timer!=-1) { - pl_sd->status.manner = 0; // have to set to 0 first [celest] - status_change_end(&pl_sd->bl,SC_NOCHAT,-1); - clif_displaymessage(sd->fd,"Player unmuted"); - } - else - clif_displaymessage(sd->fd,"Player is not muted"); - } - - return 0; -} - -/*========================================== - * @uptime by MC Cameri - *------------------------------------------ - */ -int -atcommand_uptime( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - long seconds = 0, day = 24*60*60, hour = 60*60, - minute = 60, days = 0, hours = 0, minutes = 0; - nullpo_retr(-1, sd); - - seconds = (gettick()-ticks)/CLOCKS_PER_SEC; - days = seconds/day; - seconds -= (seconds/day>0)?(seconds/day)*day:0; - hours = seconds/hour; - seconds -= (seconds/hour>0)?(seconds/hour)*hour:0; - minutes = seconds/minute; - seconds -= (seconds/minute>0)?(seconds/minute)*minute:0; - - snprintf(atcmd_output, sizeof(atcmd_output), msg_table[245], days, hours, minutes, seconds); - - clif_displaymessage(fd,atcmd_output); - - return 0; -} - -/*========================================== - * @changesex <sex> - * => Changes one's sex. Argument sex can be - * 0 or 1, m or f, male or female. - *------------------------------------------ - */ -int -atcommand_changesex( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - chrif_char_ask_name(sd->status.account_id,sd->status.name, 5,0,0,0,0,0,0); - return 0; -} - -/*================================================ - * @mute - Mutes a player for a set amount of time - *------------------------------------------------ - */ -int atcommand_mute( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - int manner; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &manner, atcmd_player_name) < 1) { - clif_displaymessage(fd, "Usage: @mute <time> <character name>."); - return -1; - } - - if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) { - pl_sd->status.manner -= manner; - if(pl_sd->status.manner < 0) - status_change_start(&pl_sd->bl,SC_NOCHAT,0,0,0,0,0,0); - } - else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * @refresh (like @jumpto <<yourself>>) - *------------------------------------------ - */ -int atcommand_refresh( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - //pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3); - clif_refresh(sd); - return 0; -} - -/*========================================== - * @petid <part of pet name> - * => Displays a list of matching pets. - *------------------------------------------ - */ -int -atcommand_petid(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char searchtext[100]; - char temp0[100]; - char temp1[100]; - int cnt = 0, i = 0; - - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - if (sscanf(message, "%99s", searchtext) < 1) - return -1; - estr_lower(searchtext); - snprintf(temp0, sizeof(temp0), "Search results for: %s", searchtext); - clif_displaymessage(fd,temp0); - while (i < MAX_PET_DB) { - strcpy(temp1,pet_db[i].name); - strcpy(temp1, estr_lower(temp1)); - strcpy(temp0,pet_db[i].jname); - strcpy(temp0, estr_lower(temp1)); - if (strstr(temp1, searchtext) || strstr(temp0, searchtext) ) { - snprintf(temp0, sizeof(temp0), "ID: %i -- Name: %s", pet_db[i].class_, - pet_db[i].jname); - if (cnt >= 100) { // Only if there are custom pets - clif_displaymessage(fd, "Be more specific, can't send more than" - " 100 results."); - } else { - clif_displaymessage(fd, temp0); - } - cnt++; - } - i++; - } - snprintf(temp0, sizeof(temp0),"%i pets have '%s' in their name.", cnt, searchtext); - clif_displaymessage(fd, temp0); - return 0; -} - -/*========================================== - * @identify - * => GM's magnifier. - *------------------------------------------ - */ -int -atcommand_identify( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int i,num; - - nullpo_retr(-1, sd); - - for(i=num=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){ - num++; - } - } - if (num > 0) { - clif_item_identify_list(sd); - } else { - clif_displaymessage(fd,"There are no items to appraise."); - } - return 0; -} - -/*========================================== - * @gmotd (Global MOTD) - * by davidsiaw :P - *------------------------------------------ - */ -int -atcommand_gmotd( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char buf[256]; - FILE *fp; - nullpo_retr(-1, sd); - if( (fp = fopen(motd_txt, "r"))!=NULL){ - while (fgets(buf, 250, fp) != NULL){ - int i; - for( i=0; buf[i]; i++){ - if( buf[i]=='\r' || buf[i]=='\n'){ - buf[i]=0; - break; - } - } - intif_GMmessage(buf,strlen(buf)+1,8); - } - fclose(fp); - } - return 0; -} - -int atcommand_misceffect( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int effect = 0; - nullpo_retr(-1, sd); - if (!message || !*message) - return -1; - if (sscanf(message, "%d", &effect) < 1) - return -1; - clif_misceffect(&sd->bl,effect); - - return 0; -} - -int charid2sessionid(int charid) -{ - int i; - int session_id=0; - struct map_session_data *pl_sd = NULL; - - for(i=0;i<fd_max;i++){ - if(session[i] && (pl_sd= (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){ - if (pl_sd->status.char_id==charid) { session_id = i; break; } - } - } - - return session_id; -} - -int accountid2sessionid(int accountid) -{ - int i; - int session_id=0; - struct map_session_data *pl_sd = NULL; - - for(i=0;i<fd_max;i++){ - if(session[i] && (pl_sd= (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){ - if (pl_sd->status.account_id==accountid) { session_id = i; break; } - } - } - - return session_id; -} - - -/*========================================== - * Jump to a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ - -int atcommand_jumptoid( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int cid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player CID (usage: @jumptoid/@warptoid/@gotoid <char id>)."); - return -1; - } - - cid=atoi(message); - - if ((session_id=charid2sessionid(cid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - pc_setpos(sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - sprintf(atcmd_output, msg_table[4], pl_sd->status.name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[154]); // Character not found. - return -1; - } - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, cid = %d\n",session_id,cid); - - return 0; -} - -/*========================================== - * Jump to a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ - -int atcommand_jumptoid2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int aid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @jumptoid/@warptoid/@gotoid <account id>)."); - return -1; - } - - aid=atoi(message); - - if ((session_id=accountid2sessionid(aid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - pc_setpos(sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3); - sprintf(atcmd_output, msg_table[4], pl_sd->status.name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[154]); // Character not found. - return -1; - } - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, aid = %d\n",session_id,aid); - - return 0; -} - -/*========================================== - * Recall a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_recallid( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int cid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player CID (usage: @recallid <char id>)."); - return -1; - } - - cid=atoi(message); - - if ((session_id=charid2sessionid(cid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2); - sprintf(atcmd_output, msg_table[46], pl_sd->status.name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[154]); // Character not found. - return -1; - } - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, cid = %d\n",session_id,cid); - - return 0; -} - -/*========================================== - * Recall a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_recallid2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int aid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @recallid2 <account id>)."); - return -1; - } - - aid=atoi(message); - - if ((session_id=accountid2sessionid(aid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[247]); - return -1; - } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, msg_table[248]); - return -1; - } - pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2); - sprintf(atcmd_output, msg_table[46], pl_sd->status.name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[154]); // Character not found. - return -1; - } - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, aid = %d\n",session_id,aid); - - return 0; -} - -/*========================================== - * Kick a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_kickid( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int cid=0; - int session_id=0; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player CID (usage: @kickid <char id>)."); - return -1; - } - - cid=atoi(message); - - if ((session_id=charid2sessionid(cid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level - clif_GM_kick(sd, pl_sd, 1); - else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, cid = %d\n",session_id,cid); - - return 0; -} - -/*========================================== - * Kick a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_kickid2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int aid=0; - int session_id=0; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @kickid2 <account id>)."); - return -1; - } - - aid=atoi(message); - - if ((session_id=accountid2sessionid(aid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level - clif_GM_kick(sd, pl_sd, 1); - else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, aid = %d\n",session_id,aid); - - return 0; -} - -/*========================================== - * Revive a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_reviveid( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int cid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player CID (usage: @reviveid <char id>)."); - return -1; - } - - cid=atoi(message); - - if ((session_id=charid2sessionid(cid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - pl_sd->status.hp = pl_sd->status.max_hp; - pc_setstand(pl_sd); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - clif_updatestatus(pl_sd, SP_HP); - clif_updatestatus(pl_sd, SP_SP); - clif_resurrection(&pl_sd->bl, 1); - clif_displaymessage(fd, msg_table[51]); // Character revived. - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, cid = %d\n",session_id,cid); - - - return 0; -} - -/*========================================== - * Revive a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_reviveid2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int aid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @reviveid2 <account id>)."); - return -1; - } - - aid=atoi(message); - - if ((session_id=accountid2sessionid(aid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - pl_sd->status.hp = pl_sd->status.max_hp; - pc_setstand(pl_sd); - if (battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - clif_updatestatus(pl_sd, SP_HP); - clif_updatestatus(pl_sd, SP_SP); - clif_resurrection(&pl_sd->bl, 1); - clif_displaymessage(fd, msg_table[51]); // Character revived. - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, aid = %d\n",session_id,aid); - - - return 0; -} - -/*========================================== - * Kill a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_killid( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int cid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player CID (usage: @killid <char id>)."); - return -1; - } - - cid=atoi(message); - - if ((session_id=charid2sessionid(cid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(fd, msg_table[14]); // Character killed. - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, cid = %d\n",session_id,cid); - - return 0; -} - -/*========================================== - * Kill a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int atcommand_killid2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int aid=0; - int session_id=0; - struct map_session_data *pl_sd; - - memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - - if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @killid2 <account id>)."); - return -1; - } - - aid=atoi(message); - - if ((session_id=accountid2sessionid(aid))!=0) - { - if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(fd, msg_table[14]); // Character killed. - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, aid = %d\n",session_id,aid); - - return 0; -} - -/*========================================== - * Make a player killable, by PID - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int -atcommand_charkillableid( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - int cid=0; - int session_id=0; - - if (!message || (cid = atoi(message)) == 0 || !*message) - return -1; - - cid=atoi(message); - - if ((session_id=charid2sessionid(cid))!=0) - { - if((pl_sd= (struct map_session_data *) session[session_id]->session_data) == NULL) - return -1; - - pl_sd->special_state.killable = !pl_sd->special_state.killable; - - if(pl_sd->special_state.killable) - clif_displaymessage(fd, "The player is now killable"); - else - clif_displaymessage(fd, "The player is no longer killable"); - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, cid = %d\n",session_id,cid); - return 0; -} - - -/*========================================== - * Make a player killable, by PID - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------ - */ -int -atcommand_charkillableid2( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - int aid=0; - int session_id=0; - - if (!message || (aid = atoi(message)) == 0 || !*message) - return -1; - - aid=atoi(message); - - if ((session_id=accountid2sessionid(aid))!=0) - { - if((pl_sd= (struct map_session_data *) session[session_id]->session_data) == NULL) - return -1; - - pl_sd->special_state.killable = !pl_sd->special_state.killable; - - if(pl_sd->special_state.killable) - clif_displaymessage(fd, "The player is now killable"); - else - clif_displaymessage(fd, "The player is no longer killable"); - } - else - { - clif_displaymessage(fd,msg_table[3]); - } - //printf("Session_id = %d, aid = %d\n",session_id,aid); - return 0; -} - -#ifndef TXT_ONLY /* Begin SQL-Only commands */ - -/*========================================== - * Mail System commands by [Valaris] - *------------------------------------------ - */ -int atcommand_listmail( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - if(!battle_config.mail_system) - return 0; - - nullpo_retr(-1, sd); - - if(strlen(command)==12) - mail_check(sd,3); - else if(strlen(command)==9) - mail_check(sd,2); - else - mail_check(sd,1); - return 0; -} - -int atcommand_readmail( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - if(!battle_config.mail_system) - return 0; - - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(sd->fd,"You must specify a message number."); - return 0; - } - - if(strlen(command)==11) - mail_delete(sd,atoi(message)); - else - mail_read(sd,atoi(message)); - - return 0; -} - -int atcommand_sendmail( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char name[24],text[80]; - - if(!battle_config.mail_system) - return 0; - - nullpo_retr(-1, sd); - - if (!message || !*message) { - clif_displaymessage(sd->fd,"You must specify a recipient and a message."); - return 0; - } - - if ((sscanf(message, "\"%[^\"]\" %79[^\n]", name, text) < 2) && - (sscanf(message, "%23s %79[^\n]", name, text) < 2)) { - clif_displaymessage(sd->fd,"You must specify a recipient and a message."); - return 0; - } - - if(strlen(command)==17) - mail_send(sd,name,text,1); - else - mail_send(sd,name,text,0); - - return 0; -} - -/*========================================== - * Refresh online command for SQL [Valaris] - * Will refresh and check online column of - * players and set correctly. - *------------------------------------------ - */ -int atcommand_refreshonline( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - nullpo_retr(-1, sd); - - char_online_check(); - - return 0; -} - -#endif /* end sql only */ - -/*========================================== - * Show Monster DB Info v 1.0 - * originally by [Lupus] eAthena - *------------------------------------------ - */ -int atcommand_mobinfo( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - unsigned char msize[3][7] = {"Small", "Medium", "Large"}; - unsigned char mrace[12][11] = {"Formless", "Undead", "Beast", "Plant", "Insect", "Fish", "Demon", "Demi-Human", "Angel", "Dragon", "Boss", "Non-Boss"}; - unsigned char melement[11][8] = {"None", "Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead"}; - char atcmd_output2[200]; - struct item_data *item_data; - struct mob_db *mob; - int mob_id; - int i, j; - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - memset(atcmd_output2, '\0', sizeof(atcmd_output2)); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a Monster/NPC name/id (usage: @mobinfo <monster_name_or_monster_ID>)."); - return -1; - } - - // If monster identifier/name argument is a name - if ((mob_id = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = mobdb_checkid(atoi(message)); - - if (mob_id == 0) { - clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name. - return -1; - } - - mob = &mob_db[mob_id]; - - // stats - if (mob->mexp) - sprintf(atcmd_output, "Monster (MVP): '%s'/'%s' (%d)", mob->name, mob->jname, mob_id); - else - sprintf(atcmd_output, "Monster: '%s'/'%s' (%d)", mob->name, mob->jname, mob_id); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, " Level:%d HP:%d SP:%d Base EXP:%d Job EXP:%d", mob->lv, mob->max_hp, mob->max_sp, mob->base_exp, mob->job_exp); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, " DEF:%d MDEF:%d STR:%d AGI:%d VIT:%d INT:%d DEX:%d LUK:%d", mob->def, mob->mdef, mob->str, mob->agi, mob->vit, mob->int_, mob->dex, mob->luk); - clif_displaymessage(fd, atcmd_output); - if (mob->element < 20) { - //Element - None, Level 0 - i = 0; - j = 0; - } else { - i = mob->element % 20 + 1; - j = mob->element / 20; - } - sprintf(atcmd_output, " ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)", mob->atk1, mob->atk2, mob->range, mob->range2 , mob->range3, msize[mob->size], mrace[mob->race], melement[i], j); - clif_displaymessage(fd, atcmd_output); - // drops - clif_displaymessage(fd, " Drops:"); - strcpy(atcmd_output, " "); - j = 0; - for (i = 0; i < 10; i++) { - if (mob->dropitem[i].nameid <= 0 || (item_data = itemdb_search(mob->dropitem[i].nameid)) == NULL) - continue; - if (mob->dropitem[i].p > 0) { - sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->dropitem[i].p / 100); - strcat(atcmd_output, atcmd_output2); - if (++j % 3 == 0) { - clif_displaymessage(fd, atcmd_output); - strcpy(atcmd_output, " "); - } - } - } - if (j == 0) - clif_displaymessage(fd, "This monster has no drop."); - else if (j % 3 != 0) - clif_displaymessage(fd, atcmd_output); - // mvp - if (mob->mexp) { - sprintf(atcmd_output, " MVP Bonus EXP:%d %02.02f%%", mob->mexp, (float)mob->mexpper / 100); - clif_displaymessage(fd, atcmd_output); - strcpy(atcmd_output, " MVP Items:"); - j = 0; - for (i = 0; i < 3; i++) { - if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_search(mob->mvpitem[i].nameid)) == NULL) - continue; - if (mob->mvpitem[i].p > 0) { - j++; - if (j == 1) - sprintf(atcmd_output2, " %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100); - else - sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100); - strcat(atcmd_output, atcmd_output2); - } - } - if (j == 0) - clif_displaymessage(fd, "This monster has no MVP drop."); - else - clif_displaymessage(fd, atcmd_output); - } - - return 0; -} - -/*========================================== - * @adopt by [Veider] - * - * adopt a novice - *------------------------------------------ - */ -int -atcommand_adopt(const int fd, struct map_session_data* sd, -const char* command, const char* message) -{ - struct map_session_data *pl_sd1 = NULL; - struct map_session_data *pl_sd2 = NULL; - struct map_session_data *pl_sd3 = NULL; - char player1[255], player2[255], player3[255]; - - nullpo_retr(-1, sd); - - if (!message || !*message) - return -1; - - if (sscanf(message, "%[^,],%[^,],%[^\r\n]", player1, player2, player3) != 3) { - clif_displaymessage(fd, "usage: @adopt <player1> <player2> <player3>."); - return -1; - } - - printf("Adopting: --%s--%s--%s--\n",player1,player2,player3); - - if((pl_sd1=map_nick2sd((char *) player1)) == NULL) { - sprintf(player2, "Cannot find player %s online", player1); - clif_displaymessage(fd, player2); - return -1; - } - - if((pl_sd2=map_nick2sd((char *) player2)) == NULL) { - sprintf(player1, "Cannot find player %s online", player2); - clif_displaymessage(fd, player1); - return -1; - } - - if((pl_sd3=map_nick2sd((char *) player3)) == NULL) { - sprintf(player1, "Cannot find player %s online", player3); - clif_displaymessage(fd, player1); - return -1; - } - - if((pl_sd1->status.base_level < 70) || (pl_sd2->status.base_level < 70)){ - clif_displaymessage(fd, "They are too young to be parents!"); - return -1; - } - - if (pc_adoption(pl_sd1, pl_sd2, pl_sd3) == 0) { - clif_displaymessage(fd, "They are family.. wish them luck"); - return 0; - } - else - return -1; -} - diff --git a/src/map/atcommand.h b/src/map/atcommand.h deleted file mode 100644 index 1160dccb7..000000000 --- a/src/map/atcommand.h +++ /dev/null @@ -1,292 +0,0 @@ -// $Id: atcommand.h 148 2004-09-30 14:05:37Z MouseJstr $ -#ifndef _ATCOMMAND_H_ -#define _ATCOMMAND_H_ - -enum AtCommandType { - AtCommand_None = -1, - AtCommand_Broadcast = 0, - AtCommand_LocalBroadcast, - AtCommand_MapMove, - AtCommand_ResetState, - AtCommand_RuraP, - AtCommand_Rura, - AtCommand_Warp, - AtCommand_Where, - AtCommand_JumpTo, - AtCommand_Jump, - AtCommand_Who, - AtCommand_Who2, - AtCommand_Who3, - AtCommand_WhoMap, - AtCommand_WhoMap2, - AtCommand_WhoMap3, - AtCommand_WhoGM, - AtCommand_Save, - AtCommand_Load, - AtCommand_Speed, - AtCommand_Storage, - AtCommand_GuildStorage, - AtCommand_Option, - AtCommand_Hide, - AtCommand_JobChange, - AtCommand_JobChange2, - AtCommand_JobChange3, - AtCommand_Die, - AtCommand_Kill, - AtCommand_Alive, - AtCommand_Kami, - AtCommand_KamiB, - AtCommand_Heal, - AtCommand_Item, - AtCommand_Item2, - AtCommand_ItemReset, - AtCommand_ItemCheck, - AtCommand_BaseLevelUp, - AtCommand_JobLevelUp, - AtCommand_H, - AtCommand_Help, - AtCommand_GM, - AtCommand_PvPOff, - AtCommand_PvPOn, - AtCommand_GvGOff, - AtCommand_GvGOn, - AtCommand_Model, - AtCommand_Go, - AtCommand_Spawn, - AtCommand_Monster, - AtCommand_MonsterSmall, - AtCommand_MonsterBig, - AtCommand_KillMonster, - AtCommand_KillMonster2, - AtCommand_Refine, - AtCommand_Produce, - AtCommand_Memo, - AtCommand_GAT, - AtCommand_Packet, - AtCommand_StatusPoint, - AtCommand_SkillPoint, - AtCommand_Zeny, - AtCommand_Param, - AtCommand_Strength, - AtCommand_Agility, - AtCommand_Vitality, - AtCommand_Intelligence, - AtCommand_Dexterity, - AtCommand_Luck, - AtCommand_GuildLevelUp, - AtCommand_MakeEgg, - AtCommand_PetFriendly, - AtCommand_PetHungry, - AtCommand_PetRename, -// AtCommand_CharPetRename, // by Yor, Now #petrename - AtCommand_Recall, -// AtCommand_CharacterJob, // Now #jobchange - AtCommand_Revive, -// AtCommand_CharacterStats, // Now #stats - AtCommand_CharacterStatsAll, -// AtCommand_CharacterOption, // Now #option -// AtCommand_CharacterSave, // Now #save - AtCommand_CharacterLoad, - AtCommand_Night, - AtCommand_Day, - AtCommand_Doom, - AtCommand_DoomMap, - AtCommand_Raise, - AtCommand_RaiseMap, - AtCommand_CharacterBaseLevel, - AtCommand_CharacterJobLevel, - AtCommand_Kick, - AtCommand_KickAll, - AtCommand_AllSkill, - AtCommand_QuestSkill, - AtCommand_CharQuestSkill, - AtCommand_LostSkill, - AtCommand_CharLostSkill, - AtCommand_SpiritBall, - AtCommand_Party, - AtCommand_Guild, - AtCommand_AgitStart, - AtCommand_AgitEnd, - AtCommand_MapExit, - AtCommand_IDSearch, - AtCommand_CharSkReset, - AtCommand_CharStReset, - //by chbrules - AtCommand_CharModel, - AtCommand_CharSKPoint, - AtCommand_CharSTPoint, -// AtCommand_CharZeny, //now #zeny - AtCommand_RecallAll, - AtCommand_ReloadItemDB, - AtCommand_ReloadMobDB, - AtCommand_ReloadSkillDB, - AtCommand_ReloadScript, - AtCommand_ReloadGMDB, - AtCommand_ReloadAtcommand, - AtCommand_ReloadBattleConf, - AtCommand_ReloadStatusDB, - AtCommand_ReloadPcDB, - AtCommand_MapInfo, - AtCommand_Dye, - AtCommand_Hstyle, - AtCommand_Hcolor, - AtCommand_StatAll, - AtCommand_CharChangeSex, // by Yor - AtCommand_CharBlock, // by Yor - AtCommand_CharBan, // by Yor - AtCommand_CharUnBlock, // by Yor - AtCommand_CharUnBan, // by Yor - AtCommand_MountPeco, // by Valaris - AtCommand_CharMountPeco, // by Yor - AtCommand_GuildSpy, // [Syrus22] - AtCommand_PartySpy, // [Syrus22] - AtCommand_RepairAll, // [Valaris] - AtCommand_GuildRecall, // by Yor - AtCommand_PartyRecall, // by Yor - AtCommand_Nuke, // [Valaris] - AtCommand_Enablenpc, - AtCommand_Hidenpc, - AtCommand_Disablenpc, - AtCommand_ServerTime, // by Yor - AtCommand_CharDelItem, // by Yor - AtCommand_Jail, // by Yor - AtCommand_UnJail, // by Yor - AtCommand_Disguise, // [Valaris] - AtCommand_UnDisguise, // by Yor - AtCommand_CharDisguise, // Kalaspuff - AtCommand_CharUnDisguise, // Kalaspuff - AtCommand_EMail, // by Yor - AtCommand_Hatch, - AtCommand_Effect, // by Apple -// AtCommand_Char_Item_List, // by Yor, now #itemlist -// AtCommand_Char_Storage_List, // by Yor, now #storagelist - AtCommand_Char_Cart_List, // by Yor - AtCommand_AddWarp, // by MouseJstr - AtCommand_Follow, // by MouseJstr - AtCommand_SkillOn, // by MouseJstr - AtCommand_SkillOff, // by MouseJstr - AtCommand_Killer, // by MouseJstr - AtCommand_NpcMove, // by MouseJstr - AtCommand_Killable, // by MouseJstr - AtCommand_CharKillable, // by MouseJstr -// AtCommand_Chareffect, // by MouseJstr, now #effect - AtCommand_Dropall, // by MouseJstr - AtCommand_Chardropall, // by MouseJstr - AtCommand_Storeall, // by MouseJstr - AtCommand_Charstoreall, // by MouseJstr - AtCommand_Skillid, // by MouseJstr - AtCommand_Useskill, // by MouseJstr - AtCommand_Summon, - AtCommand_Rain, - AtCommand_Snow, - AtCommand_Sakura, - AtCommand_Fog, - AtCommand_Leaves, - AtCommand_AdjGmLvl, // MouseJstr - AtCommand_AdjCmdLvl, // MouseJstr - AtCommand_Trade, // MouseJstr - AtCommand_Send, - AtCommand_SetBattleFlag, - AtCommand_UnMute, - AtCommand_Clearweather, // by Dexity - AtCommand_UpTime, // by MC Cameri - AtCommand_ChangeSex, // by MC Cameri - AtCommand_Mute, // [celest] - AtCommand_WhoZeny, // [Valaris] <-- LOL...(MC Cameri) worth it. - AtCommand_HappyHappyJoyJoy, // [Valaris] - AtCommand_Refresh, // by MC Cameri - AtCommand_PetId, // by MC Cameri - AtCommand_Identify, // by MC Cameri - AtCommand_Gmotd, // Added by MC Cameri, created by davidsiaw - AtCommand_MiscEffect, // by MC Cameri - AtCommand_MobSearch, - AtCommand_CleanMap, - AtCommand_NpcTalk, - AtCommand_PetTalk, - AtCommand_Users, - - // SQL-only commands start -#ifndef TXT_ONLY - AtCommand_CheckMail, // [Valaris] - AtCommand_ListMail, // [Valaris] - AtCommand_ListNewMail, // [Valaris] - AtCommand_ReadMail, // [Valaris] - AtCommand_SendMail, // [Valaris] - AtCommand_DeleteMail, // [Valaris] - AtCommand_SendPriorityMail, // [Valaris] -// AtCommand_Sound, // [Valaris] - AtCommand_RefreshOnline, // [Valaris] - // SQL-only commands end -#endif - AtCommand_SkillTree, // by MouseJstr - AtCommand_Marry, // by MouseJstr - AtCommand_Divorce, // by MouseJstr - AtCommand_Rings, // by MouseJstr - AtCommand_Grind, // by MouseJstr - AtCommand_Grind2, // by MouseJstr - - AtCommand_DMStart, // by MouseJstr - AtCommand_DMTick, // by MouseJstr - - AtCommand_JumpToId, // by Dino9021 - AtCommand_JumpToId2, // by Dino9021 - AtCommand_RecallId, // by Dino9021 - AtCommand_RecallId2, // by Dino9021 - AtCommand_KickId, // by Dino9021 - AtCommand_KickId2, // by Dino9021 - AtCommand_ReviveId, // by Dino9021 - AtCommand_ReviveId2, // by Dino9021 - AtCommand_KillId, // by Dino9021 - AtCommand_KillId2, // by Dino9021 - AtCommand_CharKillableId, // by Dino9021 - AtCommand_CharKillableId2, // by Dino9021 - AtCommand_Sound, - AtCommand_UndisguiseAll, - AtCommand_DisguiseAll, - AtCommand_ChangeLook, - AtCommand_AutoLoot, //by Upa-Kun - AtCommand_MobInfo, //by Lupus - AtCommand_Adopt, // by Veider - - // end - AtCommand_Unknown, - AtCommand_MAX -}; - -typedef enum AtCommandType AtCommandType; - -typedef struct AtCommandInfo { - AtCommandType type; - const char* command; - int level; - int (*proc)(const int, struct map_session_data*, - const char* command, const char* message); -} AtCommandInfo; - -AtCommandType -is_atcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl); - -AtCommandType atcommand( - struct map_session_data *sd, - const int level, const char* message, AtCommandInfo* info); -int get_atcommand_level(const AtCommandType type); - -char * msg_txt(int msg_number); // [Yor] - -int atcommand_item(const int fd, struct map_session_data* sd,const char* command, const char* message); // [Valaris] -int atcommand_rura(const int fd, struct map_session_data* sd,const char* command, const char* message); // [Yor] -int atcommand_spawn(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Valaris] -int atcommand_jumpto(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Yor] -int atcommand_recall(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Yor] - -int atcommand_config_read(const char *cfgName); -int msg_config_read(const char *cfgName); -void do_final_msg(); - -char *estr_lower(char *str); - -char * job_name(int class_); -int e_mail_check(char *email); - -#endif - diff --git a/src/map/battle.c b/src/map/battle.c deleted file mode 100644 index 077e5fc9b..000000000 --- a/src/map/battle.c +++ /dev/null @@ -1,4629 +0,0 @@ -// $Id: battle.c,v 1.10 2004/09/29 21:08:17 Akitasha Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "battle.h" - -#include "timer.h" -#include "nullpo.h" -#include "malloc.h" - -#include "map.h" -#include "pc.h" -#include "status.h" -#include "skill.h" -#include "mob.h" -#include "itemdb.h" -#include "clif.h" -#include "pet.h" -#include "guild.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -int attr_fix_table[4][10][10]; - -struct Battle_Config battle_config; - -/*========================================== - * 二点間の距離を返す - * 戻りは整数で0以上 - *------------------------------------------ - */ -static int distance(int x0,int y0,int x1,int y1) -{ - int dx,dy; - - dx=abs(x0-x1); - dy=abs(y0-y1); - return dx>dy ? dx : dy; -} - -/*========================================== - * 自分をロックしている対象の数を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int battle_counttargeted(struct block_list *bl,struct block_list *src,int target_lv) -{ - nullpo_retr(0, bl); - if(bl->type == BL_PC) - return pc_counttargeted((struct map_session_data *)bl,src,target_lv); - else if(bl->type == BL_MOB) - return mob_counttargeted((struct mob_data *)bl,src,target_lv); - return 0; -} - -// ダメージの遅延 -struct battle_delay_damage_ { - struct block_list *src; - int target; - int damage; - int flag; -}; -int battle_delay_damage_sub(int tid,unsigned int tick,int id,int data) -{ - struct battle_delay_damage_ *dat=(struct battle_delay_damage_ *)data; - struct block_list *target=map_id2bl(dat->target); - if( dat && map_id2bl(id)==dat->src && target && target->prev!=NULL) - battle_damage(dat->src,target,dat->damage,dat->flag); - aFree(dat); - return 0; -} -int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_list *target,int damage,int flag) -{ - struct battle_delay_damage_ *dat = (struct battle_delay_damage_*)aCalloc(1,sizeof(struct battle_delay_damage_)); - - nullpo_retr(0, src); - nullpo_retr(0, target); - - - dat->src=src; - dat->target=target->id; - dat->damage=damage; - dat->flag=flag; - add_timer(tick,battle_delay_damage_sub,src->id,(int)dat); - return 0; -} - -// 実際にHPを操作 -int battle_damage(struct block_list *bl,struct block_list *target,int damage,int flag) -{ - struct map_session_data *sd=NULL; - struct status_change *sc_data=status_get_sc_data(target); - short *sc_count; - int i; - - nullpo_retr(0, target); //blはNULLで呼ばれることがあるので他でチェック - - if(damage==0 || target->type == BL_PET) - return 0; - - if(target->prev == NULL) - return 0; - - if(bl) { - if(bl->prev==NULL) - return 0; - - if(bl->type==BL_PC) - sd=(struct map_session_data *)bl; - } - - if(damage<0) - return battle_heal(bl,target,-damage,0,flag); - - if(!flag && (sc_count=status_get_sc_count(target))!=NULL && *sc_count>0){ - // 凍結、石化、睡眠を消去 - if(sc_data[SC_FREEZE].timer!=-1) - status_change_end(target,SC_FREEZE,-1); - if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) - status_change_end(target,SC_STONE,-1); - if(sc_data[SC_SLEEP].timer!=-1) - status_change_end(target,SC_SLEEP,-1); - } - - if(target->type==BL_MOB){ // MOB - struct mob_data *md=(struct mob_data *)target; - if(md && md->skilltimer!=-1 && md->state.skillcastcancel) // 詠唱妨害 - skill_castcancel(target,0); - return mob_damage(bl,md,damage,0); - } - else if(target->type==BL_PC){ // PC - - struct map_session_data *tsd=(struct map_session_data *)target; - - if(tsd && tsd->sc_data && tsd->sc_data[SC_DEVOTION].val1){ // ディボーションをかけられている - struct map_session_data *md = map_id2sd(tsd->sc_data[SC_DEVOTION].val1); - if(md && skill_devotion3(&md->bl,target->id)){ - skill_devotion(md,target->id); - } - else if(md && bl) - for(i=0;i<5;i++) - if(md->dev.val1[i] == target->id){ - clif_damage(bl,&md->bl, gettick(), 0, 0, - damage, 0 , 0, 0); - pc_damage(&md->bl,md,damage); - - return 0; - } - } - - if(tsd && tsd->skilltimer!=-1){ // 詠唱妨害 - // フェンカードや妨害されないスキルかの検査 - if( (!tsd->special_state.no_castcancel || map[bl->m].flag.gvg) && tsd->state.skillcastcancel && - !tsd->special_state.no_castcancel2) - skill_castcancel(target,0); - } - - return pc_damage(bl,tsd,damage); - - } - else if(target->type==BL_SKILL) - return skill_unit_ondamaged((struct skill_unit *)target,bl,damage,gettick()); - return 0; -} -int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp,int flag) -{ - nullpo_retr(0, target); //blはNULLで呼ばれることがあるので他でチェック - - if(target->type == BL_PET) - return 0; - if( target->type ==BL_PC && pc_isdead((struct map_session_data *)target) ) - return 0; - if(hp==0 && sp==0) - return 0; - - if(hp<0) - return battle_damage(bl,target,-hp,flag); - - if(target->type==BL_MOB) - return mob_heal((struct mob_data *)target,hp); - else if(target->type==BL_PC) - return pc_heal((struct map_session_data *)target,hp,sp); - return 0; -} - -// 攻撃停止 -int battle_stopattack(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB) - return mob_stopattack((struct mob_data*)bl); - else if(bl->type==BL_PC) - return pc_stopattack((struct map_session_data*)bl); - else if(bl->type==BL_PET) - return pet_stopattack((struct pet_data*)bl); - return 0; -} -// 移動停止 -int battle_stopwalking(struct block_list *bl,int type) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB) - return mob_stop_walking((struct mob_data*)bl,type); - else if(bl->type==BL_PC) - return pc_stop_walking((struct map_session_data*)bl,type); - else if(bl->type==BL_PET) - return pet_stop_walking((struct pet_data*)bl,type); - return 0; -} - - -/*========================================== - * ダメージの属性修正 - *------------------------------------------ - */ -int battle_attr_fix(int damage,int atk_elem,int def_elem) -{ - int def_type= def_elem%10, def_lv=def_elem/10/2; - - if( atk_elem<0 || atk_elem>9 || def_type<0 || def_type>9 || - def_lv<1 || def_lv>4){ // 属 性値がおかしいのでとりあえずそのまま返す - if(battle_config.error_log) - printf("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv); - return damage; - } - - return damage*attr_fix_table[def_lv-1][atk_elem][def_type]/100; -} - - -/*========================================== - * ダメージ最終計算 - *------------------------------------------ - */ -int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag) -{ - struct map_session_data *sd=NULL; - struct mob_data *md=NULL; - struct status_change *sc_data,*sc; - short *sc_count; - int class_; - - nullpo_retr(0, bl); - - class_ = status_get_class(bl); - if(bl->type==BL_MOB) md=(struct mob_data *)bl; - else sd=(struct map_session_data *)bl; - - sc_data=status_get_sc_data(bl); - sc_count=status_get_sc_count(bl); - - if(sc_count!=NULL && *sc_count>0){ - if (sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON && - flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK) { - // セーフティウォール - struct skill_unit *unit; - unit = (struct skill_unit *)sc_data[SC_SAFETYWALL].val2; - if (unit) { - if (unit->group && (--unit->group->val2)<=0) - skill_delunit(unit); - damage=0; - } else { - status_change_end(bl,SC_SAFETYWALL,-1); - } - } - if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 && - ((flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK) || - (flag&BF_MISC && (skill_num == HT_BLITZBEAT || skill_num == SN_FALCONASSAULT)) || - (flag&BF_MAGIC && skill_num == ASC_BREAKER))){ // [DracoRPG] - // ニューマ - damage=0; - } - - if(sc_data[SC_ROKISWEIL].timer!=-1 && damage>0 && - flag&BF_MAGIC ){ - // ニューマ - damage=0; - } - - if(sc_data[SC_AETERNA].timer!=-1 && damage>0){ // レックスエーテルナ - damage<<=1; - status_change_end( bl,SC_AETERNA,-1 ); - } - - //属性場のダメージ増加 - if(sc_data[SC_VOLCANO].timer!=-1){ // ボルケーノ - if(flag&BF_SKILL && skill_get_pl(skill_num)==3) - //damage += damage*sc_data[SC_VOLCANO].val4/100; - damage += damage * enchant_eff[sc_data[SC_VOLCANO].val1-1] /100; - else if(!flag&BF_SKILL && status_get_attack_element(bl)==3) - //damage += damage*sc_data[SC_VOLCANO].val4/100; - damage += damage * enchant_eff[sc_data[SC_VOLCANO].val1-1] /100; - } - - if(sc_data[SC_VIOLENTGALE].timer!=-1){ // バイオレントゲイル - if(flag&BF_SKILL && skill_get_pl(skill_num)==4) - //damage += damage*sc_data[SC_VIOLENTGALE].val4/100; - damage += damage * enchant_eff[sc_data[SC_VIOLENTGALE].val1-1] /100; - else if(!flag&BF_SKILL && status_get_attack_element(bl)==4) - //damage += damage*sc_data[SC_VIOLENTGALE].val4/100; - damage += damage * enchant_eff[sc_data[SC_VIOLENTGALE].val1-1] /100; - } - - if(sc_data[SC_DELUGE].timer!=-1){ // デリュージ - if(flag&BF_SKILL && skill_get_pl(skill_num)==1) - //damage += damage*sc_data[SC_DELUGE].val4/100; - damage += damage * enchant_eff[sc_data[SC_DELUGE].val1-1] /100; - else if(!flag&BF_SKILL && status_get_attack_element(bl)==1) - //damage += damage*sc_data[SC_DELUGE].val4/100; - damage += damage * enchant_eff[sc_data[SC_DELUGE].val1-1] /100; - } - - if(sc_data[SC_ENERGYCOAT].timer!=-1 && damage>0 && flag&BF_WEAPON){ // エナジーコート - if(sd){ - if(sd->status.sp>0){ - int per = sd->status.sp * 5 / (sd->status.max_sp + 1); - sd->status.sp -= sd->status.sp * (per * 5 + 10) / 1000; - if( sd->status.sp < 0 ) sd->status.sp = 0; - damage -= damage * ((per+1) * 6) / 100; - clif_updatestatus(sd,SP_SP); - } - if(sd->status.sp<=0) - status_change_end( bl,SC_ENERGYCOAT,-1 ); - } - else - damage -= damage * (sc_data[SC_ENERGYCOAT].val1 * 6) / 100; - } - - if(sc_data[SC_KYRIE].timer!=-1 && damage > 0){ // キリエエレイソン - sc=&sc_data[SC_KYRIE]; - sc->val2-=damage; - if(flag&BF_WEAPON){ - if(sc->val2>=0) damage=0; - else damage=-sc->val2; - } - if((--sc->val3)<=0 || (sc->val2<=0) || skill_num == AL_HOLYLIGHT) - status_change_end(bl, SC_KYRIE, -1); - } - - if(sc_data[SC_BASILICA].timer!=-1 && damage > 0){ - // ニューマ - damage=0; - } - if(sc_data[SC_LANDPROTECTOR].timer!=-1 && damage>0 && flag&BF_MAGIC){ - // ニューマ - damage=0; - } - - if(sc_data[SC_AUTOGUARD].timer != -1 && damage > 0 && flag&BF_WEAPON) { - if(rand()%100 < sc_data[SC_AUTOGUARD].val2) { - int delay; - - damage = 0; - clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sc_data[SC_AUTOGUARD].val1,1); - // different delay depending on skill level [celest] - if (sc_data[SC_AUTOGUARD].val1 <= 5) - delay = 300; - else if (sc_data[SC_AUTOGUARD].val1 > 5 && sc_data[SC_AUTOGUARD].val1 <= 9) - delay = 200; - else - delay = 100; - if(sd) - sd->canmove_tick = gettick() + delay; - else if(md) - md->canmove_tick = gettick() + delay; - } - } -// -- moonsoul (chance to block attacks with new Lord Knight skill parrying) -// - if(sc_data[SC_PARRYING].timer != -1 && damage > 0 && flag&BF_WEAPON) { - if(rand()%100 < sc_data[SC_PARRYING].val2) { - damage = 0; - clif_skill_nodamage(bl,bl,LK_PARRYING,sc_data[SC_PARRYING].val1,1); - } - } - // リジェクトソード - if(sc_data[SC_REJECTSWORD].timer!=-1 && damage > 0 && flag&BF_WEAPON && - // Fixed the condition check [Aalye] - (src->type==BL_MOB || (src->type==BL_PC && (((struct map_session_data *)src)->status.weapon == 1 || - ((struct map_session_data *)src)->status.weapon == 2 || - ((struct map_session_data *)src)->status.weapon == 3)))){ - if(rand()%100 < (15*sc_data[SC_REJECTSWORD].val1)){ //反射確率は15*Lv - damage = damage*50/100; - clif_damage(bl,src,gettick(),0,0,damage,0,0,0); - battle_damage(bl,src,damage,0); - //ダメージを与えたのは良いんだが、ここからどうして表示するんだかわかんねぇ - //エフェクトもこれでいいのかわかんねぇ - clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sc_data[SC_REJECTSWORD].val1,1); - if((--sc_data[SC_REJECTSWORD].val2)<=0) - status_change_end(bl, SC_REJECTSWORD, -1); - } - } - if(sc_data[SC_SPIDERWEB].timer!=-1 && damage > 0) // [Celest] - if ((flag&BF_SKILL && skill_get_pl(skill_num)==3) || - (!flag&BF_SKILL && status_get_attack_element(src)==3)) { - damage<<=1; - status_change_end(bl, SC_SPIDERWEB, -1); - } - - if(sc_data[SC_FOGWALL].timer != -1 && flag&BF_MAGIC) - if(rand()%100 < 75) - damage = 0; - } - - if(class_ == 1288 || class_ == 1287 || class_ == 1286 || class_ == 1285) { -// if(class_ == 1288) { - if(class_ == 1288 && (flag&BF_SKILL || skill_num == ASC_BREAKER || skill_num == PA_SACRIFICE)) - damage=0; - if(src->type == BL_PC) { - struct guild *g=guild_search(((struct map_session_data *)src)->status.guild_id); - struct guild_castle *gc=guild_mapname2gc(map[bl->m].name); - if(!((struct map_session_data *)src)->status.guild_id) - damage=0; - if(gc && agit_flag==0 && class_ != 1288) // guardians cannot be damaged during non-woe [Valaris] - damage=0; // end woe check [Valaris] - if(g == NULL) - damage=0;//ギルド未加入ならダメージ無し - else if((gc != NULL) && guild_isallied(g, gc)) - damage=0;//自占領ギルドのエンペならダメージ無し - else if(g && guild_checkskill(g,GD_APPROVAL) <= 0) - damage=0;//正規ギルド承認がないとダメージ無し - else if (battle_config.guild_max_castles != 0 && guild_checkcastles(g)>=battle_config.guild_max_castles) - damage = 0; // [MouseJstr] - else if (g && gc && guild_check_alliance(gc->guild_id, g->guild_id, 0) == 1) - return 0; - } - else damage = 0; - } - - if(map[bl->m].flag.gvg && damage > 0) { //GvG - if(bl->type == BL_MOB){ //defenseがあればダメージが減るらしい? - struct guild_castle *gc=guild_mapname2gc(map[bl->m].name); - if (gc) damage -= damage*(gc->defense/100)*(battle_config.castle_defense_rate/100); - } - if(flag&BF_WEAPON) { - if(flag&BF_SHORT) - damage=damage*battle_config.gvg_short_damage_rate/100; - if(flag&BF_LONG) - damage=damage*battle_config.gvg_long_damage_rate/100; - } - if(flag&BF_MAGIC) - damage = damage*battle_config.gvg_magic_damage_rate/100; - if(flag&BF_MISC) - damage=damage*battle_config.gvg_misc_damage_rate/100; - if(damage < 1) damage = 1; - } - - if(battle_config.skill_min_damage || flag&BF_MISC) { - if(div_ < 255) { - if(damage > 0 && damage < div_) - damage = div_; - } - else if(damage > 0 && damage < 3) - damage = 3; - } - - if( md!=NULL && md->hp>0 && damage > 0 ) // 反撃などのMOBスキル判定 - mobskill_event(md,flag); - - return damage; -} - -/*========================================== - * HP/SP吸収の計算 - *------------------------------------------ - */ -int battle_calc_drain(int damage, int rate, int per, int val) -{ - int diff = 0; - - if (damage <= 0 || rate <= 0) - return 0; - - if (per && rand()%100 < rate) { - diff = (damage * per) / 100; - if (diff == 0) { - if (per > 0) - diff = 1; - else - diff = -1; - } - } - - if (val && rand()%100 < rate) { - diff += val; - } - return diff; -} - -/*========================================== - * 修練ダメージ - *------------------------------------------ - */ -int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type) -{ - int damage,skill; - int race=status_get_race(target); - int weapon; - damage = 0; - - nullpo_retr(0, sd); - - // デーモンベイン(+3 〜 +30) vs 不死 or 悪魔 (死人は含めない?) - if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,status_get_elem_type(target)) || race==6) ) - damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn - //damage += (skill * 3); - - // ビーストベイン(+4 〜 +40) vs 動物 or 昆虫 - if((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (race==2 || race==4) ) - damage += (skill * 4); - - if(type == 0) - weapon = sd->weapontype1; - else - weapon = sd->weapontype2; - switch(weapon) - { - case 0x01: // 短剣 Knife - case 0x02: // 1HS - { - // 剣修練(+4 〜 +40) 片手剣 短剣含む - if((skill = pc_checkskill(sd,SM_SWORD)) > 0) { - damage += (skill * 4); - } - break; - } - case 0x03: // 2HS - { - // 両手剣修練(+4 〜 +40) 両手剣 - if((skill = pc_checkskill(sd,SM_TWOHAND)) > 0) { - damage += (skill * 4); - } - break; - } - case 0x04: // 1HL - case 0x05: // 2HL - { - // 槍修練(+4 〜 +40,+5 〜 +50) 槍 - if((skill = pc_checkskill(sd,KN_SPEARMASTERY)) > 0) { - if(!pc_isriding(sd)) - damage += (skill * 4); // ペコに乗ってない - else - damage += (skill * 5); // ペコに乗ってる - } - break; - } - case 0x06: // 片手斧 - case 0x07: // Axe by Tato - { - if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0) { - damage += (skill * 3); - } - break; - } - case 0x08: // メイス - { - // メイス修練(+3 〜 +30) メイス - if((skill = pc_checkskill(sd,PR_MACEMASTERY)) > 0) { - damage += (skill * 3); - } - break; - } - case 0x09: // なし? - break; - case 0x0a: // 杖 - break; - case 0x0b: // 弓 - break; - case 0x00: // 素手 Bare Hands - case 0x0c: // Knuckles - { - // 鉄拳(+3 〜 +30) 素手,ナックル - if((skill = pc_checkskill(sd,MO_IRONHAND)) > 0) { - damage += (skill * 3); - } - break; - } - case 0x0d: // Musical Instrument - { - // 楽器の練習(+3 〜 +30) 楽器 - if((skill = pc_checkskill(sd,BA_MUSICALLESSON)) > 0) { - damage += (skill * 3); - } - break; - } - case 0x0e: // Dance Mastery - { - // Dance Lesson Skill Effect(+3 damage for every lvl = +30) 鞭 - if((skill = pc_checkskill(sd,DC_DANCINGLESSON)) > 0) { - damage += (skill * 3); - } - break; - } - case 0x0f: // Book - { - // Advance Book Skill Effect(+3 damage for every lvl = +30) { - if((skill = pc_checkskill(sd,SA_ADVANCEDBOOK)) > 0) { - damage += (skill * 3); - } - break; - } - case 0x10: // Katars - { - // カタール修練(+3 〜 +30) カタール - if((skill = pc_checkskill(sd,AS_KATAR)) > 0) { - //ソニックブロー時は別処理(1撃に付き1/8適応) - damage += (skill * 3); - } - break; - } - } - damage = dmg + damage; - return (damage); -} - -static struct Damage battle_calc_pet_weapon_attack( - struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int wflag) -{ - struct pet_data *pd = (struct pet_data *)src; - struct mob_data *tmd=NULL; - int hitrate,flee,cri = 0,atkmin,atkmax; - int luk,target_count = 1; - int def1 = status_get_def(target); - int def2 = status_get_def2(target); - int t_vit = status_get_vit(target); - struct Damage wd; - int damage,damage2=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv); - int flag,dmg_lv=0; - int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0; - struct status_change *t_sc_data; - int div_flag=0; // 0: total damage is to be divided by div_ - // 1: damage is distributed,and has to be multiplied by div_ [celest] - - //return前の処理があるので情報出力部のみ変更 - if( target == NULL || pd == NULL ){ //srcは内容に直接触れていないのでスルーしてみる - nullpo_info(NLP_MARK); - memset(&wd,0,sizeof(wd)); - return wd; - } - - s_race=status_get_race(src); - s_ele=status_get_attack_element(src); - - // ターゲット - if(target->type == BL_MOB) - tmd=(struct mob_data *)target; - else { - memset(&wd,0,sizeof(wd)); - return wd; - } - t_race=status_get_race( target ); - t_size=status_get_size( target ); - t_mode=status_get_mode( target ); - t_sc_data=status_get_sc_data( target ); - - flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // 攻撃の種類の設定 - - // 回避率計算、回避判定は後で - flee = status_get_flee(target); - if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0) - target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv); - if(battle_config.agi_penalty_type > 0) { - if(target_count >= battle_config.agi_penalty_count) { - if(battle_config.agi_penalty_type == 1) - flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; - else if(battle_config.agi_penalty_type == 2) - flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; - } - } - hitrate=status_get_hit(src) - flee + 80; - - type=0; // normal - if (skill_num > 0) { - div_ = skill_get_num(skill_num,skill_lv); - if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below - } - else div_ = 1; // single attack - - luk=status_get_luk(src); - - if(battle_config.pet_str) - damage = status_get_baseatk(src); - else - damage = 0; - - if(skill_num==HW_MAGICCRASHER){ /* マジッククラッシャーはMATKで殴る */ - atkmin = status_get_matk1(src); - atkmax = status_get_matk2(src); - }else{ - atkmin = status_get_atk(src); - atkmax = status_get_atk2(src); - } - if(mob_db[pd->class_].range>3 ) - flag=(flag&~BF_RANGEMASK)|BF_LONG; - - if(atkmin > atkmax) atkmin = atkmax; - - cri = status_get_critical(src); - cri -= status_get_luk(target) * 2; // luk/5*10 => target_luk*2 not target_luk*3 - if(battle_config.enemy_critical_rate != 100) { - cri = cri*battle_config.enemy_critical_rate/100; - if(cri < 1) - cri = 1; - } - if(t_sc_data) { - if (t_sc_data[SC_SLEEP].timer!=-1) - cri <<=1; - if(t_sc_data[SC_JOINTBEAT].timer != -1 && - t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG] - cri = 1000; - } - - if(skill_num == 0 && battle_config.enemy_critical && (rand() % 1000) < cri) - { - damage += atkmax; - type = 0x0a; - } - else { - int vitbonusmax; - - if(atkmax > atkmin) - damage += atkmin + rand() % (atkmax-atkmin + 1); - else - damage += atkmin ; - // スキル修正1(攻撃力倍化系) - // オーバートラスト(+5% 〜 +25%),他攻撃系スキルの場合ここで補正 - // バッシュ,マグナムブレイク, - // ボーリングバッシュ,スピアブーメラン,ブランディッシュスピア,スピアスタッブ, - // メマーナイト,カートレボリューション - // ダブルストレイフィング,アローシャワー,チャージアロー, - // ソニックブロー - if(skill_num>0){ - int i; - if( (i=skill_get_pl(skill_num))>0 ) - s_ele=i; - - flag=(flag&~BF_SKILLMASK)|BF_SKILL; - switch( skill_num ){ - case SM_BASH: // バッシュ - damage = damage*(100+ 30*skill_lv)/100; - hitrate = (hitrate*(100+5*skill_lv))/100; - break; - case SM_MAGNUM: // マグナムブレイク - damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100; - hitrate = (hitrate*(100+10*skill_lv))/100; - break; - case MC_MAMMONITE: // メマーナイト - damage = damage*(100+ 50*skill_lv)/100; - break; - case AC_DOUBLE: // ダブルストレイフィング - damage = damage*(180+ 20*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case AC_SHOWER: // アローシャワー - damage = damage*(75 + 5*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case AC_CHARGEARROW: // チャージアロー - damage = damage*150/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case KN_PIERCE: // ピアース - damage = damage*(100+ 10*skill_lv)/100; - hitrate = hitrate*(100+5*skill_lv)/100; - div_=t_size+1; - div_flag = 1; - break; - case KN_SPEARSTAB: // スピアスタブ - damage = damage*(100+ 15*skill_lv)/100; - break; - case KN_SPEARBOOMERANG: // スピアブーメラン - damage = damage*(100+ 50*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case KN_BRANDISHSPEAR: // ブランディッシュスピア - damage = damage*(100+ 20*skill_lv)/100; - if(skill_lv>3 && wflag==1) damage2+=damage/2; - if(skill_lv>6 && wflag==1) damage2+=damage/4; - if(skill_lv>9 && wflag==1) damage2+=damage/8; - if(skill_lv>6 && wflag==2) damage2+=damage/2; - if(skill_lv>9 && wflag==2) damage2+=damage/4; - if(skill_lv>9 && wflag==3) damage2+=damage/2; - damage +=damage2; - break; - case KN_BOWLINGBASH: // ボウリングバッシュ - damage = damage*(100+ 50*skill_lv)/100; - blewcount=0; - break; - case AS_GRIMTOOTH: - damage = damage*(100+ 20*skill_lv)/100; - break; - case AS_POISONREACT: // celest - s_ele = 0; - damage = damage*(100+ 30*skill_lv)/100; - break; - case AS_SONICBLOW: // ソニックブロウ - damage = damage*(300+ 50*skill_lv)/100; - break; - case TF_SPRINKLESAND: // 砂まき - damage = damage*125/100; - break; - case MC_CARTREVOLUTION: // カートレボリューション - damage = (damage*150)/100; - break; - // 以下MOB - case NPC_COMBOATTACK: // 多段攻撃 - div_flag = 1; - break; - case NPC_RANDOMATTACK: // ランダムATK攻撃 - damage = damage*(50+rand()%150)/100; - break; - // 属性攻撃(適当) - case NPC_WATERATTACK: - case NPC_GROUNDATTACK: - case NPC_FIREATTACK: - case NPC_WINDATTACK: - case NPC_POISONATTACK: - case NPC_HOLYATTACK: - case NPC_DARKNESSATTACK: - case NPC_UNDEADATTACK: - case NPC_TELEKINESISATTACK: - div_= pd->skillduration; // [Valaris] - break; - case NPC_GUIDEDATTACK: - hitrate = 1000000; - break; - case NPC_RANGEATTACK: - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case NPC_PIERCINGATT: - flag=(flag&~BF_RANGEMASK)|BF_SHORT; - break; - case RG_BACKSTAP: // バックスタブ - damage = damage*(300+ 40*skill_lv)/100; - hitrate = 1000000; - break; - case RG_RAID: // サプライズアタック - damage = damage*(100+ 40*skill_lv)/100; - break; - case RG_INTIMIDATE: // インティミデイト - damage = damage*(100+ 30*skill_lv)/100; - break; - case CR_SHIELDCHARGE: // シールドチャージ - damage = damage*(100+ 20*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_SHORT; - s_ele = 0; - break; - case CR_SHIELDBOOMERANG: // シールドブーメラン - damage = damage*(100+ 30*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - s_ele = 0; - break; - case CR_HOLYCROSS: // ホーリークロス - damage = damage*(100+ 35*skill_lv)/100; - break; - case CR_GRANDCROSS: - hitrate= 1000000; - break; - case AM_DEMONSTRATION: // デモンストレーション - hitrate= 1000000; - damage = damage*(100+ 20*skill_lv)/100; - damage2 = damage2*(100+ 20*skill_lv)/100; - break; - case AM_ACIDTERROR: // アシッドテラー - hitrate = 1000000; - damage = damage*(100+ 40*skill_lv)/100; - damage2 = damage2*(100+ 40*skill_lv)/100; - break; - case MO_FINGEROFFENSIVE: //指弾 - damage = damage * (125 + 25 * skill_lv) / 100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn - break; - case MO_INVESTIGATE: // 発 勁 - if(def1 < 1000000) - damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50; - hitrate = 1000000; - s_ele = 0; - break; - case MO_EXTREMITYFIST: // 阿修羅覇鳳拳 - damage = damage * 8 + 250 + (skill_lv * 150); - hitrate = 1000000; - s_ele = 0; - break; - case MO_CHAINCOMBO: // 連打掌 - damage = damage*(150+ 50*skill_lv)/100; - break; - case MO_COMBOFINISH: // 猛龍拳 - damage = damage*(240+ 60*skill_lv)/100; - break; - case DC_THROWARROW: // 矢撃ち - damage = damage*(60+ 40 * skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case BA_MUSICALSTRIKE: // ミュージカルストライク - damage = damage*(60+ 40 * skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case CH_TIGERFIST: // 伏虎拳 - damage = damage*(40+ 100*skill_lv)/100; - break; - case CH_CHAINCRUSH: // 連柱崩撃 - damage = damage*(400+ 100*skill_lv)/100; - break; - case CH_PALMSTRIKE: // 猛虎硬派山 - damage = damage*(200+ 100*skill_lv)/100; - break; - case LK_SPIRALPIERCE: /* スパイラルピアース */ - damage = damage*(100+ 50*skill_lv)/100; //増加量が分からないので適当に - flag=(flag&~BF_RANGEMASK)|BF_LONG; - if(target->type == BL_PC) - ((struct map_session_data *)target)->canmove_tick = gettick() + 1000; - else if(target->type == BL_MOB) - ((struct mob_data *)target)->canmove_tick = gettick() + 1000; - break; - case LK_HEADCRUSH: /* ヘッドクラッシュ */ - damage = damage*(100+ 40*skill_lv)/100; - break; - case LK_JOINTBEAT: /* ジョイントビート */ - damage = damage*(50+ 10*skill_lv)/100; - break; - case ASC_METEORASSAULT: /* メテオアサルト */ - damage = damage*(40+ 40*skill_lv)/100; - break; - case SN_SHARPSHOOTING: /* シャープシューティング */ - damage += damage*(30*skill_lv)/100; - break; - case CG_ARROWVULCAN: /* アローバルカン */ - damage = damage*(200+100*skill_lv)/100; - break; - case AS_SPLASHER: /* ベナムスプラッシャー */ - damage = damage*(200+20*skill_lv)/100; - hitrate = 1000000; - break; - } - if (div_flag && div_ > 1) { // [Skotlex] - damage *= div_; - damage2 *= div_; - } - } - - if( skill_num!=NPC_CRITICALSLASH ){ - // 対 象の防御力によるダメージの減少 - // ディバインプロテクション(ここでいいのかな?) - if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000 ) { //DEF, VIT無視 - int t_def; - target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv); - if(battle_config.vit_penalty_type > 0) { - if(target_count >= battle_config.vit_penalty_count) { - if(battle_config.vit_penalty_type == 1) { - def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - } - else if(battle_config.vit_penalty_type == 2) { - def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - } - if(def1 < 0) def1 = 0; - if(def2 < 1) def2 = 1; - if(t_vit < 1) t_vit = 1; - } - } - t_def = def2*8/10; - vitbonusmax = (t_vit/20)*(t_vit/20)-1; - if(battle_config.pet_defense_type) { - damage = damage - (def1 * battle_config.pet_defense_type) - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - else{ - damage = damage * (100 - def1) /100 - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - } - } - } - - // 0未満だった場合1に補正 - if(damage<1) damage=1; - - // 回避修正 - if( hitrate < 1000000 && t_sc_data ) { // 必中攻撃 - if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG) - hitrate -= 75; - if (t_sc_data[SC_SLEEP].timer!=-1 || // 睡眠は必中 - t_sc_data[SC_STAN].timer!=-1 || // スタンは必中 - t_sc_data[SC_FREEZE].timer!=-1 || - (t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // 凍結は必中 - hitrate = 1000000; - } - if(hitrate < 1000000) - hitrate = ( (hitrate>95)?95: ((hitrate<5)?5:hitrate) ); - if(type == 0 && rand()%100 >= hitrate) { - damage = damage2 = 0; - dmg_lv = ATK_FLEE; - } else { - dmg_lv = ATK_DEF; - } - - - if(t_sc_data) { - int cardfix=100; - if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG) - cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100; - if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG) - cardfix=cardfix*50/100; - if(cardfix != 100) - damage=damage*cardfix/100; - } - if(damage < 0) damage = 0; - - // 属 性の適用 - if(skill_num != 0 || s_ele != 0 || !battle_config.pet_attack_attr_none) - damage=battle_attr_fix(damage, s_ele, status_get_element(target) ); - - if(skill_num==PA_PRESSURE) /* プレッシャー 必中? */ - damage = 500+300*skill_lv; - - // インベナム修正 - if(skill_num==TF_POISON){ - damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) ); - } - if(skill_num==MC_CARTREVOLUTION){ - damage = battle_attr_fix(damage, 0, status_get_element(target) ); - } - - // 完全回避の判定 - if(battle_config.enemy_perfect_flee) { - if(skill_num == 0 && tmd!=NULL && rand()%1000 < status_get_flee2(target) ){ - damage=0; - type=0x0b; - dmg_lv = ATK_LUCKY; - } - } - -// if(def1 >= 1000000 && damage > 0) - if(t_mode&0x40 && damage > 0) - damage = 1; - - if(skill_num != CR_GRANDCROSS) - damage=battle_calc_damage(src,target,damage,div_,skill_num,skill_lv,flag); - - wd.damage=damage; - wd.damage2=0; - wd.type=type; - wd.div_=div_; - wd.amotion=status_get_amotion(src); - if(skill_num == KN_AUTOCOUNTER) - wd.amotion >>= 1; - wd.dmotion=status_get_dmotion(target); - wd.blewcount=blewcount; - wd.flag=flag; - wd.dmg_lv=dmg_lv; - - return wd; -} - -static struct Damage battle_calc_mob_weapon_attack( - struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int wflag) -{ - struct map_session_data *tsd=NULL; - struct mob_data* md=(struct mob_data *)src,*tmd=NULL; - int hitrate,flee,cri = 0,atkmin,atkmax; - int luk,target_count = 1; - int def1 = status_get_def(target); - int def2 = status_get_def2(target); - int t_vit = status_get_vit(target); - struct Damage wd; - int damage,damage2=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv); - int flag,skill,ac_flag = 0,dmg_lv = 0; - int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0,s_size=0,s_race2=0; - struct status_change *sc_data,*t_sc_data; - short *sc_count; - short *option, *opt1, *opt2; - int div_flag=0; // 0: total damage is to be divided by div_ - // 1: damage is distributed,and has to be multiplied by div_ [celest] - - //return前の処理があるので情報出力部のみ変更 - if( src == NULL || target == NULL || md == NULL ){ - nullpo_info(NLP_MARK); - memset(&wd,0,sizeof(wd)); - return wd; - } - - s_race = status_get_race(src); - s_ele = status_get_attack_element(src); - s_size = status_get_size(src); - sc_data = status_get_sc_data(src); - sc_count = status_get_sc_count(src); - option = status_get_option(src); - opt1 = status_get_opt1(src); - opt2 = status_get_opt2(src); - s_race2 = status_get_race2(src); - - // ターゲット - if(target->type == BL_PC) - tsd = (struct map_session_data *)target; - else if(target->type == BL_MOB) - tmd = (struct mob_data *)target; - t_race = status_get_race( target ); - t_size = status_get_size( target ); - t_mode = status_get_mode( target ); - t_sc_data = status_get_sc_data( target ); - - if(skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) || - (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) { - if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1) { - int dir = map_calc_dir(src,target->x,target->y),t_dir = status_get_dir(target); - int dist = distance(src->x,src->y,target->x,target->y); - if(dist <= 0 || map_check_dir(dir,t_dir) ) { - memset(&wd,0,sizeof(wd)); - t_sc_data[SC_AUTOCOUNTER].val3 = 0; - t_sc_data[SC_AUTOCOUNTER].val4 = 1; - if(sc_data && sc_data[SC_AUTOCOUNTER].timer == -1) { - int range = status_get_range(target); - if((target->type == BL_PC && ((struct map_session_data *)target)->status.weapon != 11 && dist <= range+1) || - (target->type == BL_MOB && range <= 3 && dist <= range+1) ) - t_sc_data[SC_AUTOCOUNTER].val3 = src->id; - } - return wd; - } - else ac_flag = 1; - } else if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_POISONREACT].timer != -1) { // poison react [Celest] - t_sc_data[SC_POISONREACT].val3 = 0; - t_sc_data[SC_POISONREACT].val4 = 1; - t_sc_data[SC_POISONREACT].val3 = src->id; - } - } - flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // 攻撃の種類の設定 - - // 回避率計算、回避判定は後で - flee = status_get_flee(target); - if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0) - target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv); - if(battle_config.agi_penalty_type > 0) { - if(target_count >= battle_config.agi_penalty_count) { - if(battle_config.agi_penalty_type == 1) - flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; - else if(battle_config.agi_penalty_type == 2) - flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; - } - } - hitrate=status_get_hit(src) - flee + 80; - - type=0; // normal - if (skill_num > 0) { - div_ = skill_get_num(skill_num,skill_lv); - if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below - } else div_ = 1; // single attack - - luk=status_get_luk(src); - - if(battle_config.enemy_str) - damage = status_get_baseatk(src); - else - damage = 0; - if(skill_num==HW_MAGICCRASHER){ /* マジッククラッシャーはMATKで殴る */ - atkmin = status_get_matk1(src); - atkmax = status_get_matk2(src); - }else{ - atkmin = status_get_atk(src); - atkmax = status_get_atk2(src); - } - if(mob_db[md->class_].range>3 ) - flag=(flag&~BF_RANGEMASK)|BF_LONG; - - if(atkmin > atkmax) atkmin = atkmax; - - if(sc_data != NULL && sc_data[SC_MAXIMIZEPOWER].timer!=-1 ){ // マキシマイズパワー - atkmin=atkmax; - } - - cri = status_get_critical(src); - cri -= status_get_luk(target) * 3; - if(battle_config.enemy_critical_rate != 100) { - cri = cri*battle_config.enemy_critical_rate/100; - if(cri < 1) - cri = 1; - } - if(t_sc_data) { - if (t_sc_data[SC_SLEEP].timer!=-1 ) // 睡眠中はクリティカルが倍に - cri <<=1; - if(t_sc_data[SC_JOINTBEAT].timer != -1 && - t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG] - cri = 1000; - } - - if(ac_flag) cri = 1000; - - if(skill_num == KN_AUTOCOUNTER) { - if(!(battle_config.monster_auto_counter_type&1)) - cri = 1000; - else - cri <<= 1; - } - - if(tsd && tsd->critical_def) - cri = cri * (100 - tsd->critical_def) / 100; - - if((skill_num == 0 || skill_num == KN_AUTOCOUNTER) && skill_lv >= 0 && battle_config.enemy_critical && (rand() % 1000) < cri) // 判定(スキルの場合は無視) - // 敵の判定 - { - damage += atkmax; - type = 0x0a; - } - else { - int vitbonusmax; - - if(atkmax > atkmin) - damage += atkmin + rand() % (atkmax-atkmin + 1); - else - damage += atkmin ; - // スキル修正1(攻撃力倍化系) - // オーバートラスト(+5% 〜 +25%),他攻撃系スキルの場合ここで補正 - // バッシュ,マグナムブレイク, - // ボーリングバッシュ,スピアブーメラン,ブランディッシュスピア,スピアスタッブ, - // メマーナイト,カートレボリューション - // ダブルストレイフィング,アローシャワー,チャージアロー, - // ソニックブロー - if(sc_data){ //状態異常中のダメージ追加 - if(sc_data[SC_OVERTHRUST].timer!=-1) // オーバートラスト - damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100; - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100; - if(sc_data[SC_BERSERK].timer!=-1) // バーサーク - damage += damage*2; - if(sc_data && sc_data[SC_AURABLADE].timer!=-1) //[DracoRPG] - damage += sc_data[SC_AURABLADE].val1 * 20; - } - - if(skill_num>0){ - int i; - if( (i=skill_get_pl(skill_num))>0 ) - s_ele=i; - - flag=(flag&~BF_SKILLMASK)|BF_SKILL; - switch( skill_num ){ - case SM_BASH: // バッシュ - damage = damage*(100+ 30*skill_lv)/100; - hitrate = (hitrate*(100+5*skill_lv))/100; - break; - case SM_MAGNUM: // マグナムブレイク - damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100; - hitrate = (hitrate*(100+10*skill_lv))/100; - break; - case MC_MAMMONITE: // メマーナイト - damage = damage*(100+ 50*skill_lv)/100; - break; - case AC_DOUBLE: // ダブルストレイフィング - damage = damage*(180+ 20*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case AC_SHOWER: // アローシャワー - damage = damage*(75 + 5*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case AC_CHARGEARROW: // チャージアロー - damage = damage*150/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case KN_PIERCE: // ピアース - damage = damage*(100+ 10*skill_lv)/100; - hitrate = hitrate*(100+5*skill_lv)/100; - div_ = t_size+1; - div_flag = 1; - break; - case KN_SPEARSTAB: // スピアスタブ - damage = damage*(100+ 15*skill_lv)/100; - break; - case KN_SPEARBOOMERANG: // スピアブーメラン - damage = damage*(100+ 50*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case KN_BRANDISHSPEAR: // ブランディッシュスピア - damage = damage*(100+ 20*skill_lv)/100; - if(skill_lv>3 && wflag==1) damage2+=damage/2; - if(skill_lv>6 && wflag==1) damage2+=damage/4; - if(skill_lv>9 && wflag==1) damage2+=damage/8; - if(skill_lv>6 && wflag==2) damage2+=damage/2; - if(skill_lv>9 && wflag==2) damage2+=damage/4; - if(skill_lv>9 && wflag==3) damage2+=damage/2; - damage +=damage2; - break; - case KN_BOWLINGBASH: // ボウリングバッシュ - damage = damage*(100+ 50*skill_lv)/100; - blewcount=0; - break; - case KN_AUTOCOUNTER: - if(battle_config.monster_auto_counter_type&1) - hitrate += 20; - else - hitrate = 1000000; - flag=(flag&~BF_SKILLMASK)|BF_NORMAL; - break; - case AS_GRIMTOOTH: - damage = damage*(100+ 20*skill_lv)/100; - break; - case AS_POISONREACT: // celest - s_ele = 0; - damage = damage*(100+ 30*skill_lv)/100; - break; - case AS_SONICBLOW: // ソニックブロウ - damage = damage*(300+ 50*skill_lv)/100; - break; - case TF_SPRINKLESAND: // 砂まき - damage = damage*125/100; - break; - case MC_CARTREVOLUTION: // カートレボリューション - damage = (damage*150)/100; - break; - // 以下MOB - case NPC_COMBOATTACK: // 多段攻撃 - div_flag = 1; - break; - case NPC_RANDOMATTACK: // ランダムATK攻撃 - damage = damage*(50+rand()%150)/100; - break; - // 属性攻撃(適当) - case NPC_WATERATTACK: - case NPC_GROUNDATTACK: - case NPC_FIREATTACK: - case NPC_WINDATTACK: - case NPC_POISONATTACK: - case NPC_HOLYATTACK: - case NPC_DARKNESSATTACK: - case NPC_UNDEADATTACK: - case NPC_TELEKINESISATTACK: - damage = damage*(100+25*(skill_lv-1))/100; - break; - case NPC_GUIDEDATTACK: - hitrate = 1000000; - break; - case NPC_RANGEATTACK: - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case NPC_PIERCINGATT: - flag=(flag&~BF_RANGEMASK)|BF_SHORT; - break; - case RG_BACKSTAP: // バックスタブ - damage = damage*(300+ 40*skill_lv)/100; - hitrate = 1000000; - break; - case RG_RAID: // サプライズアタック - damage = damage*(100+ 40*skill_lv)/100; - break; - case RG_INTIMIDATE: // インティミデイト - damage = damage*(100+ 30*skill_lv)/100; - break; - case CR_SHIELDCHARGE: // シールドチャージ - damage = damage*(100+ 20*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_SHORT; - s_ele = 0; - break; - case CR_SHIELDBOOMERANG: // シールドブーメラン - damage = damage*(100+ 30*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - s_ele = 0; - break; - case CR_HOLYCROSS: // ホーリークロス - damage = damage*(100+ 35*skill_lv)/100; - break; - case CR_GRANDCROSS: - hitrate= 1000000; - break; - case AM_DEMONSTRATION: // デモンストレーション - hitrate = 1000000; - damage = damage*(100+ 20*skill_lv)/100; - damage2 = damage2*(100+ 20*skill_lv)/100; - break; - case AM_ACIDTERROR: // アシッドテラー - hitrate = 1000000; - damage = damage*(100+ 40*skill_lv)/100; - damage2 = damage2*(100+ 40*skill_lv)/100; - break; - case MO_FINGEROFFENSIVE: //指弾 - damage = damage * (125 + 25 * skill_lv) / 100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn - break; - case MO_INVESTIGATE: // 発 勁 - if(def1 < 1000000) - damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50; - hitrate = 1000000; - s_ele = 0; - break; - case MO_EXTREMITYFIST: // 阿修羅覇鳳拳 - damage = damage * 8 + 250 + (skill_lv * 150); - hitrate = 1000000; - s_ele = 0; - break; - case MO_CHAINCOMBO: // 連打掌 - damage = damage*(150+ 50*skill_lv)/100; - break; - case BA_MUSICALSTRIKE: // ミュージカルストライク - damage = damage*(60+ 40 * skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case DC_THROWARROW: // 矢撃ち - damage = damage*(60+ 40 * skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case MO_COMBOFINISH: // 猛龍拳 - damage = damage*(240+ 60*skill_lv)/100; - break; - case CH_TIGERFIST: // 伏虎拳 - damage = damage*(40+ 100*skill_lv)/100; - break; - case CH_CHAINCRUSH: // 連柱崩撃 - damage = damage*(400+ 100*skill_lv)/100; - break; - case CH_PALMSTRIKE: // 猛虎硬派山 - damage = damage*(200+ 100*skill_lv)/100; - break; - case LK_SPIRALPIERCE: /* スパイラルピアース */ - damage = damage*(100+ 50*skill_lv)/100; //増加量が分からないので適当に - flag=(flag&~BF_RANGEMASK)|BF_LONG; - if(tsd) - tsd->canmove_tick = gettick() + 1000; - else if(tmd) - tmd->canmove_tick = gettick() + 1000; - break; - case LK_HEADCRUSH: /* ヘッドクラッシュ */ - damage = damage*(100+ 40*skill_lv)/100; - break; - case LK_JOINTBEAT: /* ジョイントビート */ - damage = damage*(50+ 10*skill_lv)/100; - break; - case ASC_METEORASSAULT: /* メテオアサルト */ - damage = damage*(40+ 40*skill_lv)/100; - break; - case SN_SHARPSHOOTING: /* シャープシューティング */ - damage += damage*(30*skill_lv)/100; - break; - case CG_ARROWVULCAN: /* アローバルカン */ - damage = damage*(200+100*skill_lv)/100; - break; - case AS_SPLASHER: /* ベナムスプラッシャー */ - damage = damage*(200+20*skill_lv)/100; - hitrate = 1000000; - break; - } - if (div_flag && div_ > 1) { // [Skotlex] - damage *= div_; - damage2 *= div_; - } - } - - if( skill_num!=NPC_CRITICALSLASH ){ - // 対 象の防御力によるダメージの減少 - // ディバインプロテクション(ここでいいのかな?) - if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT無視 - int t_def; - target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv); - if(battle_config.vit_penalty_type > 0) { - if(target_count >= battle_config.vit_penalty_count) { - if(battle_config.vit_penalty_type == 1) { - def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - } - else if(battle_config.vit_penalty_type == 2) { - def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - } - if(def1 < 0) def1 = 0; - if(def2 < 1) def2 = 1; - if(t_vit < 1) t_vit = 1; - } - } - t_def = def2*8/10; - if(battle_check_undead(s_race,status_get_elem_type(src)) || s_race==6) - if(tsd && (skill=pc_checkskill(tsd,AL_DP)) > 0 ) - t_def += skill* (int) (3 + (tsd->status.base_level+1)*0.04); // submitted by orn - //t_def += skill*3; - - vitbonusmax = (t_vit/20)*(t_vit/20)-1; - if(battle_config.monster_defense_type) { - damage = damage - (def1 * battle_config.monster_defense_type) - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - else{ - damage = damage * (100 - def1) /100 - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - } - } - } - - // 0未満だった場合1に補正 - if(damage<1) damage=1; - - // 回避修正 - if( hitrate < 1000000 && t_sc_data ) { // 必中攻撃 - if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG) - hitrate -= 75; - if (t_sc_data[SC_SLEEP].timer!=-1 || // 睡眠は必中 - t_sc_data[SC_STAN].timer!=-1 || // スタンは必中 - t_sc_data[SC_FREEZE].timer!=-1 || - (t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // 凍結は必中 - hitrate = 1000000; - } - if(hitrate < 1000000) - hitrate = ( (hitrate>95)?95: ((hitrate<5)?5:hitrate) ); - if(type == 0 && rand()%100 >= hitrate) { - damage = damage2 = 0; - dmg_lv = ATK_FLEE; - } else { - dmg_lv = ATK_DEF; - } - - if(tsd){ - int cardfix=100,i; - cardfix=cardfix*(100-tsd->subele[s_ele])/100; // 属 性によるダメージ耐性 - cardfix=cardfix*(100-tsd->subrace[s_race])/100; // 種族によるダメージ耐性 - cardfix=cardfix*(100-tsd->subsize[s_size])/100; - cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; // 種族によるダメージ耐性 - if(mob_db[md->class_].mode & 0x20) - cardfix=cardfix*(100-tsd->subrace[10])/100; - else - cardfix=cardfix*(100-tsd->subrace[11])/100; - for(i=0;i<tsd->add_def_class_count;i++) { - if(tsd->add_def_classid[i] == md->class_) { - cardfix=cardfix*(100-tsd->add_def_classrate[i])/100; - break; - } - } - for(i=0;i<tsd->add_damage_class_count2;i++) { - if(tsd->add_damage_classid2[i] == md->class_) { - cardfix=cardfix*(100+tsd->add_damage_classrate2[i])/100; - break; - } - } - if(flag&BF_LONG) - cardfix=cardfix*(100-tsd->long_attack_def_rate)/100; - if(flag&BF_SHORT) - cardfix=cardfix*(100-tsd->near_attack_def_rate)/100; - damage=damage*cardfix/100; - } - if(t_sc_data) { - int cardfix=100; - if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG) - cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100; - if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG) - cardfix=cardfix*50/100; - if(cardfix != 100) - damage=damage*cardfix/100; - } - if(t_sc_data && t_sc_data[SC_ASSUMPTIO].timer != -1){ //アシャンプティオ - if(!map[target->m].flag.pvp) - damage=damage/3; - else - damage=damage/2; - } - - if(damage < 0) damage = 0; - - // 属 性の適用 - if (!((battle_config.mob_ghostring_fix == 1) && - (status_get_elem_type(target) == 8) && - (target->type==BL_PC))) // [MouseJstr] - if(skill_num != 0 || s_ele != 0 || !battle_config.mob_attack_attr_none) - damage=battle_attr_fix(damage, s_ele, status_get_element(target) ); - - //if(sc_data && sc_data[SC_AURABLADE].timer!=-1) /* オーラブレード 必中 */ - // damage += sc_data[SC_AURABLADE].val1 * 10; - if(skill_num==PA_PRESSURE) /* プレッシャー 必中? */ - damage = 500+300*skill_lv; - - // インベナム修正 - if(skill_num==TF_POISON){ - damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) ); - } - if(skill_num==MC_CARTREVOLUTION){ - damage = battle_attr_fix(damage, 0, status_get_element(target) ); - } - - // 完全回避の判定 - if(skill_num == 0 && tsd!=NULL && rand()%1000 < status_get_flee2(target) ){ - damage=0; - type=0x0b; - dmg_lv = ATK_LUCKY; - } - - if(battle_config.enemy_perfect_flee) { - if(skill_num == 0 && tmd!=NULL && rand()%1000 < status_get_flee2(target) ){ - damage=0; - type=0x0b; - dmg_lv = ATK_LUCKY; - } - } - -// if(def1 >= 1000000 && damage > 0) - if(t_mode&0x40 && damage > 0) - damage = 1; - - if( tsd && tsd->special_state.no_weapon_damage) - damage = 0; - - if(skill_num != CR_GRANDCROSS) - damage=battle_calc_damage(src,target,damage,div_,skill_num,skill_lv,flag); - - wd.damage=damage; - wd.damage2=0; - wd.type=type; - wd.div_=div_; - wd.amotion=status_get_amotion(src); - if(skill_num == KN_AUTOCOUNTER) - wd.amotion >>= 1; - wd.dmotion=status_get_dmotion(target); - wd.blewcount=blewcount; - wd.flag=flag; - wd.dmg_lv=dmg_lv; - return wd; -} -/* - * ========================================================================= - * PCの武器による攻撃 - *------------------------------------------------------------------------- - */ -static struct Damage battle_calc_pc_weapon_attack( - struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int wflag) -{ - struct map_session_data *sd=(struct map_session_data *)src,*tsd=NULL; - struct mob_data *tmd=NULL; - int hitrate,flee,cri = 0,atkmin,atkmax; - int dex,luk,target_count = 1; - int no_cardfix=0; - int def1 = status_get_def(target); - int def2 = status_get_def2(target); - int t_vit = status_get_vit(target); - struct Damage wd; - int damage,damage2,damage3=0,damage4=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv); - int flag,skill,dmg_lv = 0; - int t_mode=0,t_race=0,t_size=1,s_race=7,s_ele=0,s_size=1; - int t_race2=0; - struct status_change *sc_data,*t_sc_data; - short *sc_count; - short *option, *opt1, *opt2; - int atkmax_=0, atkmin_=0, s_ele_; //二刀流用 - int watk,watk_,cardfix,t_ele; - int da=0,i,t_class,ac_flag = 0; - int idef_flag=0,idef_flag_=0; - int div_flag=0; // 0: total damage is to be divided by div_ - // 1: damage is distributed,and has to be multiplied by div_ [celest] - - //return前の処理があるので情報出力部のみ変更 - if( src == NULL || target == NULL || sd == NULL ){ - nullpo_info(NLP_MARK); - memset(&wd,0,sizeof(wd)); - return wd; - } - - - // アタッカー - s_race=status_get_race(src); //種族 - s_ele=status_get_attack_element(src); //属性 - s_ele_=status_get_attack_element2(src); //左手属性 - s_size=status_get_size(src); - sc_data=status_get_sc_data(src); //ステータス異常 - sc_count=status_get_sc_count(src); //ステータス異常の数 - option=status_get_option(src); //鷹とかペコとかカートとか - opt1=status_get_opt1(src); //石化、凍結、スタン、睡眠、暗闇 - opt2=status_get_opt2(src); //毒、呪い、沈黙、暗闇? - t_race2=status_get_race2(target); - - if(skill_num != CR_GRANDCROSS) //グランドクロスでないなら - sd->state.attack_type = BF_WEAPON; //攻撃タイプは武器攻撃 - - // ターゲット - if(target->type==BL_PC) //対象がPCなら - tsd=(struct map_session_data *)target; //tsdに代入(tmdはNULL) - else if(target->type==BL_MOB) //対象がMobなら - tmd=(struct mob_data *)target; //tmdに代入(tsdはNULL) - t_race=status_get_race( target ); //対象の種族 - t_ele=status_get_elem_type(target); //対象の属性 - t_size=status_get_size( target ); //対象のサイズ - t_mode=status_get_mode( target ); //対象のMode - t_sc_data=status_get_sc_data( target ); //対象のステータス異常 - -//オートカウンター処理ここから - if(skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) || - (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) { - if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1) { //グランドクロスでなく、対象がオートカウンター状態の場合 - int dir = map_calc_dir(src,target->x,target->y),t_dir = status_get_dir(target); - int dist = distance(src->x,src->y,target->x,target->y); - if(dist <= 0 || map_check_dir(dir,t_dir) ) { //対象との距離が0以下、または対象の正面? - memset(&wd,0,sizeof(wd)); - t_sc_data[SC_AUTOCOUNTER].val3 = 0; - t_sc_data[SC_AUTOCOUNTER].val4 = 1; - if(sc_data && sc_data[SC_AUTOCOUNTER].timer == -1) { //自分がオートカウンター状態 - int range = status_get_range(target); - if((target->type == BL_PC && ((struct map_session_data *)target)->status.weapon != 11 && dist <= range+1) || //対象がPCで武器が弓矢でなく射程内 - (target->type == BL_MOB && range <= 3 && dist <= range+1) ) //または対象がMobで射程が3以下で射程内 - t_sc_data[SC_AUTOCOUNTER].val3 = src->id; - } - return wd; //ダメージ構造体を返して終了 - } - else ac_flag = 1; - } else if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_POISONREACT].timer != -1) { // poison react [Celest] - t_sc_data[SC_POISONREACT].val3 = 0; - t_sc_data[SC_POISONREACT].val4 = 1; - t_sc_data[SC_POISONREACT].val3 = src->id; - } - } -//オートカウンター処理ここまで - - flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // 攻撃の種類の設定 - - // 回避率計算、回避判定は後で - flee = status_get_flee(target); - if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0) //AGI、VITペナルティ設定が有効 - target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv); //対象の数を算出 - if(battle_config.agi_penalty_type > 0) { - if(target_count >= battle_config.agi_penalty_count) { //ペナルティ設定より対象が多い - if(battle_config.agi_penalty_type == 1) //回避率がagi_penalty_num%ずつ減少 - flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; - else if(battle_config.agi_penalty_type == 2) //回避率がagi_penalty_num分減少 - flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; //回避率は最低でも1 - } - } - hitrate=status_get_hit(src) - flee + 80; //命中率計算 - - type=0; // normal - if (skill_num > 0) { - div_=skill_get_num(skill_num,skill_lv); - if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below - } else div_ = 1; // single attack - - dex=status_get_dex(src); //DEX - luk=status_get_luk(src); //LUK - watk = status_get_atk(src); //ATK - watk_ = status_get_atk_(src); //ATK左手 - - if(skill_num==HW_MAGICCRASHER){ /* マジッククラッシャーはMATKで殴る */ - damage = damage2 = status_get_matk1(src); //damega,damega2初登場、base_atkの取得 - }else{ - damage = damage2 = status_get_baseatk(&sd->bl); //damega,damega2初登場、base_atkの取得 - } - atkmin = atkmin_ = dex; //最低ATKはDEXで初期化? - sd->state.arrow_atk = 0; //arrow_atk初期化 - if(sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]]) - atkmin = atkmin*(80 + sd->inventory_data[sd->equip_index[9]]->wlv*20)/100; - if(sd->equip_index[8] >= 0 && sd->inventory_data[sd->equip_index[8]]) - atkmin_ = atkmin_*(80 + sd->inventory_data[sd->equip_index[8]]->wlv*20)/100; - if(sd->status.weapon == 11) { //武器が弓矢の場合 - atkmin = watk * ((atkmin<watk)? atkmin:watk)/100; //弓用最低ATK計算 - flag=(flag&~BF_RANGEMASK)|BF_LONG; //遠距離攻撃フラグを有効 - if(sd->arrow_ele > 0) //属性矢なら属性を矢の属性に変更 - s_ele = sd->arrow_ele; - sd->state.arrow_atk = 1; //arrow_atk有効化 - } - - // サイズ修正 - // ペコ騎乗していて、槍で攻撃した場合は中型のサイズ修正を100にする - // ウェポンパーフェクション,ドレイクC - if(((sd->special_state.no_sizefix) || (pc_isriding(sd) && (sd->status.weapon==4 || sd->status.weapon==5) && t_size==1) || skill_num == MO_EXTREMITYFIST)){ //ペコ騎乗していて、槍で中型を攻撃 - atkmax = watk; - atkmax_ = watk_; - } else { - atkmax = (watk * sd->atkmods[ t_size ]) / 100; - atkmin = (atkmin * sd->atkmods[ t_size ]) / 100; - atkmax_ = (watk_ * sd->atkmods_[ t_size ]) / 100; - atkmin_ = (atkmin_ * sd->atkmods[ t_size ]) / 100; - } - if( (sc_data != NULL && sc_data[SC_WEAPONPERFECTION].timer!=-1) || (sd->special_state.no_sizefix)) { // ウェポンパーフェクション || ドレイクカード - atkmax = watk; - atkmax_ = watk_; - } - - if(atkmin > atkmax && !(sd->state.arrow_atk)) atkmin = atkmax; //弓は最低が上回る場合あり - if(atkmin_ > atkmax_) atkmin_ = atkmax_; - - if(sc_data != NULL && sc_data[SC_MAXIMIZEPOWER].timer!=-1 ){ // マキシマイズパワー - atkmin=atkmax; - atkmin_=atkmax_; - } - - //ダブルアタック判定 - if(sd->weapontype1 == 0x01) { - if(skill_num == 0 && skill_lv >= 0 && (skill = pc_checkskill(sd,TF_DOUBLE)) > 0) - da = (rand()%100 < (skill*5)) ? 1:0; - } - - //三段掌 - //if(skill_num == 0 && skill_lv >= 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16 && !sd->state.arrow_atk) { - if(skill_num == 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16) { // triple blow works with bows ^^ [celest] - da = (rand()%100 < (30 - skill)) ? 2:0; - } - - if(sd->double_rate > 0 && da == 0 && skill_num == 0) - da = (rand()%100 < sd->double_rate) ? 1:0; - - // 過剰精錬ボーナス - if(sd->overrefine>0 ) - damage+=(rand()%sd->overrefine)+1; - if(sd->overrefine_>0 ) - damage2+=(rand()%sd->overrefine_)+1; - - if(da == 0){ //ダブルアタックが発動していない - // クリティカル計算 - cri = status_get_critical(src); - cri += sd->critaddrace[t_race]; - - if(sd->state.arrow_atk) - cri += sd->arrow_cri; - if(sd->status.weapon == 16) - // カタールの場合、クリティカルを倍に - cri <<=1; - cri -= status_get_luk(target) * 3; - if(t_sc_data) { - if (t_sc_data[SC_SLEEP].timer!=-1 ) // 睡眠中はクリティカルが倍に - cri <<=1; - if(t_sc_data[SC_JOINTBEAT].timer != -1 && - t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG] - cri = 1000; - } - if(ac_flag) cri = 1000; - - if(skill_num == KN_AUTOCOUNTER) { - if(!(battle_config.pc_auto_counter_type&1)) - cri = 1000; - else - cri <<= 1; - } - if(skill_num == SN_SHARPSHOOTING) - cri += 200; - } - - if(tsd && tsd->critical_def) - cri = cri * (100-tsd->critical_def) / 100; - - if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && //ダブルアタックが発動していない - (rand() % 1000) < cri) // 判定(スキルの場合は無視) - { - damage += atkmax; - damage2 += atkmax_; - if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) { - if (sd->status.weapon < 16) { - damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; - damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; - } - } - if(sd->state.arrow_atk) - damage += sd->arrow_atk; - - damage += damage * sd->crit_atk_rate / 100; - - type = 0x0a; - -/* if(def1 < 1000000) { - if(sd->def_ratio_atk_ele & (1<<t_ele) || sd->def_ratio_atk_race & (1<<t_race)) { - damage = (damage * (def1 + def2))/100; - idef_flag = 1; - } - if(sd->def_ratio_atk_ele_ & (1<<t_ele) || sd->def_ratio_atk_race_ & (1<<t_race)) { - damage2 = (damage2 * (def1 + def2))/100; - idef_flag_ = 1; - } - if(t_mode & 0x20) { - if(!idef_flag && sd->def_ratio_atk_race & (1<<10)) { - damage = (damage * (def1 + def2))/100; - idef_flag = 1; - } - if(!idef_flag_ && sd->def_ratio_atk_race_ & (1<<10)) { - damage2 = (damage2 * (def1 + def2))/100; - idef_flag_ = 1; - } - } - else { - if(!idef_flag && sd->def_ratio_atk_race & (1<<11)) { - damage = (damage * (def1 + def2))/100; - idef_flag = 1; - } - if(!idef_flag_ && sd->def_ratio_atk_race_ & (1<<11)) { - damage2 = (damage2 * (def1 + def2))/100; - idef_flag_ = 1; - } - } - }*/ - } - else { - int vitbonusmax; - - if(atkmax > atkmin) - damage += atkmin + rand() % (atkmax-atkmin + 1); - else - damage += atkmin ; - if(atkmax_ > atkmin_) - damage2 += atkmin_ + rand() % (atkmax_-atkmin_ + 1); - else - damage2 += atkmin_ ; - if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) { - if (sd->status.weapon < 16) { - damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; - damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; - } - } - - if(sd->state.arrow_atk) { - if(sd->arrow_atk > 0) - damage += rand()%(sd->arrow_atk+1); - hitrate += sd->arrow_hit; - } - - if(skill_num != MO_INVESTIGATE && def1 < 1000000) { - if(sd->def_ratio_atk_ele & (1<<t_ele) || sd->def_ratio_atk_race & (1<<t_race)) { - damage = (damage * (def1 + def2))/100; - idef_flag = 1; - } - if(sd->def_ratio_atk_ele_ & (1<<t_ele) || sd->def_ratio_atk_race_ & (1<<t_race)) { - damage2 = (damage2 * (def1 + def2))/100; - idef_flag_ = 1; - } - if(t_mode & 0x20) { - if(!idef_flag && sd->def_ratio_atk_race & (1<<10)) { - damage = (damage * (def1 + def2))/100; - idef_flag = 1; - } - if(!idef_flag_ && sd->def_ratio_atk_race_ & (1<<10)) { - damage2 = (damage2 * (def1 + def2))/100; - idef_flag_ = 1; - } - } - else { - if(!idef_flag && sd->def_ratio_atk_race & (1<<11)) { - damage = (damage * (def1 + def2))/100; - idef_flag = 1; - } - if(!idef_flag_ && sd->def_ratio_atk_race_ & (1<<11)) { - damage2 = (damage2 * (def1 + def2))/100; - idef_flag_ = 1; - } - } - } - - // スキル修正1(攻撃力倍化系) - // オーバートラスト(+5% 〜 +25%),他攻撃系スキルの場合ここで補正 - // バッシュ,マグナムブレイク, - // ボーリングバッシュ,スピアブーメラン,ブランディッシュスピア,スピアスタッブ, - // メマーナイト,カートレボリューション - // ダブルストレイフィング,アローシャワー,チャージアロー, - // ソニックブロー - if(sc_data){ //状態異常中のダメージ追加 - if(sc_data[SC_OVERTHRUST].timer!=-1){ // オーバートラスト - damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100; - damage2 += damage2*(5*sc_data[SC_OVERTHRUST].val1)/100; - } - if(sc_data[SC_TRUESIGHT].timer!=-1){ // トゥルーサイト - damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100; - damage2 += damage2*(2*sc_data[SC_TRUESIGHT].val1)/100; - } - if(sc_data[SC_BERSERK].timer!=-1){ // バーサーク - damage += damage*2; - damage2 += damage2*2; - } - if(sc_data && sc_data[SC_AURABLADE].timer!=-1) { //[DracoRPG] - damage += sc_data[SC_AURABLADE].val1 * 20; - damage2 += sc_data[SC_AURABLADE].val1 * 20; - } - } - - if(skill_num>0){ - int i; - if( (i=skill_get_pl(skill_num))>0 ) - s_ele=s_ele_=i; - - flag=(flag&~BF_SKILLMASK)|BF_SKILL; - switch( skill_num ){ - case SM_BASH: // バッシュ - damage = damage*(100+ 30*skill_lv)/100; - damage2 = damage2*(100+ 30*skill_lv)/100; - hitrate = (hitrate*(100+5*skill_lv))/100; - break; - case SM_MAGNUM: // マグナムブレイク - // 20*skill level+100? i think this will do for now [based on jRO info] - damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100; - damage2 = damage2*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100; - hitrate = (hitrate*(100+10*skill_lv))/100; - break; - case MC_MAMMONITE: // メマーナイト - damage = damage*(100+ 50*skill_lv)/100; - damage2 = damage2*(100+ 50*skill_lv)/100; - break; - case AC_DOUBLE: // ダブルストレイフィング - if(!sd->state.arrow_atk && sd->arrow_atk > 0) { - int arr = rand()%(sd->arrow_atk+1); - damage += arr; - damage2 += arr; - } - damage = damage*(180+ 20*skill_lv)/100; - damage2 = damage2*(180+ 20*skill_lv)/100; - if(sd->arrow_ele > 0) { - s_ele = sd->arrow_ele; - s_ele_ = sd->arrow_ele; - } - flag=(flag&~BF_RANGEMASK)|BF_LONG; - sd->state.arrow_atk = 1; - break; - case AC_SHOWER: // アローシャワー - if(!sd->state.arrow_atk && sd->arrow_atk > 0) { - int arr = rand()%(sd->arrow_atk+1); - damage += arr; - damage2 += arr; - } - damage = damage*(75 + 5*skill_lv)/100; - damage2 = damage2*(75 + 5*skill_lv)/100; - if(sd->arrow_ele > 0) { - s_ele = sd->arrow_ele; - s_ele_ = sd->arrow_ele; - } - flag=(flag&~BF_RANGEMASK)|BF_LONG; - sd->state.arrow_atk = 1; - break; - case AC_CHARGEARROW: // チャージアロー - if(!sd->state.arrow_atk && sd->arrow_atk > 0) { - int arr = rand()%(sd->arrow_atk+1); - damage += arr; - damage2 += arr; - } - damage = damage*150/100; - damage2 = damage2*150/100; - if(sd->arrow_ele > 0) { - s_ele = sd->arrow_ele; - s_ele_ = sd->arrow_ele; - } - flag=(flag&~BF_RANGEMASK)|BF_LONG; - sd->state.arrow_atk = 1; - break; - case KN_PIERCE: // ピアース - damage = damage*(100+ 10*skill_lv)/100; - damage2 = damage2*(100+ 10*skill_lv)/100; - hitrate=hitrate*(100+5*skill_lv)/100; - div_=t_size+1; - div_flag=1; - break; - case KN_SPEARSTAB: // スピアスタブ - damage = damage*(100+ 15*skill_lv)/100; - damage2 = damage2*(100+ 15*skill_lv)/100; - blewcount=0; - break; - case KN_SPEARBOOMERANG: // スピアブーメラン - damage = damage*(100+ 50*skill_lv)/100; - damage2 = damage2*(100+ 50*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case KN_BRANDISHSPEAR: // ブランディッシュスピア - damage = damage*(100+ 20*skill_lv)/100; - damage2 = damage2*(100+ 20*skill_lv)/100; - if(skill_lv>3 && wflag==1) damage3+=damage/2; - if(skill_lv>6 && wflag==1) damage3+=damage/4; - if(skill_lv>9 && wflag==1) damage3+=damage/8; - if(skill_lv>6 && wflag==2) damage3+=damage/2; - if(skill_lv>9 && wflag==2) damage3+=damage/4; - if(skill_lv>9 && wflag==3) damage3+=damage/2; - damage +=damage3; - if(skill_lv>3 && wflag==1) damage4+=damage2/2; - if(skill_lv>6 && wflag==1) damage4+=damage2/4; - if(skill_lv>9 && wflag==1) damage4+=damage2/8; - if(skill_lv>6 && wflag==2) damage4+=damage2/2; - if(skill_lv>9 && wflag==2) damage4+=damage2/4; - if(skill_lv>9 && wflag==3) damage4+=damage2/2; - damage2 +=damage4; - break; - case KN_BOWLINGBASH: // ボウリングバッシュ - damage = damage*(100+ 50*skill_lv)/100; - damage2 = damage2*(100+ 50*skill_lv)/100; - blewcount=0; - break; - case KN_AUTOCOUNTER: - if(battle_config.pc_auto_counter_type&1) - hitrate += 20; - else - hitrate = 1000000; - flag=(flag&~BF_SKILLMASK)|BF_NORMAL; - break; - case AS_GRIMTOOTH: - damage = damage*(100+ 20*skill_lv)/100; - damage2 = damage2*(100+ 20*skill_lv)/100; - break; - case AS_POISONREACT: // celest - s_ele = 0; - damage = damage*(100+ 30*skill_lv)/100; - damage2 = damage2*(100+ 30*skill_lv)/100; - break; - case AS_SONICBLOW: // ソニックブロウ - hitrate+=30; // hitrate +30, thanks to midas - damage = damage*(300+ 50*skill_lv)/100; - damage2 = damage2*(300+ 50*skill_lv)/100; - break; - case TF_SPRINKLESAND: // 砂まき - damage = damage*125/100; - damage2 = damage2*125/100; - break; - case MC_CARTREVOLUTION: // カートレボリューション - if(sd->cart_max_weight > 0 && sd->cart_weight > 0) { - damage = ( damage*(150 + sd->cart_weight/800) )/100; //fixed CARTREV damage [Lupus] // should be 800, not 80... weight is *10 ^_- [celest] - damage2 = ( damage2*(150 + sd->cart_weight/800) )/100; - //damage = (damage*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100; - //damage2 = (damage2*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100; - } - else { - damage = (damage*150)/100; - damage2 = (damage2*150)/100; - } - break; - // 以下MOB - case NPC_COMBOATTACK: // 多段攻撃 - div_flag=1; - break; - case NPC_RANDOMATTACK: // ランダムATK攻撃 - damage = damage*(50+rand()%150)/100; - damage2 = damage2*(50+rand()%150)/100; - break; - // 属性攻撃(適当) - case NPC_WATERATTACK: - case NPC_GROUNDATTACK: - case NPC_FIREATTACK: - case NPC_WINDATTACK: - case NPC_POISONATTACK: - case NPC_HOLYATTACK: - case NPC_DARKNESSATTACK: - case NPC_UNDEADATTACK: - case NPC_TELEKINESISATTACK: - damage = damage*(100+25*skill_lv)/100; - damage2 = damage2*(100+25*skill_lv)/100; - break; - case NPC_GUIDEDATTACK: - hitrate = 1000000; - break; - case NPC_RANGEATTACK: - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case NPC_PIERCINGATT: - flag=(flag&~BF_RANGEMASK)|BF_SHORT; - break; - case RG_BACKSTAP: // バックスタブ - if(battle_config.backstab_bow_penalty == 1 && sd->status.weapon == 11){ - damage = (damage*(300+ 40*skill_lv)/100)/2; - damage2 = (damage2*(300+ 40*skill_lv)/100)/2; - }else{ - damage = damage*(300+ 40*skill_lv)/100; - damage2 = damage2*(300+ 40*skill_lv)/100; - } - hitrate = 1000000; - break; - case RG_RAID: // サプライズアタック - damage = damage*(100+ 40*skill_lv)/100; - damage2 = damage2*(100+ 40*skill_lv)/100; - break; - case RG_INTIMIDATE: // インティミデイト - damage = damage*(100+ 30*skill_lv)/100; - damage2 = damage2*(100+ 30*skill_lv)/100; - break; - case CR_SHIELDCHARGE: // シールドチャージ - damage = damage*(100+ 20*skill_lv)/100; - damage2 = damage2*(100+ 20*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_SHORT; - s_ele = 0; - break; - case CR_SHIELDBOOMERANG: // シールドブーメラン - damage = damage*(100+ 30*skill_lv)/100; - damage2 = damage2*(100+ 30*skill_lv)/100; - flag=(flag&~BF_RANGEMASK)|BF_LONG; - s_ele = 0; - break; - case CR_HOLYCROSS: // ホーリークロス - damage = damage*(100+ 35*skill_lv)/100; - damage2 = damage2*(100+ 35*skill_lv)/100; - break; - case CR_GRANDCROSS: - hitrate= 1000000; - if(!battle_config.gx_cardfix) - - no_cardfix = 1; - break; - case AM_DEMONSTRATION: // デモンストレーション - damage = damage*(100+ 20*skill_lv)/100; - damage2 = damage2*(100+ 20*skill_lv)/100; - no_cardfix = 1; - break; - case AM_ACIDTERROR: // アシッドテラー - hitrate = 1000000; - damage = damage*(100+ 40*skill_lv)/100; - damage2 = damage2*(100+ 40*skill_lv)/100; - s_ele = 0; - s_ele_ = 0; - no_cardfix = 1; - break; - case MO_FINGEROFFENSIVE: //指弾 - damage = damage * (125 + 25 * skill_lv) / 100; - damage2 = damage2 * (125 + 25 * skill_lv) / 100; - if(battle_config.finger_offensive_type == 0) { - div_ = sd->spiritball_old; - div_flag = 1; - } - else div_ = 1; - flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn - break; - case MO_INVESTIGATE: // 発 勁 - if(def1 < 1000000) { - damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50; - damage2 = damage2*(100+ 75*skill_lv)/100 * (def1 + def2)/50; - } - hitrate = 1000000; - s_ele = 0; - s_ele_ = 0; - break; - case MO_EXTREMITYFIST: // 阿修羅覇鳳拳 - damage = damage * (8 + ((sd->status.sp)/10)) + 250 + (skill_lv * 150); - damage2 = damage2 * (8 + ((sd->status.sp)/10)) + 250 + (skill_lv * 150); - sd->status.sp = 0; - clif_updatestatus(sd,SP_SP); - hitrate = 1000000; - s_ele = 0; - s_ele_ = 0; - break; - case MO_CHAINCOMBO: // 連打掌 - damage = damage*(150+ 50*skill_lv)/100; - damage2 = damage2*(150+ 50*skill_lv)/100; - break; - case MO_COMBOFINISH: // 猛龍拳 - damage = damage*(240+ 60*skill_lv)/100; - damage2 = damage2*(240+ 60*skill_lv)/100; - break; - case BA_MUSICALSTRIKE: // ミュージカルストライク - damage = damage*(60+ 40 * skill_lv)/100; - damage2 = damage2*(60+ 40 * skill_lv)/100; - if(sd->arrow_ele > 0) { - s_ele = sd->arrow_ele; - s_ele_ = sd->arrow_ele; - } - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case DC_THROWARROW: // 矢撃ち - if(!sd->state.arrow_atk && sd->arrow_atk > 0) { - int arr = rand()%(sd->arrow_atk+1); - damage += arr; - damage2 += arr; - } - damage = damage*(100+ 50 * skill_lv)/100; - damage2 = damage2*(100+ 50 * skill_lv)/100; - if(sd->arrow_ele > 0) { - s_ele = sd->arrow_ele; - s_ele_ = sd->arrow_ele; - } - flag=(flag&~BF_RANGEMASK)|BF_LONG; - sd->state.arrow_atk = 1; - break; - case CH_TIGERFIST: // 伏虎拳 - damage = damage*(40+ 100*skill_lv)/100; - damage2 = damage*(40+ 100*skill_lv)/100; - break; - case CH_CHAINCRUSH: // 連柱崩撃 - damage = damage*(400+ 100*skill_lv)/100; - damage2 = damage*(400+ 100*skill_lv)/100; - break; - case CH_PALMSTRIKE: // 猛虎硬派山 - damage = damage*(200+ 100*skill_lv)/100; - damage2 = damage*(200+ 100*skill_lv)/100; - break; - case LK_SPIRALPIERCE: /* スパイラルピアース */ - damage = damage*(100+ 50*skill_lv)/100; //増加量が分からないので適当に - damage2 = damage2*(100+ 50*skill_lv)/100; //増加量が分からないので適当に - flag=(flag&~BF_RANGEMASK)|BF_LONG; - if(tsd) - tsd->canmove_tick = gettick() + 1000; - else if(tmd) - tmd->canmove_tick = gettick() + 1000; - break; - case LK_HEADCRUSH: /* ヘッドクラッシュ */ - damage = damage*(100+ 40*skill_lv)/100; - damage2 = damage2*(100+ 40*skill_lv)/100; - break; - case LK_JOINTBEAT: /* ジョイントビート */ - damage = damage*(50+ 10*skill_lv)/100; - damage2 = damage2*(50+ 10*skill_lv)/100; - break; - case ASC_METEORASSAULT: /* メテオアサルト */ - damage = damage*(40+ 40*skill_lv)/100; - damage2 = damage2*(40+ 40*skill_lv)/100; - no_cardfix = 1; - break; - case SN_SHARPSHOOTING: /* シャープシューティング */ - damage += damage*(30*skill_lv)/100; - damage2 += damage2*(30*skill_lv)/100; - break; - case CG_ARROWVULCAN: /* アローバルカン */ - damage = damage*(200+100*skill_lv)/100; - damage2 = damage2*(200+100*skill_lv)/100; - if(sd->arrow_ele > 0) { - s_ele = sd->arrow_ele; - s_ele_ = sd->arrow_ele; - } - flag=(flag&~BF_RANGEMASK)|BF_LONG; - break; - case AS_SPLASHER: /* ベナムスプラッシャー */ - damage = damage*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100; - damage2 = damage2*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100; - no_cardfix = 1; - hitrate = 1000000; - break; - case ASC_BREAKER: // -- moonsoul (special damage for ASC_BREAKER skill) - if(sd){ - // calculate physical part of damage -#ifndef TWILIGHT - damage = damage * skill_lv; - damage2 = damage2 * skill_lv; -#else /* TWILIGHT */ - damage = damage * skill_lv * 0.5; //Halved by Krel - damage2 = damage2 * skill_lv * 0.5; //Halved by Krel - // element modifier added right after this - - // calculate magic part of damage - damage3 = skill_lv * status_get_int(src) * 5 * 0.5; //Krel - // ignores magic defense now [Celest] - /*if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race)) - imdef_flag = 1; - if(t_mode & 0x20) { - if(sd->ignore_mdef_race & (1<<10)) - imdef_flag = 1; - } - else { - if(sd->ignore_mdef_race & (1<<11)) - imdef_flag = 1; - } - if(!imdef_flag){ - if(battle_config.magic_defense_type) { - damage3 = damage3 - (mdef1 * battle_config.magic_defense_type) - mdef2; - } - else{ - damage3 = (damage3*(100-mdef1))/100 - mdef2; - } - } - - if(damage3<1) - damage3=1; - - damage3=battle_attr_fix(damage2,s_ele_, status_get_element(target) );*/ - -#endif /* TWILIGHT */ - flag=(flag&~BF_RANGEMASK)|BF_LONG; - } - break; - } - if (div_flag && div_ > 1) { // [Skotlex] - damage *= div_; - damage2 *= div_; - } - if (sd && skill_num > 0 && sd->skillatk[0] == skill_num) - damage += damage*sd->skillatk[1]/100; - } - if(da == 2) { //三段掌が発動しているか - type = 0x08; - div_ = 255; //三段掌用に… - damage = damage * (100 + 20 * pc_checkskill(sd, MO_TRIPLEATTACK)) / 100; - } - - if( skill_num!=NPC_CRITICALSLASH ){ - // 対 象の防御力によるダメージの減少 - // ディバインプロテクション(ここでいいのかな?) - if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT無視 - int t_def; - target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv); - if(battle_config.vit_penalty_type > 0) { - if(target_count >= battle_config.vit_penalty_count) { - if(battle_config.vit_penalty_type == 1) { - def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - } - else if(battle_config.vit_penalty_type == 2) { - def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - } - if(def1 < 0) def1 = 0; - if(def2 < 1) def2 = 1; - if(t_vit < 1) t_vit = 1; - } - } - t_def = def2*8/10; - vitbonusmax = (t_vit/20)*(t_vit/20)-1; - if (tmd) { - if(t_mode & 0x20) { - if(sd->ignore_def_mob & 2) - idef_flag = 1; - if(sd->ignore_def_mob_ & 2) - idef_flag_ = 1; - } else { - if(sd->ignore_def_mob & 1) - idef_flag = 1; - if(sd->ignore_def_mob_ & 1) - idef_flag_ = 1; - } - } - if(sd->ignore_def_ele & (1<<t_ele) || sd->ignore_def_race & (1<<t_race)) - idef_flag = 1; - if(sd->ignore_def_ele_ & (1<<t_ele) || sd->ignore_def_race_ & (1<<t_race)) - idef_flag_ = 1; - if(t_mode & 0x20) { - if(sd->ignore_def_race & (1<<10)) - idef_flag = 1; - if(sd->ignore_def_race_ & (1<<10)) - idef_flag_ = 1; - } - else { - if(sd->ignore_def_race & (1<<11)) - idef_flag = 1; - if(sd->ignore_def_race_ & (1<<11)) - idef_flag_ = 1; - } - - if(!idef_flag){ - if(battle_config.player_defense_type) { - damage = damage - (def1 * battle_config.player_defense_type) - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - else{ - damage = damage * (100 - def1) /100 - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - } - if(!idef_flag_){ - if(battle_config.player_defense_type) { - damage2 = damage2 - (def1 * battle_config.player_defense_type) - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - else{ - damage2 = damage2 * (100 - def1) /100 - t_def - ((vitbonusmax < 1)?0: rand()%(vitbonusmax+1) ); - } - } - } - } - } - - // 状態異常中のダメージ追加でクリティカルにも有効なスキル - if (sc_data) { - // エンチャントデッドリーポイズン - if(!no_cardfix && sc_data[SC_EDP].timer != -1 && skill_num != ASC_BREAKER && skill_num != ASC_METEORASSAULT) { - damage += damage * (150 + sc_data[SC_EDP].val1 * 50) / 100; - no_cardfix = 1; - } - // sacrifice works on boss monsters, and does 9% damage to self [Celest] - if (!skill_num && /*!(t_mode&0x20) &&*/ sc_data[SC_SACRIFICE].timer != -1) { - int mhp = status_get_max_hp(src); - int dmg = mhp * 9/100; - pc_heal(sd, -dmg, 0); - damage = dmg * (90 + sc_data[SC_SACRIFICE].val1 * 10) / 100; - damage2 = 0; - hitrate = 1000000; - s_ele = 0; - s_ele_ = 0; - skill_num = PA_SACRIFICE; - //clif_skill_nodamage(src,target,skill_num,skill_lv,1); // this doesn't show effect either.. hmm =/ - sc_data[SC_SACRIFICE].val2 --; - if (sc_data[SC_SACRIFICE].val2 == 0) - status_change_end(src, SC_SACRIFICE,-1); - } - } - - // 精錬ダメージの追加 - if( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST) { //DEF, VIT無視 - damage += status_get_atk2(src); - damage2 += status_get_atk_2(src); - } - if(skill_num == CR_SHIELDBOOMERANG) { - if(sd->equip_index[8] >= 0) { - int index = sd->equip_index[8]; - if(sd->inventory_data[index] && sd->inventory_data[index]->type == 5) { - damage += sd->inventory_data[index]->weight/10; - damage += sd->status.inventory[index].refine * status_getrefinebonus(0,1); - } - } - } - if(skill_num == LK_SPIRALPIERCE) { /* スパイラルピアース */ - if(sd->equip_index[9] >= 0) { //重量で追加ダメージらしいのでシールドブーメランを参考に追加 - int index = sd->equip_index[9]; - if(sd->inventory_data[index] && sd->inventory_data[index]->type == 4) { - damage += (int)(double)(sd->inventory_data[index]->weight*(0.8*skill_lv*4/10)); - damage += sd->status.inventory[index].refine * status_getrefinebonus(0,1); - } - } - } - - // 0未満だった場合1に補正 - if(damage<1) damage=1; - if(damage2<1) damage2=1; - - // スキル修正2(修練系) - // 修練ダメージ(右手のみ) ソニックブロー時は別処理(1撃に付き1/8適応) - if( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != CR_GRANDCROSS) { //修練ダメージ無視 - damage = battle_addmastery(sd,target,damage,0); - damage2 = battle_addmastery(sd,target,damage2,1); - } - - if(sd->perfect_hit > 0) { - if(rand()%100 < sd->perfect_hit) - hitrate = 1000000; - } - - // 回避修正 - if( hitrate < 1000000 && t_sc_data ) { // 必中攻撃 - if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG) - hitrate -= 75; - if (t_sc_data[SC_SLEEP].timer!=-1 || // 睡眠は必中 - t_sc_data[SC_STAN].timer!=-1 || // スタンは必中 - t_sc_data[SC_FREEZE].timer!=-1 || - (t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // 凍結は必中 - hitrate = 1000000; - } - hitrate = (hitrate<5)?5:hitrate; - if(type == 0 && rand()%100 >= hitrate) { - damage = damage2 = 0; - dmg_lv = ATK_FLEE; - } else { - dmg_lv = ATK_DEF; - } - - // スキル修正3(武器研究) - if( (skill=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0) { - damage+= skill*2; - damage2+= skill*2; - } - //Advanced Katar Research by zanetheinsane - if(sd->weapontype1 == 0x10 || sd->weapontype2 == 0x10){ - if((skill = pc_checkskill(sd,ASC_KATAR)) > 0) { - damage += damage*(10+(skill * 2))/100; - } - } - -//スキルによるダメージ補正ここまで - -//カードによるダメージ追加処理ここから - cardfix=100; - if(!sd->state.arrow_atk) { //弓矢以外 - if(!battle_config.left_cardfix_to_right) { //左手カード補正設定無し - cardfix=cardfix*(100+sd->addrace[t_race])/100; // 種族によるダメージ修正 - cardfix=cardfix*(100+sd->addele[t_ele])/100; // 属性によるダメージ修正 - cardfix=cardfix*(100+sd->addsize[t_size])/100; // サイズによるダメージ修正 - cardfix=cardfix*(100+sd->addrace2[t_race2])/100; - } - else { - cardfix=cardfix*(100+sd->addrace[t_race]+sd->addrace_[t_race])/100; // 種族によるダメージ修正(左手による追加あり) - cardfix=cardfix*(100+sd->addele[t_ele]+sd->addele_[t_ele])/100; // 属性によるダメージ修正(左手による追加あり) - cardfix=cardfix*(100+sd->addsize[t_size]+sd->addsize_[t_size])/100; // サイズによるダメージ修正(左手による追加あり) - cardfix=cardfix*(100+sd->addrace2[t_race2]+sd->addrace2_[t_race2])/100; - } - } - else { //弓矢 - cardfix=cardfix*(100+sd->addrace[t_race]+sd->arrow_addrace[t_race])/100; // 種族によるダメージ修正(弓矢による追加あり) - cardfix=cardfix*(100+sd->addele[t_ele]+sd->arrow_addele[t_ele])/100; // 属性によるダメージ修正(弓矢による追加あり) - cardfix=cardfix*(100+sd->addsize[t_size]+sd->arrow_addsize[t_size])/100; // サイズによるダメージ修正(弓矢による追加あり) - cardfix=cardfix*(100+sd->addrace2[t_race2])/100; - } - if(t_mode & 0x20) { //ボス - if(!sd->state.arrow_atk) { //弓矢攻撃以外なら - if(!battle_config.left_cardfix_to_right) //左手カード補正設定無し - cardfix=cardfix*(100+sd->addrace[10])/100; //ボスモンスターに追加ダメージ - else //左手カード補正設定あり - cardfix=cardfix*(100+sd->addrace[10]+sd->addrace_[10])/100; //ボスモンスターに追加ダメージ(左手による追加あり) - } - else //弓矢攻撃 - cardfix=cardfix*(100+sd->addrace[10]+sd->arrow_addrace[10])/100; //ボスモンスターに追加ダメージ(弓矢による追加あり) - } - else { //ボスじゃない - if(!sd->state.arrow_atk) { //弓矢攻撃以外 - if(!battle_config.left_cardfix_to_right) //左手カード補正設定無し - cardfix=cardfix*(100+sd->addrace[11])/100; //ボス以外モンスターに追加ダメージ - else //左手カード補正設定あり - cardfix=cardfix*(100+sd->addrace[11]+sd->addrace_[11])/100; //ボス以外モンスターに追加ダメージ(左手による追加あり) - } - else - cardfix=cardfix*(100+sd->addrace[11]+sd->arrow_addrace[11])/100; //ボス以外モンスターに追加ダメージ(弓矢による追加あり) - } - //特定Class用補正処理(少女の日記→ボンゴン用?) - t_class = status_get_class(target); - for(i=0;i<sd->add_damage_class_count;i++) { - if(sd->add_damage_classid[i] == t_class) { - cardfix=cardfix*(100+sd->add_damage_classrate[i])/100; - break; - } - } - if(!no_cardfix) - damage=damage*cardfix/100; //カード補正によるダメージ増加 -//カードによるダメージ増加処理ここまで - -//カードによるダメージ追加処理(左手)ここから - cardfix=100; - if(!battle_config.left_cardfix_to_right) { //左手カード補正設定無し - cardfix=cardfix*(100+sd->addrace_[t_race])/100; // 種族によるダメージ修正左手 - cardfix=cardfix*(100+sd->addele_[t_ele])/100; // 属 性によるダメージ修正左手 - cardfix=cardfix*(100+sd->addsize_[t_size])/100; // サイズによるダメージ修正左手 - cardfix=cardfix*(100+sd->addrace2_[t_race2])/100; - if(t_mode & 0x20) //ボス - cardfix=cardfix*(100+sd->addrace_[10])/100; //ボスモンスターに追加ダメージ左手 - else - cardfix=cardfix*(100+sd->addrace_[11])/100; //ボス以外モンスターに追加ダメージ左手 - } - //特定Class用補正処理左手(少女の日記→ボンゴン用?) - for(i=0;i<sd->add_damage_class_count_;i++) { - if(sd->add_damage_classid_[i] == t_class) { - cardfix=cardfix*(100+sd->add_damage_classrate_[i])/100; - break; - } - } - if(!no_cardfix) - damage2=damage2*cardfix/100; - -//カード補正による左手ダメージ増加 -//カードによるダメージ増加処理(左手)ここまで - -//カードによるダメージ減衰処理ここから - if(tsd){ //対象がPCの場合 - cardfix=100; - cardfix=cardfix*(100-tsd->subrace[s_race])/100; // 種族によるダメージ耐性 - cardfix=cardfix*(100-tsd->subele[s_ele])/100; // 属性によるダメージ耐性 - cardfix=cardfix*(100-tsd->subsize[s_size])/100; - if(status_get_mode(src) & 0x20) - cardfix=cardfix*(100-tsd->subrace[10])/100; //ボスからの攻撃はダメージ減少 - else - cardfix=cardfix*(100-tsd->subrace[11])/100; //ボス以外からの攻撃はダメージ減少 - //特定Class用補正処理左手(少女の日記→ボンゴン用?) - for(i=0;i<tsd->add_def_class_count;i++) { - if(tsd->add_def_classid[i] == sd->status.class_) { - cardfix=cardfix*(100-tsd->add_def_classrate[i])/100; - break; - } - } - if(flag&BF_LONG) - cardfix=cardfix*(100-tsd->long_attack_def_rate)/100; //遠距離攻撃はダメージ減少(ホルンCとか) - if(flag&BF_SHORT) - cardfix=cardfix*(100-tsd->near_attack_def_rate)/100; //近距離攻撃はダメージ減少(該当無し?) - damage=damage*cardfix/100; //カード補正によるダメージ減少 - damage2=damage2*cardfix/100; //カード補正による左手ダメージ減少 - } -//カードによるダメージ減衰処理ここまで - -//対象にステータス異常がある場合のダメージ減算処理ここから - if(t_sc_data) { - cardfix=100; - if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG) //ディフェンダー状態で遠距離攻撃 - cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100; //ディフェンダーによる減衰 - if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG) - cardfix=cardfix*50/100; - if(cardfix != 100) { - damage=damage*cardfix/100; //ディフェンダー補正によるダメージ減少 - damage2=damage2*cardfix/100; //ディフェンダー補正による左手ダメージ減少 - } - if(t_sc_data[SC_ASSUMPTIO].timer != -1){ //アスムプティオ - if(!map[target->m].flag.pvp){ - damage=damage/3; - damage2=damage2/3; - }else{ - damage=damage/2; - damage2=damage2/2; - } - } - } -//対象にステータス異常がある場合のダメージ減算処理ここまで - - if(damage < 0) damage = 0; - if(damage2 < 0) damage2 = 0; - - // 属 性の適用 - damage=battle_attr_fix(damage,s_ele, status_get_element(target) ); - damage2=battle_attr_fix(damage2,s_ele_, status_get_element(target) ); - - // 星のかけら、気球の適用 - damage += sd->star; - damage2 += sd->star_; - damage += sd->spiritball*3; - damage2 += sd->spiritball*3; - - //if(sc_data && sc_data[SC_AURABLADE].timer!=-1){ /* オーラブレード 必中 */ - // damage += sc_data[SC_AURABLADE].val1 * 10; - // damage2 += sc_data[SC_AURABLADE].val1 * 10; - //} - if(skill_num==PA_PRESSURE){ /* プレッシャー 必中? */ - damage = 500+300*skill_lv; - damage2 = 500+300*skill_lv; - } - - // >二刀流の左右ダメージ計算誰かやってくれぇぇぇぇえええ! - // >map_session_data に左手ダメージ(atk,atk2)追加して - // >status_calc_pc()でやるべきかな? - // map_session_data に左手武器(atk,atk2,ele,star,atkmods)追加して - // status_calc_pc()でデータを入力しています - - //左手のみ武器装備 - if(sd->weapontype1 == 0 && sd->weapontype2 > 0) { - damage = damage2; - damage2 = 0; - } - - // 右手、左手修練の適用 - if(sd->status.weapon > 16) {// 二刀流か? - int dmg = damage, dmg2 = damage2; - // 右手修練(60% 〜 100%) 右手全般 - skill = pc_checkskill(sd,AS_RIGHT); - damage = damage * (50 + (skill * 10))/100; - if(dmg > 0 && damage < 1) damage = 1; - // 左手修練(40% 〜 80%) 左手全般 - skill = pc_checkskill(sd,AS_LEFT); - damage2 = damage2 * (30 + (skill * 10))/100; - if(dmg2 > 0 && damage2 < 1) damage2 = 1; - } - else //二刀流でなければ左手ダメージは0 - damage2 = 0; - - // 右手,短剣のみ - if(da == 1) { //ダブルアタックが発動しているか - div_ = 2; - damage += damage; - type = 0x08; - } - - if(sd->status.weapon == 16) { - // カタール追撃ダメージ - skill = pc_checkskill(sd,TF_DOUBLE); - damage2 = damage * (1 + (skill * 2))/100; - if(damage > 0 && damage2 < 1) damage2 = 1; - } - - // インベナム修正 - if(skill_num==TF_POISON){ - damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) ); - } - if(skill_num==MC_CARTREVOLUTION){ - damage = battle_attr_fix(damage, 0, status_get_element(target) ); - } - - // 完全回避の判定 - if(skill_num == 0 && tsd!=NULL && div_ < 255 && rand()%1000 < status_get_flee2(target) ){ - damage=damage2=0; - type=0x0b; - dmg_lv = ATK_LUCKY; - } - - // 対象が完全回避をする設定がONなら - if(battle_config.enemy_perfect_flee) { - if(skill_num == 0 && tmd!=NULL && div_ < 255 && rand()%1000 < status_get_flee2(target) ) { - damage=damage2=0; - type=0x0b; - dmg_lv = ATK_LUCKY; - } - } - - //MobのModeに頑強フラグが立っているときの処理 - if(t_mode&0x40){ - if(damage > 0) - damage = 1; - if(damage2 > 0) - damage2 = 1; - } - - //bNoWeaponDamage(設定アイテム無し?)でグランドクロスじゃない場合はダメージが0 - if( tsd && tsd->special_state.no_weapon_damage && skill_num != CR_GRANDCROSS) - damage = damage2 = 0; - - if(skill_num != CR_GRANDCROSS && (damage > 0 || damage2 > 0) ) { - if(damage2<1) // ダメージ最終修正 - damage=battle_calc_damage(src,target,damage,div_,skill_num,skill_lv,flag); - else if(damage<1) // 右手がミス? - damage2=battle_calc_damage(src,target,damage2,div_,skill_num,skill_lv,flag); - else { // 両 手/カタールの場合はちょっと計算ややこしい - int d1=damage+damage2,d2=damage2; - damage=battle_calc_damage(src,target,damage+damage2,div_,skill_num,skill_lv,flag); - damage2=(d2*100/d1)*damage/100; - if(damage > 1 && damage2 < 1) damage2=1; - damage-=damage2; - } - } - - /* For executioner card [Valaris] */ - if(src->type == BL_PC && sd->random_attack_increase_add > 0 && sd->random_attack_increase_per > 0 && skill_num == 0 ){ - if(rand()%100 < sd->random_attack_increase_per){ - if(damage >0) damage*=sd->random_attack_increase_add/100; - if(damage2 >0) damage2*=sd->random_attack_increase_add/100; - } - } - /* End addition */ - - // for azoth weapon [Valaris] - if(src->type == BL_PC && target->type == BL_MOB && sd->classchange) { - if(rand()%10000 < sd->classchange) { - int changeclass[]={ - 1001,1002,1004,1005,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1018,1019,1020, - 1021,1023,1024,1025,1026,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1040,1041, - 1042,1044,1045,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1060,1061, - 1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1076,1077,1078,1079,1080,1081,1083, - 1084,1085,1094,1095,1097,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110, - 1111,1113,1114,1116,1117,1118,1119,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130, - 1131,1132,1133,1134,1135,1138,1139,1140,1141,1142,1143,1144,1145,1146,1148,1149,1151, - 1152,1153,1154,1155,1156,1158,1160,1161,1163,1164,1165,1166,1167,1169,1170,1174,1175, - 1176,1177,1178,1179,1180,1182,1183,1184,1185,1188,1189,1191,1192,1193,1194,1195,1196, - 1197,1199,1200,1201,1202,1204,1205,1206,1207,1208,1209,1211,1212,1213,1214,1215,1216, - 1219,1242,1243,1245,1246,1247,1248,1249,1250,1253,1254,1255,1256,1257,1258,1260,1261, - 1263,1264,1265,1266,1267,1269,1270,1271,1273,1274,1275,1276,1277,1278,1280,1281,1282, - 1291,1292,1293,1294,1295,1297,1298,1300,1301,1302,1304,1305,1306,1308,1309,1310,1311, - 1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1364,1365,1366,1367,1368,1369, - 1370,1371,1372,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387, - 1390,1391,1392,1400,1401,1402,1403,1404,1405,1406,1408,1409,1410,1412,1413,1415,1416, - 1417,1493,1494,1495,1497,1498,1499,1500,1502,1503,1504,1505,1506,1507,1508,1509,1510, - 1511,1512,1513,1514,1515,1516,1517,1519,1520,1582,1584,1585,1586,1587 }; - mob_class_change(((struct mob_data *)target),changeclass); - } - } - - wd.damage=damage; - wd.damage2=damage2; - wd.type=type; - wd.div_=div_; - wd.amotion=status_get_amotion(src); - if(skill_num == KN_AUTOCOUNTER) - wd.amotion >>= 1; - wd.dmotion=status_get_dmotion(target); - wd.blewcount=blewcount; - wd.flag=flag; - wd.dmg_lv=dmg_lv; - - return wd; -} - -/*========================================== - * 武器ダメージ計算 - *------------------------------------------ - */ -struct Damage battle_calc_weapon_attack( - struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int wflag) -{ - struct Damage wd; - - //return前の処理があるので情報出力部のみ変更 - if (src == NULL || target == NULL) { - nullpo_info(NLP_MARK); - memset(&wd,0,sizeof(wd)); - return wd; - } - - if(target->type == BL_PET) - memset(&wd,0,sizeof(wd)); - - else if(src->type == BL_PC) - wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag); - else if(src->type == BL_MOB) - wd = battle_calc_mob_weapon_attack(src,target,skill_num,skill_lv,wflag); - else if(src->type == BL_PET) - wd = battle_calc_pet_weapon_attack(src,target,skill_num,skill_lv,wflag); - else - memset(&wd,0,sizeof(wd)); - - if(battle_config.equipment_breaking && src->type==BL_PC && (wd.damage > 0 || wd.damage2 > 0)) { - struct map_session_data *sd = (struct map_session_data *)src; - // weapon = 0, armor = 1 - int breakrate = 1; //0.01% default self weapon breaking chance [DracoRPG] - int breakrate_[2] = {0,0}; //enemy breaking chance [celest] - int breaktime = 5000; - - breakrate_[0] += sd->break_weapon_rate; - breakrate_[1] += sd->break_armor_rate; - - if (sd->sc_count) { - if (sd->sc_data[SC_MELTDOWN].timer!=-1) { - breakrate_[0] += 100*sd->sc_data[SC_MELTDOWN].val1; - breakrate_[1] = 70*sd->sc_data[SC_MELTDOWN].val1; - breaktime = skill_get_time2(WS_MELTDOWN,1); - } - if(sd->sc_data[SC_OVERTHRUST].timer!=-1) - breakrate += 10; - } - - if(sd->status.weapon && sd->status.weapon != 11) { - if(rand() % 10000 < breakrate * battle_config.equipment_break_rate / 100 || breakrate >= 10000) - if (pc_breakweapon(sd) == 1) - wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag); - } - if(rand() % 10000 < breakrate_[0] * battle_config.equipment_break_rate / 100 || breakrate_[0] >= 10000) { - if (target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - if(tsd->status.weapon != 11) - pc_breakweapon(tsd); - } else - status_change_start(target,SC_STRIPWEAPON,1,75,0,0,breaktime,0); - } - if(rand() % 10000 < breakrate_[1] * battle_config.equipment_break_rate/100 || breakrate_[1] >= 10000) { - if (target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - if(tsd->status.weapon != 11) - pc_breakarmor(tsd); - } else - status_change_start(target,SC_STRIPSHIELD,1,75,0,0,breaktime,0); - } - } - - return wd; -} - -/*========================================== - * 魔法ダメージ計算 - *------------------------------------------ - */ -struct Damage battle_calc_magic_attack( - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag) - { - int mdef1=status_get_mdef(target); - int mdef2=status_get_mdef2(target); - int matk1,matk2,damage=0,div_=1,blewcount=skill_get_blewcount(skill_num,skill_lv),rdamage = 0; - struct Damage md; - int aflag; - int normalmagic_flag=1; - int matk_flag = 1; - int ele=0,race=7,size=1,race2=7,t_ele=0,t_race=7,t_mode = 0,cardfix,t_class,i; - struct map_session_data *sd=NULL,*tsd=NULL; - struct mob_data *tmd = NULL; - - - //return前の処理があるので情報出力部のみ変更 - if( bl == NULL || target == NULL ){ - nullpo_info(NLP_MARK); - memset(&md,0,sizeof(md)); - return md; - } - - if(target->type == BL_PET) { - memset(&md,0,sizeof(md)); - return md; - } - - matk1=status_get_matk1(bl); - matk2=status_get_matk2(bl); - ele = skill_get_pl(skill_num); - race = status_get_race(bl); - size = status_get_size(bl); - race2 = status_get_race2(bl); - t_ele = status_get_elem_type(target); - t_race = status_get_race(target); - t_mode = status_get_mode(target); - -#define MATK_FIX( a,b ) { matk1=matk1*(a)/(b); matk2=matk2*(a)/(b); } - - if( bl->type==BL_PC && (sd=(struct map_session_data *)bl) ){ - sd->state.attack_type = BF_MAGIC; - if(sd->matk_rate != 100) - MATK_FIX(sd->matk_rate,100); - sd->state.arrow_atk = 0; - } - if( target->type==BL_PC ) - tsd=(struct map_session_data *)target; - else if( target->type==BL_MOB ) - tmd=(struct mob_data *)target; - - aflag=BF_MAGIC|BF_LONG|BF_SKILL; - - if(skill_num > 0){ - switch(skill_num){ // 基本ダメージ計算(スキルごとに処理) - // ヒールor聖体 - case AL_HEAL: - case PR_BENEDICTIO: - damage = skill_calc_heal(bl,skill_lv)/2; - normalmagic_flag=0; - break; - case PR_ASPERSIO: /* アスペルシオ */ - damage = 40; //固定ダメージ - normalmagic_flag=0; - break; - case PR_SANCTUARY: // サンクチュアリ - damage = (skill_lv>6)?388:skill_lv*50; - normalmagic_flag=0; - blewcount|=0x10000; - break; - case ALL_RESURRECTION: - case PR_TURNUNDEAD: // 攻撃リザレクションとターンアンデッド - if(target->type != BL_PC && battle_check_undead(t_race,t_ele)){ - int hp, mhp, thres; - hp = status_get_hp(target); - mhp = status_get_max_hp(target); - thres = (skill_lv * 20) + status_get_luk(bl)+ - status_get_int(bl) + status_get_lv(bl)+ - ((200 - hp * 200 / mhp)); - if(thres > 700) thres = 700; -// if(battle_config.battle_log) -// printf("ターンアンデッド! 確率%d ‰(千分率)\n", thres); - if(rand()%1000 < thres && !(t_mode&0x20)) // 成功 - damage = hp; - else // 失敗 - damage = status_get_lv(bl) + status_get_int(bl) + skill_lv * 10; - } - normalmagic_flag=0; - break; - - case MG_NAPALMBEAT: // ナパームビート(分散計算込み) - MATK_FIX(70+ skill_lv*10,100); - if(flag>0){ - MATK_FIX(1,flag); - }else { - if(battle_config.error_log) - printf("battle_calc_magic_attack(): napam enemy count=0 !\n"); - } - break; - case MG_FIREBALL: // ファイヤーボール - { - const int drate[]={100,90,70}; - if(flag>2) - matk1=matk2=0; - else - MATK_FIX( (95+skill_lv*5)*drate[flag] ,10000 ); - } - break; - case MG_FIREWALL: // ファイヤーウォール -/* - if( (t_ele!=3 && !battle_check_undead(t_race,t_ele)) || target->type==BL_PC ) //PCは火属性でも飛ぶ?そもそもダメージ受ける? - blewcount |= 0x10000; - else - blewcount = 0; -*/ - if((t_ele==3 || battle_check_undead(t_race,t_ele)) && target->type!=BL_PC) - blewcount = 0; - else - blewcount |= 0x10000; - MATK_FIX( 1,2 ); - break; - case MG_THUNDERSTORM: // サンダーストーム - MATK_FIX( 80,100 ); - break; - case MG_FROSTDIVER: // フロストダイバ - MATK_FIX( 100+skill_lv*10, 100); - break; - case WZ_FROSTNOVA: // フロストダイバ - MATK_FIX((100+skill_lv*10)*2/3, 100); - break; - case WZ_FIREPILLAR: // ファイヤーピラー - if(mdef1 < 1000000) - mdef1=mdef2=0; // MDEF無視 - MATK_FIX( 1,5 ); - matk1+=50; - matk2+=50; - break; - case WZ_SIGHTRASHER: - MATK_FIX( 100+skill_lv*20, 100); - break; - case WZ_METEOR: - case WZ_JUPITEL: // ユピテルサンダー - break; - case WZ_VERMILION: // ロードオブバーミリオン - MATK_FIX( skill_lv*20+80, 100 ); - break; - case WZ_WATERBALL: // ウォーターボール - //matk1+= skill_lv*30; - //matk2+= skill_lv*30; - MATK_FIX( 100+skill_lv*30, 100 ); - break; - case WZ_STORMGUST: // ストームガスト - MATK_FIX( skill_lv*40+100 ,100 ); -// blewcount|=0x10000; - break; - case AL_HOLYLIGHT: // ホーリーライト - MATK_FIX( 125,100 ); - break; - case AL_RUWACH: - MATK_FIX( 145,100 ); - break; - case HW_NAPALMVULCAN: // ナパームビート(分散計算込み) - MATK_FIX(70+ skill_lv*10,100); - if(flag>0){ - MATK_FIX(1,flag); - }else { - if(battle_config.error_log) - printf("battle_calc_magic_attack(): napalmvulcan enemy count=0 !\n"); - } - break; - case PF_SOULBURN: // Celest - if (target->type != BL_PC || skill_lv < 5) { - memset(&md,0,sizeof(md)); - return md; - } else if (target->type == BL_PC) { - damage = ((struct map_session_data *)target)->status.sp * 2; - matk_flag = 0; // don't consider matk and matk2 - } - break; - case ASC_BREAKER: - damage = rand()%500 + 500 + skill_lv * status_get_int(bl) * 5; - matk_flag = 0; // don't consider matk and matk2 - break; - } - } - - if(normalmagic_flag){ // 一般魔法ダメージ計算 - int imdef_flag=0; - if (matk_flag) { - if(matk1>matk2) - damage= matk2+rand()%(matk1-matk2+1); - else - damage= matk2; - } - if(sd) { - if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race)) - imdef_flag = 1; - if(t_mode & 0x20) { - if(sd->ignore_mdef_race & (1<<10)) - imdef_flag = 1; - } - else { - if(sd->ignore_mdef_race & (1<<11)) - imdef_flag = 1; - } - } - if(!imdef_flag){ - if(battle_config.magic_defense_type) { - damage = damage - (mdef1 * battle_config.magic_defense_type) - mdef2; - } - else{ - damage = (damage*(100-mdef1))/100 - mdef2; - } - } - - if(damage<1) - damage=1; - } - - if(sd) { - cardfix=100; - cardfix=cardfix*(100+sd->magic_addrace[t_race])/100; - cardfix=cardfix*(100+sd->magic_addele[t_ele])/100; - if(t_mode & 0x20) - cardfix=cardfix*(100+sd->magic_addrace[10])/100; - else - cardfix=cardfix*(100+sd->magic_addrace[11])/100; - t_class = status_get_class(target); - for(i=0;i<sd->add_magic_damage_class_count;i++) { - if(sd->add_magic_damage_classid[i] == t_class) { - cardfix=cardfix*(100+sd->add_magic_damage_classrate[i])/100; - break; - } - } - damage=damage*cardfix/100; - if (skill_num > 0 && sd->skillatk[0] == skill_num) - damage += damage*sd->skillatk[1]/100; - } - - if( tsd ){ - int s_class = status_get_class(bl); - cardfix=100; - cardfix=cardfix*(100-tsd->subele[ele])/100; // 属 性によるダメージ耐性 - cardfix=cardfix*(100-tsd->subrace[race])/100; // 種族によるダメージ耐性 - cardfix=cardfix*(100-tsd->subsize[size])/100; - cardfix=cardfix*(100-tsd->magic_subrace[race])/100; - cardfix=cardfix*(100-tsd->subrace2[race2])/100; // 種族によるダメージ耐性 - if(status_get_mode(bl) & 0x20) - cardfix=cardfix*(100-tsd->magic_subrace[10])/100; - else - cardfix=cardfix*(100-tsd->magic_subrace[11])/100; - for(i=0;i<tsd->add_mdef_class_count;i++) { - if(tsd->add_mdef_classid[i] == s_class) { - cardfix=cardfix*(100-tsd->add_mdef_classrate[i])/100; - break; - } - } - cardfix=cardfix*(100-tsd->magic_def_rate)/100; - damage=damage*cardfix/100; - } - if(damage < 0) damage = 0; - - damage=battle_attr_fix(damage, ele, status_get_element(target) ); // 属 性修正 - - if(skill_num == CR_GRANDCROSS) { // グランドクロス - struct Damage wd; - wd=battle_calc_weapon_attack(bl,target,skill_num,skill_lv,flag); - damage = (damage + wd.damage) * (100 + 40*skill_lv)/100; - if(battle_config.gx_dupele) damage=battle_attr_fix(damage, ele, status_get_element(target) ); //属性2回かかる - if(bl==target) damage=damage/2; //反動は半分 - } - - div_=skill_get_num( skill_num,skill_lv ); - - if(div_>1 && skill_num != WZ_VERMILION) - damage*=div_; - -// if(mdef1 >= 1000000 && damage > 0) - if(t_mode&0x40 && damage > 0) - damage = 1; - - if( tsd && tsd->special_state.no_magic_damage) { - if (battle_config.gtb_pvp_only != 0) { // [MouseJstr] - if ((map[target->m].flag.pvp || map[target->m].flag.gvg) && target->type==BL_PC) - damage = (damage * (100 - battle_config.gtb_pvp_only)) / 100; - } else - damage=0; // 黄 金蟲カード(魔法ダメージ0) - } - - damage=battle_calc_damage(bl,target,damage,div_,skill_num,skill_lv,aflag); // 最終修正 - - /* magic_damage_return by [AppleGirl] and [Valaris] */ - if( target->type==BL_PC && tsd && tsd->magic_damage_return > 0 ){ - rdamage += damage * tsd->magic_damage_return / 100; - if(rdamage < 1) rdamage = 1; - clif_damage(target,bl,gettick(),0,0,rdamage,0,0,0); - battle_damage(target,bl,rdamage,0); - } - /* end magic_damage_return */ - - md.damage=damage; - md.div_=div_; - md.amotion=status_get_amotion(bl); - md.dmotion=status_get_dmotion(target); - md.damage2=0; - md.type=0; - md.blewcount=blewcount; - md.flag=aflag; - - return md; -} - -/*========================================== - * その他ダメージ計算 - *------------------------------------------ - */ -struct Damage battle_calc_misc_attack( - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag) -{ - int int_=status_get_int(bl); -// int luk=status_get_luk(bl); - int dex=status_get_dex(bl); - int skill,ele,race,size,cardfix,race2; - struct map_session_data *sd=NULL,*tsd=NULL; - int damage=0,div_=1,blewcount=skill_get_blewcount(skill_num,skill_lv); - struct Damage md; - int damagefix=1; - - int aflag=BF_MISC|BF_SHORT|BF_SKILL; - - //return前の処理があるので情報出力部のみ変更 - if( bl == NULL || target == NULL ){ - nullpo_info(NLP_MARK); - memset(&md,0,sizeof(md)); - return md; - } - - if(target->type == BL_PET) { - memset(&md,0,sizeof(md)); - return md; - } - - if( bl->type == BL_PC && (sd=(struct map_session_data *)bl) ) { - sd->state.attack_type = BF_MISC; - sd->state.arrow_atk = 0; - } - - if( target->type==BL_PC ) - tsd=(struct map_session_data *)target; - - switch(skill_num){ - - case HT_LANDMINE: // ランドマイン - damage=skill_lv*(dex+75)*(100+int_)/100; - break; - - case HT_BLASTMINE: // ブラストマイン - damage=skill_lv*(dex/2+50)*(100+int_)/100; - break; - - case HT_CLAYMORETRAP: // クレイモアートラップ - damage=skill_lv*(dex/2+75)*(100+int_)/100; - break; - - case HT_BLITZBEAT: // ブリッツビート - if( sd==NULL || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0) - skill=0; - damage=(dex/10+int_/2+skill*3+40)*2; - if(flag > 1) - damage /= flag; - aflag |= (flag&~BF_RANGEMASK)|BF_LONG; - break; - - case TF_THROWSTONE: // 石投げ - damage=50; - damagefix=0; - aflag |= (flag&~BF_RANGEMASK)|BF_LONG; - break; - - case BA_DISSONANCE: // 不協和音 - damage=(skill_lv)*20+pc_checkskill(sd,BA_MUSICALLESSON)*3; - break; - - case NPC_SELFDESTRUCTION: // 自爆 - damage=status_get_hp(bl)-(bl==target?1:0); - damagefix=0; - break; - - case NPC_SMOKING: // タバコを吸う - damage=3; - damagefix=0; - break; - - case NPC_DARKBREATH: - { - struct status_change *sc_data = status_get_sc_data(target); - int hitrate=status_get_hit(bl) - status_get_flee(target) + 80; - hitrate = ( (hitrate>95)?95: ((hitrate<5)?5:hitrate) ); - if(sc_data && (sc_data[SC_SLEEP].timer!=-1 || sc_data[SC_STAN].timer!=-1 || - sc_data[SC_FREEZE].timer!=-1 || (sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) ) ) - hitrate = 1000000; - if(rand()%100 < hitrate) { - damage = 500 + (skill_lv-1)*1000 + rand()%1000; - if(damage > 9999) damage = 9999; - } - } - break; - case SN_FALCONASSAULT: /* ファルコンアサルト */ -#ifdef TWILIGHT - if( sd==NULL || (skill = pc_checkskill(sd,HT_BLITZBEAT)) <= 0) - skill=0; - damage=(100+50*skill_lv+(dex/10+int_/2+skill*3+40)*2) * 2; -#else - if( sd==NULL || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0) - skill=0; - damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100; // [Celest] -#endif - if(flag > 1) - damage /= flag; - aflag |= (flag&~BF_RANGEMASK)|BF_LONG; - break; - } - - ele = skill_get_pl(skill_num); - race = status_get_race(bl); - size = status_get_size(bl); - race2 = status_get_race(bl); - - if(damagefix){ - if(damage<1 && skill_num != NPC_DARKBREATH) - damage=1; - - if( tsd ){ - cardfix=100; - cardfix=cardfix*(100-tsd->subele[ele])/100; // 属性によるダメージ耐性 - cardfix=cardfix*(100-tsd->subrace[race])/100; // 種族によるダメージ耐性 - cardfix=cardfix*(100-tsd->subsize[size])/100; - cardfix=cardfix*(100-tsd->misc_def_rate)/100; - cardfix=cardfix*(100-tsd->subrace2[race2])/100; - damage=damage*cardfix/100; - } - if (sd && skill_num > 0 && sd->skillatk[0] == skill_num) - damage += damage*sd->skillatk[1]/100; - - if(damage < 0) damage = 0; - damage=battle_attr_fix(damage, ele, status_get_element(target) ); // 属性修正 - } - - div_=skill_get_num( skill_num,skill_lv ); - if(div_>1) - damage*=div_; - - if(damage > 0 && (damage < div_ || (status_get_def(target) >= 1000000 && status_get_mdef(target) >= 1000000) ) ) { - damage = div_; - } - - if(status_get_mode(target)&0x40 && damage>0) - damage = 1; - - damage=battle_calc_damage(bl,target,damage,div_,skill_num,skill_lv,aflag); // 最終修正 - - md.damage=damage; - md.div_=div_; - md.amotion=status_get_amotion(bl); - md.dmotion=status_get_dmotion(target); - md.damage2=0; - md.type=0; - md.blewcount=blewcount; - md.flag=aflag; - return md; - -} -/*========================================== - * ダメージ計算一括処理用 - *------------------------------------------ - */ -struct Damage battle_calc_attack( int attack_type, - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag) -{ - struct Damage d; - switch(attack_type){ - case BF_WEAPON: - return battle_calc_weapon_attack(bl,target,skill_num,skill_lv,flag); - case BF_MAGIC: - return battle_calc_magic_attack(bl,target,skill_num,skill_lv,flag); - case BF_MISC: - return battle_calc_misc_attack(bl,target,skill_num,skill_lv,flag); - default: - if(battle_config.error_log) - printf("battle_calc_attack: unknwon attack type ! %d\n",attack_type); - memset(&d,0,sizeof(d)); - break; - } - return d; -} -/*========================================== - * 通常攻撃処理まとめ - *------------------------------------------ - */ -int battle_weapon_attack( struct block_list *src,struct block_list *target, - unsigned int tick,int flag) -{ - struct map_session_data *sd=NULL; - struct status_change *sc_data = status_get_sc_data(src),*t_sc_data=status_get_sc_data(target); - short *opt1; - int race = 7, ele = 0; - int damage,rdamage = 0; - struct Damage wd; - - nullpo_retr(0, src); - nullpo_retr(0, target); - - if(src->type == BL_PC) - sd = (struct map_session_data *)src; - - if(src->prev == NULL || target->prev == NULL) - return 0; - if(src->type == BL_PC && pc_isdead(sd)) - return 0; - if(target->type == BL_PC && pc_isdead((struct map_session_data *)target)) - return 0; - - opt1=status_get_opt1(src); - if(opt1 && *opt1 > 0) { - battle_stopattack(src); - return 0; - } - if(sc_data && sc_data[SC_BLADESTOP].timer!=-1){ - battle_stopattack(src); - return 0; - } - - if(battle_check_target(src,target,BCT_ENEMY) <= 0 && - !battle_check_range(src,target,0)) - return 0; // 攻撃対象外 - - race = status_get_race(target); - ele = status_get_elem_type(target); - if(battle_check_target(src,target,BCT_ENEMY) > 0 && - battle_check_range(src,target,0)){ - // 攻撃対象となりうるので攻撃 - if(sd && sd->status.weapon == 11) { - if(sd->equip_index[10] >= 0) { - if(battle_config.arrow_decrement) - pc_delitem(sd,sd->equip_index[10],1,0); - } - else { - clif_arrow_fail(sd,0); - return 0; - } - } - if(flag&0x8000) { - if(sd && battle_config.pc_attack_direction_change) - sd->dir = sd->head_dir = map_calc_dir(src, target->x,target->y ); - else if(src->type == BL_MOB && battle_config.monster_attack_direction_change) - ((struct mob_data *)src)->dir = map_calc_dir(src, target->x,target->y ); - wd=battle_calc_weapon_attack(src,target,KN_AUTOCOUNTER,flag&0xff,0); - } - else if(flag&AS_POISONREACT && sc_data && sc_data[SC_POISONREACT].timer!=-1) { - wd=battle_calc_weapon_attack(src,target,AS_POISONREACT,sc_data[SC_POISONREACT].val1,0); - } - else - wd=battle_calc_weapon_attack(src,target,0,0,0); - if((damage = wd.damage + wd.damage2) > 0 && src != target) { - if(wd.flag&BF_SHORT) { - if(target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - if(tsd && tsd->short_weapon_damage_return > 0) { - rdamage += damage * tsd->short_weapon_damage_return / 100; - if(rdamage < 1) rdamage = 1; - } - } - if(t_sc_data && t_sc_data[SC_REFLECTSHIELD].timer != -1) { - rdamage += damage * t_sc_data[SC_REFLECTSHIELD].val2 / 100; - if(rdamage < 1) rdamage = 1; - } - } - else if(wd.flag&BF_LONG) { - if(target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - if(tsd && tsd->long_weapon_damage_return > 0) { - rdamage += damage * tsd->long_weapon_damage_return / 100; - if(rdamage < 1) rdamage = 1; - } - } - } - if(rdamage > 0) - clif_damage(src,src,tick,wd.amotion,wd.dmotion,rdamage,1,4,0); - } - - if (wd.div_ == 255 && sd) { //三段掌 - int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - int skilllv; - if(wd.damage+wd.damage2 < status_get_hp(target)) { - if((skilllv = pc_checkskill(sd, MO_CHAINCOMBO)) > 0) - delay += 300 * battle_config.combo_delay_rate /100; //追加ディレイをconfにより調整 - - status_change_start(src,SC_COMBO,MO_TRIPLEATTACK,skilllv,0,0,delay,0); - } - sd->attackabletime = sd->canmove_tick = tick + delay; - clif_combo_delay(src,delay); - clif_skill_damage(src , target , tick , wd.amotion , wd.dmotion , - wd.damage , 3 , MO_TRIPLEATTACK, pc_checkskill(sd,MO_TRIPLEATTACK) , -1 ); - } - else { - clif_damage(src,target,tick, wd.amotion, wd.dmotion, - wd.damage, wd.div_ , wd.type, wd.damage2); - //二刀流左手とカタール追撃のミス表示(無理やり〜) - if(sd && sd->status.weapon >= 16 && wd.damage2 == 0) - clif_damage(src,target,tick+10, wd.amotion, wd.dmotion,0, 1, 0, 0); - } - if(sd && sd->splash_range > 0 && (wd.damage > 0 || wd.damage2 > 0) ) - skill_castend_damage_id(src,target,0,-1,tick,0); - map_freeblock_lock(); - battle_delay_damage(tick+wd.amotion,src,target,(wd.damage+wd.damage2),0); - if(target->prev != NULL && - (target->type != BL_PC || (target->type == BL_PC && !pc_isdead((struct map_session_data *)target) ) ) ) { - if(wd.damage > 0 || wd.damage2 > 0) { - skill_additional_effect(src,target,0,0,BF_WEAPON,tick); - if(sd) { - if(sd->weapon_coma_ele[ele] > 0 && rand()%10000 < sd->weapon_coma_ele[ele]) - battle_damage(src,target,status_get_max_hp(target),1); - if(sd->weapon_coma_race[race] > 0 && rand()%10000 < sd->weapon_coma_race[race]) - battle_damage(src,target,status_get_max_hp(target),1); - if(status_get_mode(target) & 0x20) { - if(sd->weapon_coma_race[10] > 0 && rand()%10000 < sd->weapon_coma_race[10]) - battle_damage(src,target,status_get_max_hp(target),1); - } - else { - if(sd->weapon_coma_race[11] > 0 && rand()%10000 < sd->weapon_coma_race[11]) - battle_damage(src,target,status_get_max_hp(target),1); - } - } - } - } - if(sc_data && sc_data[SC_AUTOSPELL].timer != -1 && rand()%100 < sc_data[SC_AUTOSPELL].val4) { - int skilllv=sc_data[SC_AUTOSPELL].val3,i,f=0; - i = rand()%100; - if(i >= 50) skilllv -= 2; - else if(i >= 15) skilllv--; - if(skilllv < 1) skilllv = 1; - if(sd) { - int sp = skill_get_sp(sc_data[SC_AUTOSPELL].val2,skilllv)*2/3; - if(sd->status.sp >= sp) { - if((i=skill_get_inf(sc_data[SC_AUTOSPELL].val2) == 2) || i == 32) - f = skill_castend_pos2(src,target->x,target->y,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - else { - switch( skill_get_nk(sc_data[SC_AUTOSPELL].val2) ) { - case 0: case 2: - f = skill_castend_damage_id(src,target,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - break; - case 1:/* 支援系 */ - if((sc_data[SC_AUTOSPELL].val2==AL_HEAL || (sc_data[SC_AUTOSPELL].val2==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele)) - f = skill_castend_damage_id(src,target,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - else - f = skill_castend_nodamage_id(src,target,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - break; - } - } - if(!f) pc_heal(sd,0,-sp); - } - } - else { - if((i=skill_get_inf(sc_data[SC_AUTOSPELL].val2) == 2) || i == 32) - skill_castend_pos2(src,target->x,target->y,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - else { - switch( skill_get_nk(sc_data[SC_AUTOSPELL].val2) ) { - case 0: case 2: - skill_castend_damage_id(src,target,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - break; - case 1:/* 支援系 */ - if((sc_data[SC_AUTOSPELL].val2==AL_HEAL || (sc_data[SC_AUTOSPELL].val2==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele)) - skill_castend_damage_id(src,target,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - else - skill_castend_nodamage_id(src,target,sc_data[SC_AUTOSPELL].val2,skilllv,tick,flag); - break; - } - } - } - } - if(sd) { - if(sd->autospell_id > 0 && rand()%100 < sd->autospell_rate) { - int skilllv = sd->autospell_lv, i; - i = rand()%100; - if(i >= 50) skilllv -= 2; - else if(i >= 15) skilllv--; - if(skilllv < 1) skilllv = 1; - - if((i=skill_get_inf(sd->autospell_id) == 2) || i == 32) - skill_castend_pos2(src,target->x,target->y,sd->autospell_id,skilllv,tick,flag); - else { - switch( skill_get_nk(sd->autospell_id) ) { - case 0: case 2: - skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag); - break; - case 1:/* 支援系 */ - if((sd->autospell_id==AL_HEAL || (sd->autospell_id==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele)) - skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag); - else - skill_castend_nodamage_id(src,target,sd->autospell_id,skilllv,tick,flag); - break; - } - } - } - if (wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) { - int hp = 0,sp = 0; - if (!battle_config.left_cardfix_to_right) { // 二刀流左手カードの吸収系効果を右手に追加しない場合 - hp += battle_calc_drain(wd.damage, sd->hp_drain_rate, sd->hp_drain_per, sd->hp_drain_value); - hp += battle_calc_drain(wd.damage2, sd->hp_drain_rate_, sd->hp_drain_per_, sd->hp_drain_value_); - sp += battle_calc_drain(wd.damage, sd->sp_drain_rate, sd->sp_drain_per, sd->sp_drain_value); - sp += battle_calc_drain(wd.damage2, sd->sp_drain_rate_, sd->sp_drain_per_, sd->sp_drain_value_); - } else { // 二刀流左手カードの吸収系効果を右手に追加する場合 - int hp_drain_rate = sd->hp_drain_rate + sd->hp_drain_rate_; - int hp_drain_per = sd->hp_drain_per + sd->hp_drain_per_; - int hp_drain_value = sd->hp_drain_value + sd->hp_drain_value_; - int sp_drain_rate = sd->sp_drain_rate + sd->sp_drain_rate_; - int sp_drain_per = sd->sp_drain_per + sd->sp_drain_per_; - int sp_drain_value = sd->sp_drain_value + sd->sp_drain_value_; - hp += battle_calc_drain(wd.damage, hp_drain_rate, hp_drain_per, hp_drain_value); - sp += battle_calc_drain(wd.damage, sp_drain_rate, sp_drain_per, sp_drain_value); - } - - if (hp || sp) pc_heal(sd, hp, sp); - if (sd->sp_drain_type && target->type == BL_PC) - battle_heal(NULL,target,0,-sp,0); - } - } - if (target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - if(tsd && ((sd && !sd->state.arrow_atk) || (status_get_range(src)<=2)) && - tsd->autospell2_id > 0 && rand()%100 < tsd->autospell2_rate) { - struct block_list *tbl; - int skilllv = tsd->autospell_lv, i; - i = rand()%100; - if(i >= 50) skilllv -= 2; - else if(i >= 15) skilllv--; - if(skilllv < 1) skilllv = 1; - - if (tsd->autospell2_type == 0) tbl = target; - else tbl = src; - if((i=skill_get_inf(tsd->autospell2_id) == 2) || i == 32) - skill_castend_pos2(target,tbl->x,tbl->y,tsd->autospell2_id,skilllv,tick,flag); - else { - switch( skill_get_nk(tsd->autospell2_id) ) { - case 0: case 2: - skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag); - break; - case 1:/* 支援系 */ - if((tsd->autospell2_id==AL_HEAL || (tsd->autospell2_id==ALL_RESURRECTION && tbl->type != BL_PC)) && - battle_check_undead(status_get_race(tbl),status_get_elem_type(tbl))) - skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag); - else - skill_castend_nodamage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag); - break; - } - } - } - } - - if(rdamage > 0) - battle_delay_damage(tick+wd.amotion,target,src,rdamage,0); - - if(t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1 && t_sc_data[SC_AUTOCOUNTER].val4 > 0) { - if(t_sc_data[SC_AUTOCOUNTER].val3 == src->id) - battle_weapon_attack(target,src,tick,0x8000|t_sc_data[SC_AUTOCOUNTER].val1); - status_change_end(target,SC_AUTOCOUNTER,-1); - } - if(t_sc_data && t_sc_data[SC_POISONREACT].timer != -1 && t_sc_data[SC_POISONREACT].val4 > 0) { // poison react [Celest] - if(t_sc_data[SC_POISONREACT].val3 == src->id) { - struct map_session_data *tsd = (struct map_session_data *)target; - if ((src->type == BL_MOB && status_get_elem_type(src)==5) || (src->type == BL_PC && status_get_attack_element(src)==5)) { - t_sc_data[SC_POISONREACT].val2 = 0; - battle_weapon_attack(target,src,tick,flag|AS_POISONREACT); - } else { - skill_use_id(tsd,src->id,TF_POISON,5); - --t_sc_data[SC_POISONREACT].val2; - } - if (t_sc_data[SC_POISONREACT].val2<=0) - status_change_end(target,SC_POISONREACT,-1); - } - } - if (t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1 && - !(status_get_mode(src)&0x20)) { // ボスには無効 - int lv = t_sc_data[SC_BLADESTOP_WAIT].val1; - status_change_end(target,SC_BLADESTOP_WAIT,-1); - status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0); - status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0); - } - if(t_sc_data && t_sc_data[SC_SPLASHER].timer!=-1) //殴ったので対象のベナムスプラッシャー状態を解除 - status_change_end(target,SC_SPLASHER,-1); - - map_freeblock_unlock(); - } - return wd.dmg_lv; -} - -int battle_check_undead(int race,int element) -{ - if(battle_config.undead_detect_type == 0) { - if(element == 9) - return 1; - } - else if(battle_config.undead_detect_type == 1) { - if(race == 1) - return 1; - } - else { - if(element == 9 || race == 1) - return 1; - } - return 0; -} - -/*========================================== - * 敵味方判定(1=肯定,0=否定,-1=エラー) - * flag&0xf0000 = 0x00000:敵じゃないか判定(ret:1=敵ではない) - * = 0x10000:パーティー判定(ret:1=パーティーメンバ) - * = 0x20000:全て(ret:1=敵味方両方) - * = 0x40000:敵か判定(ret:1=敵) - * = 0x50000:パーティーじゃないか判定(ret:1=パーティでない) - *------------------------------------------ - */ -int battle_check_target( struct block_list *src, struct block_list *target,int flag) -{ - int s_p,s_g,t_p,t_g; - struct block_list *ss=src; - struct status_change *sc_data; - struct status_change *tsc_data; - - nullpo_retr(0, src); - nullpo_retr(0, target); - - if( flag&0x40000 ){ // 反転フラグ - int ret=battle_check_target(src,target,flag&0x30000); - if(ret!=-1) - return !ret; - return -1; - } - - if( flag&0x20000 ){ - if( target->type==BL_MOB || target->type==BL_PC ) - return 1; - else - return -1; - } - - if(src->type == BL_SKILL && target->type == BL_SKILL) // 対象がスキルユニットなら無条件肯定 - return -1; - - if(target->type == BL_PC && ((struct map_session_data *)target)->invincible_timer != -1) - return -1; - - // Celest - sc_data = status_get_sc_data(src); - tsc_data = status_get_sc_data(target); - if ((sc_data && sc_data[SC_BASILICA].timer != -1) || - (tsc_data && tsc_data[SC_BASILICA].timer != -1)) - return -1; - - if(target->type == BL_SKILL) { - switch(((struct skill_unit *)target)->group->unit_id){ - case 0x8d: - case 0x8f: - case 0x98: - return 0; - break; - } - } - - if(target->type == BL_PET) - return -1; - - // スキルユニットの場合、親を求める - if( src->type==BL_SKILL) { - struct skill_unit *su = (struct skill_unit *)src; - int skillid, inf2; - - nullpo_retr (-1, su); - nullpo_retr (-1, su->group); - skillid = su->group->skill_id; - inf2 = skill_get_inf2(skillid); - if( (ss=map_id2bl( su->group->src_id))==NULL ) - return -1; - if(ss->prev == NULL) - return -1; - if(inf2&0x80 && - (map[src->m].flag.pvp || - (skillid >= 115 && skillid <= 125 && map[src->m].flag.gvg)) && - !(target->type == BL_PC && pc_isinvisible((struct map_session_data *)target))) - return 0; - if(ss == target) { - if(inf2&0x100) - return 0; - if(inf2&0x200) - return -1; - } - } - - if( src->type==BL_MOB ){ - struct mob_data *md=(struct mob_data *)src; - nullpo_retr (-1, md); - - if(target->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)target; - nullpo_retr (-1, sd); - - if(md->class_ >= 1285 && md->class_ <= 1287){ - struct guild_castle *gc = guild_mapname2gc (map[target->m].name); - if(gc && agit_flag==0) // Guardians will not attack during non-woe time [Valaris] - return 1; // end addition [Valaris] - if(gc && sd->status.guild_id > 0) { - struct guild *g=guild_search(sd->status.guild_id); // don't attack guild members [Valaris] - if(g && g->guild_id == gc->guild_id) - return 1; - if(g && guild_isallied(g,gc)) - return 1; - } - } - // option to have monsters ignore GMs [Valaris] - if (battle_config.monsters_ignore_gm > 0 && pc_isGM(sd) >= battle_config.monsters_ignore_gm) - return 1; - } - // Mobでmaster_idがあってspecial_mob_aiなら、召喚主を求める - if(md->master_id>0){ - if(md->master_id==target->id) // 主なら肯定 - return 1; - if(md->state.special_mob_ai){ - if(target->type==BL_MOB){ //special_mob_aiで対象がMob - struct mob_data *tmd=(struct mob_data *)target; - if(tmd){ - if(tmd->master_id != md->master_id) //召喚主が一緒でなければ否定 - return 0; - else{ //召喚主が一緒なので肯定したいけど自爆は否定 - if(md->state.special_mob_ai>2) - return 0; - else - return 1; - } - } - } - } - if((ss=map_id2bl(md->master_id))==NULL) - return -1; - } - } - - if( src==target || ss==target ) // 同じなら肯定 - return 1; - - if(target->type == BL_PC && pc_isinvisible((struct map_session_data *)target)) - return -1; - - if( src->prev==NULL || // 死んでるならエラー - (src->type==BL_PC && pc_isdead((struct map_session_data *)src) ) ) - return -1; - - if( (ss->type == BL_PC && target->type==BL_MOB) || - (ss->type == BL_MOB && target->type==BL_PC) ) - return 0; // PCvsMOBなら否定 - - if(ss->type == BL_PET && target->type==BL_MOB) - return 0; - - s_p=status_get_party_id(ss); - s_g=status_get_guild_id(ss); - - t_p=status_get_party_id(target); - t_g=status_get_guild_id(target); - - if(flag&0x10000) { - if(s_p && t_p && s_p == t_p) // 同じパーティなら肯定(味方) - return 1; - else // パーティ検索なら同じパーティじゃない時点で否定 - return 0; - } - - if(ss->type == BL_MOB && s_g > 0 && t_g > 0 && s_g == t_g ) // 同じギルド/mobクラスなら肯定(味方) - return 1; - -//printf("ss:%d src:%d target:%d flag:0x%x %d %d ",ss->id,src->id,target->id,flag,src->type,target->type); -//printf("p:%d %d g:%d %d\n",s_p,t_p,s_g,t_g); - - if( ss->type==BL_PC && target->type==BL_PC) { // 両方PVPモードなら否定(敵) - struct skill_unit *su=NULL; - if(src->type==BL_SKILL) - su=(struct skill_unit *)src; - if(map[ss->m].flag.pvp || pc_iskiller((struct map_session_data *)ss, (struct map_session_data*)target)) { // [MouseJstr] - if(su && su->group->target_flag==BCT_NOENEMY) - return 1; - else if (battle_config.pk_mode && - (((struct map_session_data*)ss)->status.class_==0 || ((struct map_session_data*)target)->status.class_==0 || - ((struct map_session_data*)ss)->status.base_level < battle_config.pk_min_level || - ((struct map_session_data*)target)->status.base_level < battle_config.pk_min_level)) - return 1; // prevent novice engagement in pk_mode [Valaris] - else if(map[ss->m].flag.pvp_noparty && s_p > 0 && t_p > 0 && s_p == t_p) - return 1; - else if(map[ss->m].flag.pvp_noguild && s_g > 0 && t_g > 0 && s_g == t_g) - return 1; - return 0; - } - if(map[src->m].flag.gvg) { - struct guild *g=NULL; - if(su && su->group->target_flag==BCT_NOENEMY) - return 1; - if( s_g > 0 && s_g == t_g) - return 1; - if(map[src->m].flag.gvg_noparty && s_p > 0 && t_p > 0 && s_p == t_p) - return 1; - if((g = guild_search(s_g))) { - int i; - for(i=0;i<MAX_GUILDALLIANCE;i++){ - if(g->alliance[i].guild_id > 0 && g->alliance[i].guild_id == t_g) { - if(g->alliance[i].opposition) - return 0;//敵対ギルドなら無条件に敵 - else - return 1;//同盟ギルドなら無条件に味方 - } - } - } - return 0; - } - } - - return 1; // 該当しないので無関係人物(まあ敵じゃないので味方) -} -/*========================================== - * 射程判定 - *------------------------------------------ - */ -int battle_check_range(struct block_list *src,struct block_list *bl,int range) -{ - - int dx,dy; - int arange; - - nullpo_retr(0, src); - nullpo_retr(0, bl); - - dx=abs(bl->x-src->x); - dy=abs(bl->y-src->y); - arange=((dx>dy)?dx:dy); - - if(src->m != bl->m) // 違うマップ - return 0; - - if( range>0 && range < arange ) // 遠すぎる - return 0; - - if( arange<2 ) // 同じマスか隣接 - return 1; - -// if(bl->type == BL_SKILL && ((struct skill_unit *)bl)->group->unit_id == 0x8d) -// return 1; - - // 障害物判定 - return path_search_long(NULL,src->m,src->x,src->y,bl->x,bl->y); -} - -/*========================================== - * Return numerical value of a switch configuration (modified by [Yor]) - * on/off, english, fran軋is, deutsch, espaol - *------------------------------------------ - */ -int battle_config_switch(const char *str) { - if (strcmpi(str, "on") == 0 || strcmpi(str, "yes") == 0 || strcmpi(str, "oui") == 0 || strcmpi(str, "ja") == 0 || strcmpi(str, "si") == 0) - return 1; - if (strcmpi(str, "off") == 0 || strcmpi(str, "no") == 0 || strcmpi(str, "non") == 0 || strcmpi(str, "nein") == 0) - return 0; - return atoi(str); -} - -static const struct { - char str[128]; - void *val; -} battle_data[] = { - { "warp_point_debug", &battle_config.warp_point_debug }, - { "enemy_critical", &battle_config.enemy_critical }, - { "enemy_critical_rate", &battle_config.enemy_critical_rate }, - { "enemy_str", &battle_config.enemy_str }, - { "enemy_perfect_flee", &battle_config.enemy_perfect_flee }, - { "casting_rate", &battle_config.cast_rate }, - { "delay_rate", &battle_config.delay_rate }, - { "delay_dependon_dex", &battle_config.delay_dependon_dex }, - { "skill_delay_attack_enable", &battle_config.sdelay_attack_enable }, - { "left_cardfix_to_right", &battle_config.left_cardfix_to_right }, - { "player_skill_add_range", &battle_config.pc_skill_add_range }, - { "skill_out_range_consume", &battle_config.skill_out_range_consume }, - { "monster_skill_add_range", &battle_config.mob_skill_add_range }, - { "player_damage_delay", &battle_config.pc_damage_delay }, - { "player_damage_delay_rate", &battle_config.pc_damage_delay_rate }, - { "defunit_not_enemy", &battle_config.defnotenemy }, - { "random_monster_checklv", &battle_config.random_monster_checklv }, - { "attribute_recover", &battle_config.attr_recover }, - { "flooritem_lifetime", &battle_config.flooritem_lifetime }, - { "item_auto_get", &battle_config.item_auto_get }, - { "item_first_get_time", &battle_config.item_first_get_time }, - { "item_second_get_time", &battle_config.item_second_get_time }, - { "item_third_get_time", &battle_config.item_third_get_time }, - { "mvp_item_first_get_time", &battle_config.mvp_item_first_get_time }, - { "mvp_item_second_get_time", &battle_config.mvp_item_second_get_time }, - { "mvp_item_third_get_time", &battle_config.mvp_item_third_get_time }, - { "item_rate", &battle_config.item_rate }, - { "drop_rate0item", &battle_config.drop_rate0item }, - { "base_exp_rate", &battle_config.base_exp_rate }, - { "job_exp_rate", &battle_config.job_exp_rate }, - { "pvp_exp", &battle_config.pvp_exp }, - { "gtb_pvp_only", &battle_config.gtb_pvp_only }, - { "guild_max_castles", &battle_config.guild_max_castles }, - { "death_penalty_type", &battle_config.death_penalty_type }, - { "death_penalty_base", &battle_config.death_penalty_base }, - { "death_penalty_job", &battle_config.death_penalty_job }, - { "zeny_penalty", &battle_config.zeny_penalty }, - { "restart_hp_rate", &battle_config.restart_hp_rate }, - { "restart_sp_rate", &battle_config.restart_sp_rate }, - { "mvp_hp_rate", &battle_config.mvp_hp_rate }, - { "mvp_item_rate", &battle_config.mvp_item_rate }, - { "mvp_exp_rate", &battle_config.mvp_exp_rate }, - { "monster_hp_rate", &battle_config.monster_hp_rate }, - { "monster_max_aspd", &battle_config.monster_max_aspd }, - { "atcommand_gm_only", &battle_config.atc_gmonly }, - { "atcommand_spawn_quantity_limit", &battle_config.atc_spawn_quantity_limit }, - { "gm_all_skill", &battle_config.gm_allskill }, - { "gm_all_skill_add_abra", &battle_config.gm_allskill_addabra }, - { "gm_all_equipment", &battle_config.gm_allequip }, - { "gm_skill_unconditional", &battle_config.gm_skilluncond }, - { "player_skillfree", &battle_config.skillfree }, - { "player_skillup_limit", &battle_config.skillup_limit }, - { "weapon_produce_rate", &battle_config.wp_rate }, - { "potion_produce_rate", &battle_config.pp_rate }, - { "monster_active_enable", &battle_config.monster_active_enable }, - { "monster_damage_delay_rate", &battle_config.monster_damage_delay_rate}, - { "monster_loot_type", &battle_config.monster_loot_type }, - { "mob_skill_use", &battle_config.mob_skill_use }, - { "mob_count_rate", &battle_config.mob_count_rate }, - { "quest_skill_learn", &battle_config.quest_skill_learn }, - { "quest_skill_reset", &battle_config.quest_skill_reset }, - { "basic_skill_check", &battle_config.basic_skill_check }, - { "guild_emperium_check", &battle_config.guild_emperium_check }, - { "guild_exp_limit", &battle_config.guild_exp_limit }, - { "player_invincible_time", &battle_config.pc_invincible_time }, - { "pet_catch_rate", &battle_config.pet_catch_rate }, - { "pet_rename", &battle_config.pet_rename }, - { "pet_friendly_rate", &battle_config.pet_friendly_rate }, - { "pet_hungry_delay_rate", &battle_config.pet_hungry_delay_rate }, - { "pet_hungry_friendly_decrease", &battle_config.pet_hungry_friendly_decrease}, - { "pet_str", &battle_config.pet_str }, - { "pet_status_support", &battle_config.pet_status_support }, - { "pet_attack_support", &battle_config.pet_attack_support }, - { "pet_damage_support", &battle_config.pet_damage_support }, - { "pet_support_rate", &battle_config.pet_support_rate }, - { "pet_attack_exp_to_master", &battle_config.pet_attack_exp_to_master }, - { "pet_attack_exp_rate", &battle_config.pet_attack_exp_rate }, - { "skill_min_damage", &battle_config.skill_min_damage }, - { "finger_offensive_type", &battle_config.finger_offensive_type }, - { "heal_exp", &battle_config.heal_exp }, - { "resurrection_exp", &battle_config.resurrection_exp }, - { "shop_exp", &battle_config.shop_exp }, - { "combo_delay_rate", &battle_config.combo_delay_rate }, - { "item_check", &battle_config.item_check }, - { "wedding_modifydisplay", &battle_config.wedding_modifydisplay }, - { "natural_healhp_interval", &battle_config.natural_healhp_interval }, - { "natural_healsp_interval", &battle_config.natural_healsp_interval }, - { "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval}, - { "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate }, - { "item_name_override_grffile", &battle_config.item_name_override_grffile}, - { "item_equip_override_grffile", &battle_config.item_equip_override_grffile}, // [Celest] - { "item_slots_override_grffile", &battle_config.item_slots_override_grffile}, // [Celest] - { "indoors_override_grffile", &battle_config.indoors_override_grffile}, // [Celest] - { "skill_sp_override_grffile", &battle_config.skill_sp_override_grffile}, // [Celest] - { "cardillust_read_grffile", &battle_config.cardillust_read_grffile}, // [Celest] - { "arrow_decrement", &battle_config.arrow_decrement }, - { "max_aspd", &battle_config.max_aspd }, - { "max_hp", &battle_config.max_hp }, - { "max_sp", &battle_config.max_sp }, - { "max_lv", &battle_config.max_lv }, - { "max_parameter", &battle_config.max_parameter }, - { "max_cart_weight", &battle_config.max_cart_weight }, - { "player_skill_log", &battle_config.pc_skill_log }, - { "monster_skill_log", &battle_config.mob_skill_log }, - { "battle_log", &battle_config.battle_log }, - { "save_log", &battle_config.save_log }, - { "error_log", &battle_config.error_log }, - { "etc_log", &battle_config.etc_log }, - { "save_clothcolor", &battle_config.save_clothcolor }, - { "undead_detect_type", &battle_config.undead_detect_type }, - { "player_auto_counter_type", &battle_config.pc_auto_counter_type }, - { "monster_auto_counter_type", &battle_config.monster_auto_counter_type}, - { "agi_penalty_type", &battle_config.agi_penalty_type }, - { "agi_penalty_count", &battle_config.agi_penalty_count }, - { "agi_penalty_num", &battle_config.agi_penalty_num }, - { "agi_penalty_count_lv", &battle_config.agi_penalty_count_lv }, - { "vit_penalty_type", &battle_config.vit_penalty_type }, - { "vit_penalty_count", &battle_config.vit_penalty_count }, - { "vit_penalty_num", &battle_config.vit_penalty_num }, - { "vit_penalty_count_lv", &battle_config.vit_penalty_count_lv }, - { "player_defense_type", &battle_config.player_defense_type }, - { "monster_defense_type", &battle_config.monster_defense_type }, - { "pet_defense_type", &battle_config.pet_defense_type }, - { "magic_defense_type", &battle_config.magic_defense_type }, - { "player_skill_reiteration", &battle_config.pc_skill_reiteration }, - { "monster_skill_reiteration", &battle_config.monster_skill_reiteration}, - { "player_skill_nofootset", &battle_config.pc_skill_nofootset }, - { "monster_skill_nofootset", &battle_config.monster_skill_nofootset }, - { "player_cloak_check_type", &battle_config.pc_cloak_check_type }, - { "monster_cloak_check_type", &battle_config.monster_cloak_check_type }, - { "gvg_short_attack_damage_rate", &battle_config.gvg_short_damage_rate }, - { "gvg_long_attack_damage_rate", &battle_config.gvg_long_damage_rate }, - { "gvg_magic_attack_damage_rate", &battle_config.gvg_magic_damage_rate }, - { "gvg_misc_attack_damage_rate", &battle_config.gvg_misc_damage_rate }, - { "gvg_eliminate_time", &battle_config.gvg_eliminate_time }, - { "mob_changetarget_byskill", &battle_config.mob_changetarget_byskill}, - { "player_attack_direction_change", &battle_config.pc_attack_direction_change }, - { "monster_attack_direction_change", &battle_config.monster_attack_direction_change }, - { "player_land_skill_limit", &battle_config.pc_land_skill_limit }, - { "monster_land_skill_limit", &battle_config.monster_land_skill_limit}, - { "party_skill_penalty", &battle_config.party_skill_penalty }, - { "monster_class_change_full_recover", &battle_config.monster_class_change_full_recover }, - { "produce_item_name_input", &battle_config.produce_item_name_input }, - { "produce_potion_name_input", &battle_config.produce_potion_name_input}, - { "making_arrow_name_input", &battle_config.making_arrow_name_input }, - { "holywater_name_input", &battle_config.holywater_name_input }, - { "display_delay_skill_fail", &battle_config.display_delay_skill_fail }, - { "display_snatcher_skill_fail", &battle_config.display_snatcher_skill_fail }, - { "chat_warpportal", &battle_config.chat_warpportal }, - { "mob_warpportal", &battle_config.mob_warpportal }, - { "dead_branch_active", &battle_config.dead_branch_active }, - { "vending_max_value", &battle_config.vending_max_value }, - { "show_steal_in_same_party", &battle_config.show_steal_in_same_party }, - { "pet_attack_attr_none", &battle_config.pet_attack_attr_none }, - { "mob_attack_attr_none", &battle_config.mob_attack_attr_none }, - { "mob_ghostring_fix", &battle_config.mob_ghostring_fix }, - { "pc_attack_attr_none", &battle_config.pc_attack_attr_none }, - { "gx_allhit", &battle_config.gx_allhit }, - { "gx_cardfix", &battle_config.gx_cardfix }, - { "gx_dupele", &battle_config.gx_dupele }, - { "gx_disptype", &battle_config.gx_disptype }, - { "devotion_level_difference", &battle_config.devotion_level_difference }, - { "player_skill_partner_check", &battle_config.player_skill_partner_check}, - { "hide_GM_session", &battle_config.hide_GM_session }, - { "unit_movement_type", &battle_config.unit_movement_type }, - { "invite_request_check", &battle_config.invite_request_check }, - { "skill_removetrap_type", &battle_config.skill_removetrap_type }, - { "disp_experience", &battle_config.disp_experience }, - { "castle_defense_rate", &battle_config.castle_defense_rate }, - { "hp_rate", &battle_config.hp_rate }, - { "sp_rate", &battle_config.sp_rate }, - { "gm_can_drop_lv", &battle_config.gm_can_drop_lv }, - { "disp_hpmeter", &battle_config.disp_hpmeter }, - { "bone_drop", &battle_config.bone_drop }, - { "monster_damage_delay", &battle_config.monster_damage_delay }, - -// eAthena additions - { "item_rate_common", &battle_config.item_rate_common }, // Added by RoVeRT - { "item_rate_equip", &battle_config.item_rate_equip }, - { "item_rate_card", &battle_config.item_rate_card }, // End Addition - { "item_rate_heal", &battle_config.item_rate_heal }, // Added by Valaris - { "item_rate_use", &battle_config.item_rate_use }, // End - { "item_drop_common_min", &battle_config.item_drop_common_min }, // Added by TyrNemesis^ - { "item_drop_common_max", &battle_config.item_drop_common_max }, - { "item_drop_equip_min", &battle_config.item_drop_equip_min }, - { "item_drop_equip_max", &battle_config.item_drop_equip_max }, - { "item_drop_card_min", &battle_config.item_drop_card_min }, - { "item_drop_card_max", &battle_config.item_drop_card_max }, - { "item_drop_mvp_min", &battle_config.item_drop_mvp_min }, - { "item_drop_mvp_max", &battle_config.item_drop_mvp_max }, // End Addition - { "prevent_logout", &battle_config.prevent_logout }, // Added by RoVeRT - { "alchemist_summon_reward", &battle_config.alchemist_summon_reward }, // [Valaris] - { "maximum_level", &battle_config.maximum_level }, // [Valaris] - { "drops_by_luk", &battle_config.drops_by_luk }, // [Valaris] - { "monsters_ignore_gm", &battle_config.monsters_ignore_gm }, // [Valaris] - { "equipment_breaking", &battle_config.equipment_breaking }, // [Valaris] - { "equipment_break_rate", &battle_config.equipment_break_rate }, // [Valaris] - { "pk_mode", &battle_config.pk_mode }, // [Valaris] - { "pet_equip_required", &battle_config.pet_equip_required }, // [Valaris] - { "multi_level_up", &battle_config.multi_level_up }, // [Valaris] - { "backstab_bow_penalty", &battle_config.backstab_bow_penalty }, - { "night_at_start", &battle_config.night_at_start }, // added by [Yor] - { "day_duration", &battle_config.day_duration }, // added by [Yor] - { "night_duration", &battle_config.night_duration }, // added by [Yor] - { "show_mob_hp", &battle_config.show_mob_hp }, // [Valaris] - { "ban_spoof_namer", &battle_config.ban_spoof_namer }, // added by [Yor] - { "hack_info_GM_level", &battle_config.hack_info_GM_level }, // added by [Yor] - { "any_warp_GM_min_level", &battle_config.any_warp_GM_min_level }, // added by [Yor] - { "packet_ver_flag", &battle_config.packet_ver_flag }, // added by [Yor] - { "min_hair_style", &battle_config.min_hair_style }, // added by [MouseJstr] - { "max_hair_style", &battle_config.max_hair_style }, // added by [MouseJstr] - { "min_hair_color", &battle_config.min_hair_color }, // added by [MouseJstr] - { "max_hair_color", &battle_config.max_hair_color }, // added by [MouseJstr] - { "min_cloth_color", &battle_config.min_cloth_color }, // added by [MouseJstr] - { "max_cloth_color", &battle_config.max_cloth_color }, // added by [MouseJstr] - { "castrate_dex_scale", &battle_config.castrate_dex_scale }, // added by [MouseJstr] - { "area_size", &battle_config.area_size }, // added by [MouseJstr] - { "muting_players", &battle_config.muting_players}, // added by [Apple] - { "zeny_from_mobs", &battle_config.zeny_from_mobs}, // [Valaris] - { "mobs_level_up", &battle_config.mobs_level_up}, // [Valaris] - { "pk_min_level", &battle_config.pk_min_level}, // [celest] - { "skill_steal_type", &battle_config.skill_steal_type}, // [celest] - { "skill_steal_rate", &battle_config.skill_steal_rate}, // [celest] - { "night_darkness_level", &battle_config.night_darkness_level}, // [celest] - { "motd_type", &battle_config.motd_type}, // [celest] - { "allow_atcommand_when_mute", &battle_config.allow_atcommand_when_mute}, // [celest] - { "finding_ore_rate", &battle_config.finding_ore_rate}, // [celest] - { "exp_calc_type", &battle_config.exp_calc_type}, // [celest] - { "min_skill_delay_limit", &battle_config.min_skill_delay_limit}, // [celest] - { "require_glory_guild", &battle_config.require_glory_guild}, // [celest] - { "idle_no_share", &battle_config.idle_no_share}, // [celest], for a feature by [MouseJstr] - -//SQL-only options start -#ifndef TXT_ONLY - { "mail_system", &battle_config.mail_system }, // added by [Valaris] -//SQL-only options end -#endif -}; - -int battle_set_value(char *w1, char *w2) { - int i; - for(i = 0; i < sizeof(battle_data) / (sizeof(battle_data[0])); i++) - if (strcmpi(w1, battle_data[i].str) == 0) { - *((unsigned int *) battle_data[i].val) = battle_config_switch(w2); - return 1; - } - return 0; -} - -void battle_set_defaults() { - battle_config.warp_point_debug=0; - battle_config.enemy_critical=0; - battle_config.enemy_critical_rate=100; - battle_config.enemy_str=1; - battle_config.enemy_perfect_flee=0; - battle_config.cast_rate=100; - battle_config.delay_rate=100; - battle_config.delay_dependon_dex=0; - battle_config.sdelay_attack_enable=0; - battle_config.left_cardfix_to_right=0; - battle_config.pc_skill_add_range=0; - battle_config.skill_out_range_consume=1; - battle_config.mob_skill_add_range=0; - battle_config.pc_damage_delay=1; - battle_config.pc_damage_delay_rate=100; - battle_config.defnotenemy=1; - battle_config.random_monster_checklv=1; - battle_config.attr_recover=1; - battle_config.flooritem_lifetime=LIFETIME_FLOORITEM*1000; - battle_config.item_auto_get=0; - battle_config.item_first_get_time=3000; - battle_config.item_second_get_time=1000; - battle_config.item_third_get_time=1000; - battle_config.mvp_item_first_get_time=10000; - battle_config.mvp_item_second_get_time=10000; - battle_config.mvp_item_third_get_time=2000; - - battle_config.drop_rate0item=0; - battle_config.base_exp_rate=100; - battle_config.job_exp_rate=100; - battle_config.pvp_exp=1; - battle_config.gtb_pvp_only=0; - battle_config.death_penalty_type=0; - battle_config.death_penalty_base=0; - battle_config.death_penalty_job=0; - battle_config.zeny_penalty=0; - battle_config.restart_hp_rate=0; - battle_config.restart_sp_rate=0; - battle_config.mvp_item_rate=100; - battle_config.mvp_exp_rate=100; - battle_config.mvp_hp_rate=100; - battle_config.monster_hp_rate=100; - battle_config.monster_max_aspd=199; - battle_config.atc_gmonly=0; - battle_config.gm_allskill=0; - battle_config.gm_allequip=0; - battle_config.gm_skilluncond=0; - battle_config.guild_max_castles=0; - battle_config.skillfree = 0; - battle_config.skillup_limit = 0; - battle_config.wp_rate=100; - battle_config.pp_rate=100; - battle_config.monster_active_enable=1; - battle_config.monster_damage_delay_rate=100; - battle_config.monster_loot_type=0; - battle_config.mob_skill_use=1; - battle_config.mob_count_rate=100; - battle_config.quest_skill_learn=0; - battle_config.quest_skill_reset=1; - battle_config.basic_skill_check=1; - battle_config.guild_emperium_check=1; - battle_config.guild_exp_limit=50; - battle_config.pc_invincible_time = 5000; - battle_config.pet_catch_rate=100; - battle_config.pet_rename=0; - battle_config.pet_friendly_rate=100; - battle_config.pet_hungry_delay_rate=100; - battle_config.pet_hungry_friendly_decrease=5; - battle_config.pet_str=1; - battle_config.pet_status_support=0; - battle_config.pet_attack_support=0; - battle_config.pet_damage_support=0; - battle_config.pet_support_rate=100; - battle_config.pet_attack_exp_to_master=0; - battle_config.pet_attack_exp_rate=100; - battle_config.skill_min_damage=0; - battle_config.finger_offensive_type=0; - battle_config.heal_exp=0; - battle_config.resurrection_exp=0; - battle_config.shop_exp=0; - battle_config.combo_delay_rate=100; - battle_config.item_check=1; - battle_config.wedding_modifydisplay=0; - battle_config.natural_healhp_interval=6000; - battle_config.natural_healsp_interval=8000; - battle_config.natural_heal_skill_interval=10000; - battle_config.natural_heal_weight_rate=50; - battle_config.item_name_override_grffile=1; - battle_config.item_equip_override_grffile=0; // [Celest] - battle_config.item_slots_override_grffile=0; // [Celest] - battle_config.indoors_override_grffile=0; // [Celest] - battle_config.skill_sp_override_grffile=0; // [Celest] - battle_config.cardillust_read_grffile=0; // [Celest] - battle_config.arrow_decrement=1; - battle_config.max_aspd = 199; - battle_config.max_hp = 32500; - battle_config.max_sp = 32500; - battle_config.max_lv = 99; // [MouseJstr] - battle_config.max_parameter = 99; - battle_config.max_cart_weight = 8000; - battle_config.pc_skill_log = 0; - battle_config.mob_skill_log = 0; - battle_config.battle_log = 0; - battle_config.save_log = 0; - battle_config.error_log = 1; - battle_config.etc_log = 1; - battle_config.save_clothcolor = 0; - battle_config.undead_detect_type = 0; - battle_config.pc_auto_counter_type = 1; - battle_config.monster_auto_counter_type = 1; - battle_config.agi_penalty_type = 0; - battle_config.agi_penalty_count = 3; - battle_config.agi_penalty_num = 0; - battle_config.agi_penalty_count_lv = ATK_FLEE; - battle_config.vit_penalty_type = 0; - battle_config.vit_penalty_count = 3; - battle_config.vit_penalty_num = 0; - battle_config.vit_penalty_count_lv = ATK_DEF; - battle_config.player_defense_type = 0; - battle_config.monster_defense_type = 0; - battle_config.pet_defense_type = 0; - battle_config.magic_defense_type = 0; - battle_config.pc_skill_reiteration = 0; - battle_config.monster_skill_reiteration = 0; - battle_config.pc_skill_nofootset = 0; - battle_config.monster_skill_nofootset = 0; - battle_config.pc_cloak_check_type = 0; - battle_config.monster_cloak_check_type = 0; - battle_config.gvg_short_damage_rate = 100; - battle_config.gvg_long_damage_rate = 60; - battle_config.gvg_magic_damage_rate = 50; - battle_config.gvg_misc_damage_rate = 60; - battle_config.gvg_eliminate_time = 7000; - battle_config.mob_changetarget_byskill = 0; - battle_config.pc_attack_direction_change = 1; - battle_config.monster_attack_direction_change = 1; - battle_config.pc_land_skill_limit = 1; - battle_config.monster_land_skill_limit = 1; - battle_config.party_skill_penalty = 1; - battle_config.monster_class_change_full_recover = 0; - battle_config.produce_item_name_input = 1; - battle_config.produce_potion_name_input = 1; - battle_config.making_arrow_name_input = 1; - battle_config.holywater_name_input = 1; - battle_config.display_delay_skill_fail = 1; - battle_config.display_snatcher_skill_fail = 1; - battle_config.chat_warpportal = 0; - battle_config.mob_warpportal = 0; - battle_config.dead_branch_active = 0; - battle_config.vending_max_value = 10000000; - battle_config.show_steal_in_same_party = 0; - battle_config.pet_attack_attr_none = 0; - battle_config.pc_attack_attr_none = 0; - battle_config.mob_attack_attr_none = 1; - battle_config.mob_ghostring_fix = 0; - battle_config.gx_allhit = 0; - battle_config.gx_cardfix = 0; - battle_config.gx_dupele = 1; - battle_config.gx_disptype = 1; - battle_config.devotion_level_difference = 10; - battle_config.player_skill_partner_check = 1; - battle_config.hide_GM_session = 0; - battle_config.unit_movement_type = 0; - battle_config.invite_request_check = 1; - battle_config.skill_removetrap_type = 0; - battle_config.disp_experience = 0; - battle_config.castle_defense_rate = 100; - battle_config.hp_rate = 100; - battle_config.sp_rate = 100; - battle_config.gm_can_drop_lv = 0; - battle_config.disp_hpmeter = 0; - battle_config.bone_drop = 0; - battle_config.monster_damage_delay = 1; - -// eAthena additions - battle_config.item_rate_common = 100; - battle_config.item_rate_equip = 100; - battle_config.item_rate_card = 100; - battle_config.item_rate_heal = 100; // Added by Valaris - battle_config.item_rate_use = 100; // End - battle_config.item_drop_common_min=1; // Added by TyrNemesis^ - battle_config.item_drop_common_max=10000; - battle_config.item_drop_equip_min=1; - battle_config.item_drop_equip_max=10000; - battle_config.item_drop_card_min=1; - battle_config.item_drop_card_max=10000; - battle_config.item_drop_mvp_min=1; - battle_config.item_drop_mvp_max=10000; // End Addition - battle_config.item_drop_heal_min=1; // Added by Valaris - battle_config.item_drop_heal_max=10000; - battle_config.item_drop_use_min=1; - battle_config.item_drop_use_max=10000; // End - battle_config.prevent_logout = 1; // Added by RoVeRT - battle_config.maximum_level = 255; // Added by Valaris - battle_config.drops_by_luk = 0; // [Valaris] - battle_config.equipment_breaking = 0; // [Valaris] - battle_config.equipment_break_rate = 100; // [Valaris] - battle_config.pk_mode = 0; // [Valaris] - battle_config.pet_equip_required = 0; // [Valaris] - battle_config.multi_level_up = 0; // [Valaris] - battle_config.backstab_bow_penalty = 0; // Akaru - battle_config.night_at_start = 0; // added by [Yor] - battle_config.day_duration = 2*60*60*1000; // added by [Yor] (2 hours) - battle_config.night_duration = 30*60*1000; // added by [Yor] (30 minutes) - battle_config.show_mob_hp = 0; // [Valaris] - battle_config.ban_spoof_namer = 5; // added by [Yor] (default: 5 minutes) - battle_config.hack_info_GM_level = 60; // added by [Yor] (default: 60, GM level) - battle_config.any_warp_GM_min_level = 20; // added by [Yor] - battle_config.packet_ver_flag = 255; // added by [Yor] - battle_config.min_hair_style = 0; - battle_config.max_hair_style = 20; - battle_config.min_hair_color = 0; - battle_config.max_hair_color = 9; - battle_config.min_cloth_color = 0; - battle_config.max_cloth_color = 4; - battle_config.zeny_from_mobs = 0; - battle_config.mobs_level_up = 0; - battle_config.pk_min_level = 55; - battle_config.skill_steal_type = 1; - battle_config.skill_steal_rate = 100; - battle_config.night_darkness_level = 9; - battle_config.motd_type = 0; - battle_config.allow_atcommand_when_mute = 0; - battle_config.finding_ore_rate = 100; - battle_config.castrate_dex_scale = 150; - battle_config.area_size = 14; - battle_config.exp_calc_type = 1; - battle_config.min_skill_delay_limit = 100; - battle_config.require_glory_guild = 0; - battle_config.idle_no_share = 0; - -//SQL-only options start -#ifndef TXT_ONLY - battle_config.mail_system = 0; -//SQL-only options end -#endif -} - -void battle_validate_conf() { - if(battle_config.flooritem_lifetime < 1000) - battle_config.flooritem_lifetime = LIFETIME_FLOORITEM*1000; - if(battle_config.restart_hp_rate < 0) - battle_config.restart_hp_rate = 0; - else if(battle_config.restart_hp_rate > 100) - battle_config.restart_hp_rate = 100; - if(battle_config.restart_sp_rate < 0) - battle_config.restart_sp_rate = 0; - else if(battle_config.restart_sp_rate > 100) - battle_config.restart_sp_rate = 100; - if(battle_config.natural_healhp_interval < NATURAL_HEAL_INTERVAL) - battle_config.natural_healhp_interval=NATURAL_HEAL_INTERVAL; - if(battle_config.natural_healsp_interval < NATURAL_HEAL_INTERVAL) - battle_config.natural_healsp_interval=NATURAL_HEAL_INTERVAL; - if(battle_config.natural_heal_skill_interval < NATURAL_HEAL_INTERVAL) - battle_config.natural_heal_skill_interval=NATURAL_HEAL_INTERVAL; - if(battle_config.natural_heal_weight_rate < 50) - battle_config.natural_heal_weight_rate = 50; - if(battle_config.natural_heal_weight_rate > 101) - battle_config.natural_heal_weight_rate = 101; - battle_config.monster_max_aspd = 2000 - battle_config.monster_max_aspd*10; - if(battle_config.monster_max_aspd < 10) - battle_config.monster_max_aspd = 10; - if(battle_config.monster_max_aspd > 1000) - battle_config.monster_max_aspd = 1000; - battle_config.max_aspd = 2000 - battle_config.max_aspd*10; - if(battle_config.max_aspd < 10) - battle_config.max_aspd = 10; - if(battle_config.max_aspd > 1000) - battle_config.max_aspd = 1000; - if(battle_config.hp_rate < 0) - battle_config.hp_rate = 1; - if(battle_config.sp_rate < 0) - battle_config.sp_rate = 1; - if(battle_config.max_hp > 1000000) - battle_config.max_hp = 1000000; - if(battle_config.max_hp < 100) - battle_config.max_hp = 100; - if(battle_config.max_sp > 1000000) - battle_config.max_sp = 1000000; - if(battle_config.max_sp < 100) - battle_config.max_sp = 100; - if(battle_config.max_parameter < 10) - battle_config.max_parameter = 10; - if(battle_config.max_parameter > 10000) - battle_config.max_parameter = 10000; - if(battle_config.max_cart_weight > 1000000) - battle_config.max_cart_weight = 1000000; - if(battle_config.max_cart_weight < 100) - battle_config.max_cart_weight = 100; - battle_config.max_cart_weight *= 10; - - if(battle_config.agi_penalty_count < 2) - battle_config.agi_penalty_count = 2; - if(battle_config.vit_penalty_count < 2) - battle_config.vit_penalty_count = 2; - - if(battle_config.guild_exp_limit > 99) - battle_config.guild_exp_limit = 99; - if(battle_config.guild_exp_limit < 0) - battle_config.guild_exp_limit = 0; - - if(battle_config.castle_defense_rate < 0) - battle_config.castle_defense_rate = 0; - if(battle_config.castle_defense_rate > 100) - battle_config.castle_defense_rate = 100; - if(battle_config.item_drop_common_min < 1) // Added by TyrNemesis^ - battle_config.item_drop_common_min = 1; - if(battle_config.item_drop_common_max > 10000) - battle_config.item_drop_common_max = 10000; - if(battle_config.item_drop_equip_min < 1) - battle_config.item_drop_equip_min = 1; - if(battle_config.item_drop_equip_max > 10000) - battle_config.item_drop_equip_max = 10000; - if(battle_config.item_drop_card_min < 1) - battle_config.item_drop_card_min = 1; - if(battle_config.item_drop_card_max > 10000) - battle_config.item_drop_card_max = 10000; - if(battle_config.item_drop_mvp_min < 1) - battle_config.item_drop_mvp_min = 1; - if(battle_config.item_drop_mvp_max > 10000) - battle_config.item_drop_mvp_max = 10000; // End Addition - - if (battle_config.night_at_start < 0) // added by [Yor] - battle_config.night_at_start = 0; - else if (battle_config.night_at_start > 1) // added by [Yor] - battle_config.night_at_start = 1; - if (battle_config.day_duration != 0 && battle_config.day_duration < 60000) // added by [Yor] - battle_config.day_duration = 60000; - if (battle_config.night_duration != 0 && battle_config.night_duration < 60000) // added by [Yor] - battle_config.night_duration = 60000; - - if (battle_config.ban_spoof_namer < 0) // added by [Yor] - battle_config.ban_spoof_namer = 0; - else if (battle_config.ban_spoof_namer > 32767) - battle_config.ban_spoof_namer = 32767; - - if (battle_config.hack_info_GM_level < 0) // added by [Yor] - battle_config.hack_info_GM_level = 0; - else if (battle_config.hack_info_GM_level > 100) - battle_config.hack_info_GM_level = 100; - - if (battle_config.any_warp_GM_min_level < 0) // added by [Yor] - battle_config.any_warp_GM_min_level = 0; - else if (battle_config.any_warp_GM_min_level > 100) - battle_config.any_warp_GM_min_level = 100; - - // at least 1 client must be accepted - if ((battle_config.packet_ver_flag & 255) == 0) // added by [Yor] - battle_config.packet_ver_flag = 255; // accept all clients - - if (battle_config.night_darkness_level > 10) // Celest - battle_config.night_darkness_level = 10; - - if (battle_config.motd_type < 0) - battle_config.motd_type = 0; - else if (battle_config.motd_type > 1) - battle_config.motd_type = 1; - - if (battle_config.finding_ore_rate < 0) - battle_config.finding_ore_rate = 0; - - if (battle_config.vending_max_value > 10000000 || battle_config.vending_max_value<=0) // Lupus & Kobra_k88 - battle_config.vending_max_value = 10000000; - - if (battle_config.min_skill_delay_limit < 10) - battle_config.min_skill_delay_limit = 10; // minimum delay of 10ms -} - -/*========================================== - * 設定ファイルを読み込む - *------------------------------------------ - */ -int battle_config_read(const char *cfgName) -{ - char line[1024], w1[1024], w2[1024]; - FILE *fp; - static int count = 0; - - if ((count++) == 0) - battle_set_defaults(); - - fp = fopen(cfgName,"r"); - if (fp == NULL) { - printf("File not found: %s\n", cfgName); - return 1; - } - while(fgets(line,1020,fp)){ - if (line[0] == '/' && line[1] == '/') - continue; - if (sscanf(line, "%[^:]:%s", w1, w2) != 2) - continue; - battle_set_value(w1, w2); - if (strcmpi(w1, "import") == 0) - battle_config_read(w2); - } - fclose(fp); - - if (--count == 0) { - battle_validate_conf(); - add_timer_func_list(battle_delay_damage_sub, "battle_delay_damage_sub"); - } - - return 0; -} diff --git a/src/map/battle.h b/src/map/battle.h deleted file mode 100644 index 393cc58b4..000000000 --- a/src/map/battle.h +++ /dev/null @@ -1,328 +0,0 @@ -// $Id: battle.h,v 1.6 2004/09/29 21:08:17 Akitasha Exp $ -#ifndef _BATTLE_H_ -#define _BATTLE_H_ - -// ダメージ -struct Damage { - int damage,damage2; - int type,div_; - int amotion,dmotion; - int blewcount; - int flag; - int dmg_lv; //囲まれ減算計算用 0:スキル攻撃 ATK_LUCKY,ATK_FLEE,ATK_DEF -}; - -// 属性表(読み込みはpc.c、battle_attr_fixで使用) -extern int attr_fix_table[4][10][10]; - -struct map_session_data; -struct mob_data; -struct block_list; - -// ダメージ計算 - -struct Damage battle_calc_attack( int attack_type, - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag); -struct Damage battle_calc_weapon_attack( - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag); -struct Damage battle_calc_magic_attack( - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag); -struct Damage battle_calc_misc_attack( - struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag); - -// 属性修正計算 -int battle_attr_fix(int damage,int atk_elem,int def_elem); - -// ダメージ最終計算 -int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag); -enum { // 最終計算のフラグ - BF_WEAPON = 0x0001, - BF_MAGIC = 0x0002, - BF_MISC = 0x0004, - BF_SHORT = 0x0010, - BF_LONG = 0x0040, - BF_SKILL = 0x0100, - BF_NORMAL = 0x0200, - BF_WEAPONMASK=0x000f, - BF_RANGEMASK= 0x00f0, - BF_SKILLMASK= 0x0f00, -}; - -// 実際にHPを増減 -int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_list *target,int damage,int flag); -int battle_damage(struct block_list *bl,struct block_list *target,int damage,int flag); -int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp,int flag); - -// 攻撃や移動を止める -int battle_stopattack(struct block_list *bl); -int battle_stopwalking(struct block_list *bl,int type); - -// 通常攻撃処理まとめ -int battle_weapon_attack( struct block_list *bl,struct block_list *target, - unsigned int tick,int flag); - -// 各種パラメータを得る -int battle_counttargeted(struct block_list *bl,struct block_list *src,int target_lv); - -enum { - BCT_NOENEMY =0x00000, - BCT_PARTY =0x10000, - BCT_ENEMY =0x40000, - BCT_NOPARTY =0x50000, - BCT_ALL =0x20000, - BCT_NOONE =0x60000, - BCT_SELF =0x60000, -}; - -int battle_check_undead(int race,int element); -int battle_check_target( struct block_list *src, struct block_list *target,int flag); -int battle_check_range(struct block_list *src,struct block_list *bl,int range); - - -// 設定 - -int battle_config_switch(const char *str); // [Valaris] - -extern struct Battle_Config { - int warp_point_debug; - int enemy_critical; - int enemy_critical_rate; - int enemy_str; - int enemy_perfect_flee; - int cast_rate,delay_rate,delay_dependon_dex; - int sdelay_attack_enable; - int left_cardfix_to_right; - int pc_skill_add_range; - int skill_out_range_consume; - int mob_skill_add_range; - int pc_damage_delay; - int pc_damage_delay_rate; - int defnotenemy; - int random_monster_checklv; - int attr_recover; - int flooritem_lifetime; - int item_auto_get; - int item_first_get_time; - int item_second_get_time; - int item_third_get_time; - int mvp_item_first_get_time; - int mvp_item_second_get_time; - int mvp_item_third_get_time; - int item_rate,base_exp_rate,job_exp_rate; // removed item rate, depreciated - int drop_rate0item; - int death_penalty_type; - int death_penalty_base,death_penalty_job; - int pvp_exp; // [MouseJstr] - int gtb_pvp_only; // [MouseJstr] - int zeny_penalty; - int restart_hp_rate; - int restart_sp_rate; - int mvp_item_rate,mvp_exp_rate; - int mvp_hp_rate; - int monster_hp_rate; - int monster_max_aspd; - int atc_gmonly; - int atc_spawn_quantity_limit; - int gm_allskill; - int gm_allskill_addabra; - int gm_allequip; - int gm_skilluncond; - int skillfree; - int skillup_limit; - int wp_rate; - int pp_rate; - int monster_active_enable; - int monster_damage_delay_rate; - int monster_loot_type; - int mob_skill_use; - int mob_count_rate; - int quest_skill_learn; - int quest_skill_reset; - int basic_skill_check; - int guild_emperium_check; - int guild_exp_limit; - int guild_max_castles; - int pc_invincible_time; - int pet_catch_rate; - int pet_rename; - int pet_friendly_rate; - int pet_hungry_delay_rate; - int pet_hungry_friendly_decrease; - int pet_str; - int pet_status_support; - int pet_attack_support; - int pet_damage_support; - int pet_support_rate; - int pet_attack_exp_to_master; - int pet_attack_exp_rate; - int skill_min_damage; - int finger_offensive_type; - int heal_exp; - int resurrection_exp; - int shop_exp; - int combo_delay_rate; - int item_check; - int wedding_modifydisplay; - int natural_healhp_interval; - int natural_healsp_interval; - int natural_heal_skill_interval; - int natural_heal_weight_rate; - int item_name_override_grffile; - int indoors_override_grffile; // [Celest] - int skill_sp_override_grffile; // [Celest] - int cardillust_read_grffile; - int item_equip_override_grffile; - int item_slots_override_grffile; - int arrow_decrement; - int max_aspd; - int max_hp; - int max_sp; - int max_lv; - unsigned int max_parameter; - int max_cart_weight; - int pc_skill_log; - int mob_skill_log; - int battle_log; - int save_log; - int error_log; - int etc_log; - int save_clothcolor; - int undead_detect_type; - int pc_auto_counter_type; - int monster_auto_counter_type; - int agi_penalty_type; - int agi_penalty_count; - int agi_penalty_num; - int vit_penalty_type; - int vit_penalty_count; - int vit_penalty_num; - int player_defense_type; - int monster_defense_type; - int pet_defense_type; - int magic_defense_type; - int pc_skill_reiteration; - int monster_skill_reiteration; - int pc_skill_nofootset; - int monster_skill_nofootset; - int pc_cloak_check_type; - int monster_cloak_check_type; - int gvg_short_damage_rate; - int gvg_long_damage_rate; - int gvg_magic_damage_rate; - int gvg_misc_damage_rate; - int gvg_eliminate_time; - int mob_changetarget_byskill; - int pc_attack_direction_change; - int monster_attack_direction_change; - int pc_land_skill_limit; - int monster_land_skill_limit; - int party_skill_penalty; - int monster_class_change_full_recover; - int produce_item_name_input; - int produce_potion_name_input; - int making_arrow_name_input; - int holywater_name_input; - int display_delay_skill_fail; - int display_snatcher_skill_fail; - int chat_warpportal; - int mob_warpportal; - int dead_branch_active; - int vending_max_value; -// int pet_lootitem; // removed [Valaris] -// int pet_weight; // removed [Valaris] - int show_steal_in_same_party; - int pet_attack_attr_none; - int mob_attack_attr_none; - int mob_ghostring_fix; - int pc_attack_attr_none; - int item_rate_common,item_rate_card,item_rate_equip,item_rate_heal,item_rate_use; // Added by RoVeRT, Additional Heal and Usable item rate by Val - int item_drop_common_min,item_drop_common_max; // Added by TyrNemesis^ - int item_drop_card_min,item_drop_card_max; - int item_drop_equip_min,item_drop_equip_max; - int item_drop_mvp_min,item_drop_mvp_max; // End Addition - int item_drop_heal_min,item_drop_heal_max; // Added by Valatris - int item_drop_use_min,item_drop_use_max; //End - - int prevent_logout; // Added by RoVeRT - - int alchemist_summon_reward; // [Valaris] - unsigned int maximum_level; - int drops_by_luk; - int monsters_ignore_gm; - int equipment_breaking; - int equipment_break_rate; - int pet_equip_required; - int multi_level_up; - int pk_mode; - int show_mob_hp; // end additions [Valaris] - - int agi_penalty_count_lv; - int vit_penalty_count_lv; - - int gx_allhit; - int gx_cardfix; - int gx_dupele; - int gx_disptype; - int devotion_level_difference; - int player_skill_partner_check; - int hide_GM_session; - int unit_movement_type; - int invite_request_check; - int skill_removetrap_type; - int disp_experience; - int castle_defense_rate; - int backstab_bow_penalty; - int hp_rate; - int sp_rate; - int gm_can_drop_lv; - int disp_hpmeter; - int bone_drop; - int monster_damage_delay; - -// eAthena additions - int night_at_start; // added by [Yor] - int day_duration; // added by [Yor] - int night_duration; // added by [Yor] - int ban_spoof_namer; // added by [Yor] - int ban_hack_trade; // added by [Yor] - int hack_info_GM_level; // added by [Yor] - int any_warp_GM_min_level; // added by [Yor] - int packet_ver_flag; // added by [Yor] - int muting_players; // added by [PoW] - - int min_hair_style; // added by [MouseJstr] - int max_hair_style; // added by [MouseJstr] - int min_hair_color; // added by [MouseJstr] - int max_hair_color; // added by [MouseJstr] - int min_cloth_color; // added by [MouseJstr] - int max_cloth_color; // added by [MouseJstr] - - int castrate_dex_scale; // added by [MouseJstr] - int area_size; // added by [MouseJstr] - - int zeny_from_mobs; // [Valaris] - int mobs_level_up; // [Valaris] - unsigned int pk_min_level; // [celest] - int skill_steal_type; // [celest] - int skill_steal_rate; // [celest] - int night_darkness_level; // [celest] - int motd_type; // [celest] - int allow_atcommand_when_mute; // [celest] - int finding_ore_rate; // orn - int exp_calc_type; - int min_skill_delay_limit; - int require_glory_guild; - int idle_no_share; - -#ifndef TXT_ONLY /* SQL-only options */ - int mail_system; // [Valaris] -#endif - -} battle_config; - -extern int battle_config_read(const char *cfgName); -extern void battle_validate_conf(); -extern void battle_set_defaults(); -extern int battle_set_value(char *, char *); - -#endif diff --git a/src/map/charcommand.c b/src/map/charcommand.c deleted file mode 100644 index 9b700dc47..000000000 --- a/src/map/charcommand.c +++ /dev/null @@ -1,1257 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <math.h> - -#include "../common/socket.h" -#include "../common/timer.h" -#include "../common/nullpo.h" - -#include "log.h" -#include "clif.h" -#include "chrif.h" -#include "intif.h" -#include "itemdb.h" -#include "map.h" -#include "pc.h" -#include "status.h" -#include "skill.h" -#include "mob.h" -#include "pet.h" -#include "battle.h" -#include "party.h" -#include "guild.h" -#include "charcommand.h" -#include "atcommand.h" -#include "script.h" -#include "npc.h" -#include "trade.h" -#include "core.h" -#include "showmsg.h" - -static char command_symbol = '#'; - -extern char *msg_table[1000]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) - -#define CCMD_FUNC(x) int charcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message) - -CCMD_FUNC(jobchange); -CCMD_FUNC(petrename); -CCMD_FUNC(petfriendly); -CCMD_FUNC(stats); -CCMD_FUNC(option); -CCMD_FUNC(save); -CCMD_FUNC(stats_all); -CCMD_FUNC(reset); -CCMD_FUNC(spiritball); -CCMD_FUNC(itemlist); -CCMD_FUNC(effect); -CCMD_FUNC(storagelist); -CCMD_FUNC(item); -CCMD_FUNC(warp); -CCMD_FUNC(zeny); -CCMD_FUNC(showexp); -CCMD_FUNC(showdelay); - -#ifdef TXT_ONLY -/* TXT_ONLY */ - -/* TXT_ONLY */ -#else -/* SQL-only */ - -/* SQL Only */ -#endif - -/*========================================== - *CharCommandInfo charcommand_info[]構造体の定義 - *------------------------------------------ - */ - -// First char of commands is configured in charcommand_athena.conf. Leave @ in this list for default value. -// to set default level, read charcommand_athena.conf first please. -static CharCommandInfo charcommand_info[] = { - { CharCommandJobChange, "#job", 60, charcommand_jobchange }, - { CharCommandJobChange, "#jobchange", 60, charcommand_jobchange }, - { CharCommandPetRename, "#petrename", 50, charcommand_petrename }, - { CharCommandPetFriendly, "#petfriendly", 50, charcommand_petfriendly }, - { CharCommandStats, "#stats", 40, charcommand_stats }, - { CharCommandOption, "#option", 60, charcommand_option }, - { CharCommandReset, "#reset", 60, charcommand_reset }, - { CharCommandSave, "#save", 60, charcommand_save }, - { CharCommandStatsAll, "#statsall", 40, charcommand_stats_all }, - { CharCommandSpiritball, "#spiritball", 40, charcommand_spiritball }, - { CharCommandItemList, "#itemlist", 40, charcommand_itemlist }, - { CharCommandEffect, "#effect", 40, charcommand_effect }, - { CharCommandStorageList, "#storagelist", 40, charcommand_storagelist }, - { CharCommandItem, "#item", 60, charcommand_item }, - { CharCommandWarp, "#warp", 60, charcommand_warp }, - { CharCommandWarp, "#rura", 60, charcommand_warp }, - { CharCommandWarp, "#rura+", 60, charcommand_warp }, - { CharCommandZeny, "#zeny", 60, charcommand_zeny }, - { CharCommandShowExp, "#showexp", 0, charcommand_showexp}, - { CharCommandShowDelay, "#showdelay", 0, charcommand_showdelay}, - - -#ifdef TXT_ONLY -/* TXT_ONLY */ - -/* TXT_ONLY */ -#else -/* SQL-only */ - -/* SQL Only */ -#endif - -// add new commands before this line - { CharCommand_Unknown, NULL, 1, NULL } -}; - - -int get_charcommand_level(const CharCommandType type) { - int i; - - for (i = 0; charcommand_info[i].type != CharCommand_None; i++) - if (charcommand_info[i].type == type) - return charcommand_info[i].level; - - return 100; // 100: command can not be used -} - -/*========================================== - *is_charcommand @コマンドに存在するかどうか確認する - *------------------------------------------ - */ -CharCommandType -is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl) { - const char* str = message; - int s_flag = 0; - CharCommandInfo info; - CharCommandType type; - - nullpo_retr(CharCommand_None, sd); - - if (!message || !*message) - return CharCommand_None; - - memset(&info, 0, sizeof(info)); - str += strlen(sd->status.name); - while (*str && (isspace(*str) || (s_flag == 0 && *str == ':'))) { - if (*str == ':') - s_flag = 1; - str++; - } - if (!*str) - return CharCommand_None; - - type = charcommand(gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info); - if (type != CharCommand_None) { - char command[100]; - char output[200]; - const char* p = str; - memset(command, '\0', sizeof(command)); - memset(output, '\0', sizeof(output)); - while (*p && !isspace(*p)) - p++; - if (p - str >= sizeof(command)) // too long - return CharCommand_Unknown; - strncpy(command, str, p - str); - while (isspace(*p)) - p++; - - if (type == CharCommand_Unknown || info.proc == NULL) { - snprintf(output, sizeof(output),msg_txt(153), command); // %s is Unknown Command. - clif_displaymessage(fd, output); - } else { - if (info.proc(fd, sd, command, p) != 0) { - // Command can not be executed - snprintf(output, sizeof(output), msg_txt(154), command); // %s failed. - clif_displaymessage(fd, output); - } - } - - return info.type; - } - - return CharCommand_None; -} - -/*========================================== - * - *------------------------------------------ - */ -CharCommandType charcommand(const int level, const char* message, struct CharCommandInfo* info) { - char* p = (char *)message; - - if (!info) - return CharCommand_None; - if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd) - return CharCommand_None; - if (!p || !*p) { - fprintf(stderr, "char command message is empty\n"); - return CharCommand_None; - } - - if (*p == command_symbol) { // check first char. - char command[101]; - int i = 0; - memset(info, 0, sizeof(CharCommandInfo)); - sscanf(p, "%100s", command); - command[sizeof(command)-1] = '\0'; - - while (charcommand_info[i].type != CharCommand_Unknown) { - if (strcmpi(command+1, charcommand_info[i].command+1) == 0 && level >= charcommand_info[i].level) { - p[0] = charcommand_info[i].command[0]; // set correct first symbol for after. - break; - } - i++; - } - - if (charcommand_info[i].type == CharCommand_Unknown) { - // doesn't return Unknown if player is normal player (display the text, not display: unknown command) - if (level == 0) - return CharCommand_None; - else - return CharCommand_Unknown; - } - memcpy(info, &charcommand_info[i], sizeof charcommand_info[i]); - } else { - return CharCommand_None; - } - - return info->type; -} - - -/*========================================== - * - *------------------------------------------ - */ -static CharCommandInfo* get_charcommandinfo_byname(const char* name) { - int i; - - for (i = 0; charcommand_info[i].type != CharCommand_Unknown; i++) - if (strcmpi(charcommand_info[i].command + 1, name) == 0) - return &charcommand_info[i]; - - return NULL; -} - -/*========================================== - * - *------------------------------------------ - */ -int charcommand_config_read(const char *cfgName) { - char line[1024], w1[1024], w2[1024]; - CharCommandInfo* p; - FILE* fp; - - if ((fp = fopen(cfgName, "r")) == NULL) { - printf("CharCommands configuration file not found: %s\n", cfgName); - return 1; - } - - while (fgets(line, sizeof(line)-1, fp)) { - if (line[0] == '/' && line[1] == '/') - continue; - - if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2) - continue; - p = get_charcommandinfo_byname(w1); - if (p != NULL) { - p->level = atoi(w2); - if (p->level > 100) - p->level = 100; - else if (p->level < 0) - p->level = 0; - } - - if (strcmpi(w1, "import") == 0) - charcommand_config_read(w2); - else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 && - w2[0] != '/' && // symbol of standard ragnarok GM commands - w2[0] != '%' // symbol of party chat speaking - ) - command_symbol = w2[0]; - } - fclose(fp); - - return 0; -} - -/*========================================== - * 対象キャラクターを転職させる upper指定で転生や養子も可能 - *------------------------------------------ - */ -int charcommand_jobchange( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char character[100]; - struct map_session_data* pl_sd; - int job = 0, upper = -1; - - memset(character, '\0', sizeof(character)); - - if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a job and a player name (usage: #job/#jobchange <job ID> <char name>)."); - return -1; - } - - if (sscanf(message, "%d %d %99[^\n]", &job, &upper, character) < 3) { //upper指定してある - upper = -1; - if (sscanf(message, "%d %99[^\n]", &job, character) < 2) { //upper指定してない上に何か足りない - clif_displaymessage(fd, "Please, enter a job and a player name (usage: #job/#jobchange <job ID> <char name>)."); - return -1; - } - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - int j; - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job only to lower or same level - if ((job >= 0 && job < MAX_PC_CLASS)) { - - // fix pecopeco display - if ((job != 13 && job != 21 && job != 4014 && job != 4022)) { - if (pc_isriding(sd)) { - if (pl_sd->status.class_ == 13) - pl_sd->status.class_ = pl_sd->view_class = 7; - if (pl_sd->status.class_ == 21) - pl_sd->status.class_ = pl_sd->view_class = 14; - if (pl_sd->status.class_ == 4014) - pl_sd->status.class_ = pl_sd->view_class = 4008; - if (pl_sd->status.class_ == 4022) - pl_sd->status.class_ = pl_sd->view_class = 4015; - pl_sd->status.option &= ~0x0020; - clif_changeoption(&pl_sd->bl); - status_calc_pc(pl_sd, 0); - } - } else { - if (!pc_isriding(sd)) { - if (job == 13) - job = 7; - if (job == 21) - job = 14; - if (job == 4014) - job = 4008; - if (job == 4022) - job = 4015; - } - } - for (j=0; j < MAX_INVENTORY; j++) { - if(pl_sd->status.inventory[j].nameid>0 && pl_sd->status.inventory[j].equip!=0) - pc_unequipitem(pl_sd, j, 3); - } - if (pc_jobchange(pl_sd, job, upper) == 0) - clif_displaymessage(fd, msg_table[48]); // Character's job changed. - else { - clif_displaymessage(fd, msg_table[192]); // Impossible to change the character's job. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[49]); // Invalid job ID. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int charcommand_petrename( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char character[100]; - struct map_session_data *pl_sd; - - memset(character, '\0', sizeof(character)); - - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: #petrename <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pl_sd->status.pet_id > 0 && pl_sd->pd) { - if (pl_sd->pet.rename_flag != 0) { - pl_sd->pet.rename_flag = 0; - intif_save_petdata(pl_sd->status.account_id, &pl_sd->pet); - clif_send_petstatus(pl_sd); - clif_displaymessage(fd, msg_table[189]); // This player can now rename his/her pet. - } else { - clif_displaymessage(fd, msg_table[190]); // This player can already rename his/her pet. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[191]); // Sorry, but this player has no pet. - return -1; - } - } else { - clif_displaymessage(fd, msg_txt(3)); // Character not found. - return -1; - } - - return 0; -} - - -/*========================================== - * - *------------------------------------------ - */ -int charcommand_petfriendly( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - int friendly = 0; - int t = 0; - char character[100]; - struct map_session_data *pl_sd; - - memset(character, '\0', sizeof(character)); - if (!message || !*message || sscanf(message,"%d %s",&friendly,character) < 2) { - clif_displaymessage(fd, "Please, enter a valid value (usage: " - "#petfriendly <0-1000> <player>)."); - return -1; - } - - if (((pl_sd = map_nick2sd(character)) != NULL) && pc_isGM(sd)>pc_isGM(pl_sd)) { - if (pl_sd->status.pet_id > 0 && pl_sd->pd) { - if (friendly >= 0 && friendly <= 1000) { - if (friendly != pl_sd->pet.intimate) { - t = pl_sd->pet.intimate; - pl_sd->pet.intimate = friendly; - clif_send_petstatus(pl_sd); - clif_pet_emotion(pl_sd->pd,0); - if (battle_config.pet_status_support) { - if ((pl_sd->pet.intimate > 0 && t <= 0) || - (pl_sd->pet.intimate <= 0 && t > 0)) { - if (pl_sd->bl.prev != NULL) - status_calc_pc(pl_sd, 0); - else - status_calc_pc(pl_sd, 2); - } - } - clif_displaymessage(pl_sd->fd, msg_table[182]); // Pet friendly value changed! - clif_displaymessage(sd->fd, msg_table[182]); // Pet friendly value changed! - } else { - clif_displaymessage(fd, msg_table[183]); // Pet friendly is already the good value. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - } else { - return -1; - } - } else { - clif_displaymessage(fd, msg_txt(3)); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int charcommand_stats( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char character[100]; - char job_jobname[100]; - char output[200]; - struct map_session_data *pl_sd; - int i; - - memset(character, '\0', sizeof(character)); - memset(job_jobname, '\0', sizeof(job_jobname)); - memset(output, '\0', sizeof(output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: #stats <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - struct { - const char* format; - int value; - } output_table[] = { - { "Base Level - %d", pl_sd->status.base_level }, - { job_jobname, pl_sd->status.job_level }, - { "Hp - %d", pl_sd->status.hp }, - { "MaxHp - %d", pl_sd->status.max_hp }, - { "Sp - %d", pl_sd->status.sp }, - { "MaxSp - %d", pl_sd->status.max_sp }, - { "Str - %3d", pl_sd->status.str }, - { "Agi - %3d", pl_sd->status.agi }, - { "Vit - %3d", pl_sd->status.vit }, - { "Int - %3d", pl_sd->status.int_ }, - { "Dex - %3d", pl_sd->status.dex }, - { "Luk - %3d", pl_sd->status.luk }, - { "Zeny - %d", pl_sd->status.zeny }, - { NULL, 0 } - }; - sprintf(job_jobname, "Job - %s %s", job_name(pl_sd->status.class_), "(level %d)"); - sprintf(output, msg_table[53], pl_sd->status.name); // '%s' stats: - clif_displaymessage(fd, output); - for (i = 0; output_table[i].format != NULL; i++) { - sprintf(output, output_table[i].format, output_table[i].value); - clif_displaymessage(fd, output); - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * Character Reset - *------------------------------------------ - */ -int charcommand_reset( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char character[100]; - char output[200]; - struct map_session_data *pl_sd; - - memset(character, '\0', sizeof(character)); - memset(output, '\0', sizeof(output)); - - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: #reset <charname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset a character only for lower or same GM level - pc_resetstate(pl_sd); - pc_resetskill(pl_sd); - sprintf(output, msg_table[208], character); // '%s' skill and stats points reseted! - clif_displaymessage(fd, output); - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int charcommand_option( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char character[100]; - int opt1 = 0, opt2 = 0, opt3 = 0; - struct map_session_data* pl_sd; - - memset(character, '\0', sizeof(character)); - - if (!message || !*message || - sscanf(message, "%d %d %d %99[^\n]", &opt1, &opt2, &opt3, character) < 4 || - opt1 < 0 || opt2 < 0 || opt3 < 0) { - clif_displaymessage(fd, "Please, enter valid options and a player name (usage: #option <param1> <param2> <param3> <charname>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change option only to lower or same level - pl_sd->opt1 = opt1; - pl_sd->opt2 = opt2; - pl_sd->status.option = opt3; - // fix pecopeco display - if (pl_sd->status.class_ == 13 || pl_sd->status.class_ == 21 || pl_sd->status.class_ == 4014 || pl_sd->status.class_ == 4022) { - if (!pc_isriding(pl_sd)) { // pl_sd have the new value... - if (pl_sd->status.class_ == 13) - pl_sd->status.class_ = pl_sd->view_class = 7; - else if (pl_sd->status.class_ == 21) - pl_sd->status.class_ = pl_sd->view_class = 14; - else if (pl_sd->status.class_ == 4014) - pl_sd->status.class_ = pl_sd->view_class = 4008; - else if (pl_sd->status.class_ == 4022) - pl_sd->status.class_ = pl_sd->view_class = 4015; - } - } else { - if (pc_isriding(pl_sd)) { // pl_sd have the new value... - if (pl_sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor]) - pl_sd->status.option &= ~0x0020; - } else { - if (pl_sd->status.class_ == 7) - pl_sd->status.class_ = pl_sd->view_class = 13; - else if (pl_sd->status.class_ == 14) - pl_sd->status.class_ = pl_sd->view_class = 21; - else if (pl_sd->status.class_ == 4008) - pl_sd->status.class_ = pl_sd->view_class = 4014; - else if (pl_sd->status.class_ == 4015) - pl_sd->status.class_ = pl_sd->view_class = 4022; - else - pl_sd->status.option &= ~0x0020; - } - } - } - clif_changeoption(&pl_sd->bl); - status_calc_pc(pl_sd, 0); - clif_displaymessage(fd, msg_table[58]); // Character's options changed. - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int charcommand_save( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char map_name[100]; - char character[100]; - struct map_session_data* pl_sd; - int x = 0, y = 0; - int m; - - memset(map_name, '\0', sizeof(map_name)); - memset(character, '\0', sizeof(character)); - - if (!message || !*message || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, character) < 4 || x < 0 || y < 0) { - clif_displaymessage(fd, "Please, enter a valid save point and a player name (usage: #save <map> <x> <y> <charname>)."); - return -1; - } - - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change save point only to lower or same gm level - m = map_mapname2mapid(map_name); - if (m < 0) { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } else { - if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to set this map as a save map."); - return -1; - } - pc_setsavepoint(pl_sd, map_name, x, y); - clif_displaymessage(fd, msg_table[57]); // Character's respawn point changed. - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -//** Character Stats All by fritz -int charcommand_stats_all(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - char output[1024], gmlevel[1024]; - int i; - int count; - struct map_session_data *pl_sd; - - memset(output, '\0', sizeof(output)); - memset(gmlevel, '\0', sizeof(gmlevel)); - - count = 0; - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - - if (pc_isGM(pl_sd) > 0) - sprintf(gmlevel, "| GM Lvl: %d", pc_isGM(pl_sd)); - else - sprintf(gmlevel, " "); - - sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level, pl_sd->status.hp, pl_sd->status.max_hp, pl_sd->status.sp, pl_sd->status.max_sp); - clif_displaymessage(fd, output); - sprintf(output, "STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s", pl_sd->status.str, pl_sd->status.agi, pl_sd->status.vit, pl_sd->status.int_, pl_sd->status.dex, pl_sd->status.luk, pl_sd->status.zeny, gmlevel); - clif_displaymessage(fd, output); - clif_displaymessage(fd, "--------"); - count++; - } - } - - if (count == 0) - clif_displaymessage(fd, msg_table[28]); // No player found. - else if (count == 1) - clif_displaymessage(fd, msg_table[29]); // 1 player found. - else { - sprintf(output, msg_table[30], count); // %d players found. - clif_displaymessage(fd, output); - } - - return 0; -} - -/*========================================== - * CharSpiritBall Function by PalasX - *------------------------------------------ - */ -int charcommand_spiritball(const int fd, struct map_session_data* sd,const char* command, const char* message) -{ - struct map_session_data *pl_sd; - char character[100]; - int spirit = 0; - - memset(character, '\0', sizeof(character)); - - if(!message || !*message || sscanf(message, "%d %99[^\n]", &spirit, character) < 2 || spirit < 0 || spirit > 1000) { - clif_displaymessage(fd, "Usage: @spiritball <number: 0-1000>) <CHARACTER_NAME>."); - return -1; - } - - if((pl_sd = map_nick2sd(character)) != NULL) { - if (spirit >= 0 && spirit <= 0x7FFF) { - if (pl_sd->spiritball != spirit || spirit > 999) { - if (pl_sd->spiritball > 0) - pc_delspiritball(pl_sd, pl_sd->spiritball, 1); - pl_sd->spiritball = spirit; - clif_spiritball(pl_sd); - // no message, player can look the difference - if (spirit > 1000) - clif_displaymessage(fd, msg_table[204]); // WARNING: more than 1000 spiritballs can CRASH your server and/or client! - } else { - clif_displaymessage(fd, msg_table[205]); // You already have this number of spiritballs. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[37]); // An invalid number was specified. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - return 0; -} - -/*========================================== - * #itemlist <character>: Displays the list of a player's items. - *------------------------------------------ - */ -int -charcommand_itemlist( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - struct item_data *item_data, *item_temp; - int i, j, equip, count, counter, counter2; - char character[100], output[200], equipstr[100], outputtmp[200]; - nullpo_retr(-1, sd); - - memset(character, '\0', sizeof(character)); - memset(output, '\0', sizeof(output)); - memset(equipstr, '\0', sizeof(equipstr)); - memset(outputtmp, '\0', sizeof(outputtmp)); - - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: #itemlist <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level - counter = 0; - count = 0; - for (i = 0; i < MAX_INVENTORY; i++) { - if (pl_sd->status.inventory[i].nameid > 0 && (item_data = itemdb_search(pl_sd->status.inventory[i].nameid)) != NULL) { - counter = counter + pl_sd->status.inventory[i].amount; - count++; - if (count == 1) { - sprintf(output, "------ Items list of '%s' ------", pl_sd->status.name); - clif_displaymessage(fd, output); - } - if ((equip = pl_sd->status.inventory[i].equip)) { - strcpy(equipstr, "| equiped: "); - if (equip & 4) - strcat(equipstr, "robe/gargment, "); - if (equip & 8) - strcat(equipstr, "left accessory, "); - if (equip & 16) - strcat(equipstr, "body/armor, "); - if ((equip & 34) == 2) - strcat(equipstr, "right hand, "); - if ((equip & 34) == 32) - strcat(equipstr, "left hand, "); - if ((equip & 34) == 34) - strcat(equipstr, "both hands, "); - if (equip & 64) - strcat(equipstr, "feet, "); - if (equip & 128) - strcat(equipstr, "right accessory, "); - if ((equip & 769) == 1) - strcat(equipstr, "lower head, "); - if ((equip & 769) == 256) - strcat(equipstr, "top head, "); - if ((equip & 769) == 257) - strcat(equipstr, "lower/top head, "); - if ((equip & 769) == 512) - strcat(equipstr, "mid head, "); - if ((equip & 769) == 512) - strcat(equipstr, "lower/mid head, "); - if ((equip & 769) == 769) - strcat(equipstr, "lower/mid/top head, "); - // remove final ', ' - equipstr[strlen(equipstr) - 2] = '\0'; - } else - memset(equipstr, '\0', sizeof(equipstr)); - if (sd->status.inventory[i].refine) - sprintf(output, "%d %s %+d (%s %+d, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, pl_sd->status.inventory[i].refine, item_data->jname, pl_sd->status.inventory[i].refine, pl_sd->status.inventory[i].nameid, equipstr); - else - sprintf(output, "%d %s (%s, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, item_data->jname, pl_sd->status.inventory[i].nameid, equipstr); - clif_displaymessage(fd, output); - memset(output, '\0', sizeof(output)); - counter2 = 0; - for (j = 0; j < item_data->slot; j++) { - if (pl_sd->status.inventory[i].card[j]) { - if ((item_temp = itemdb_search(pl_sd->status.inventory[i].card[j])) != NULL) { - if (output[0] == '\0') - sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); - else - sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); - strcat(output, outputtmp); - } - } - } - if (output[0] != '\0') { - output[strlen(output) - 2] = ')'; - output[strlen(output) - 1] = '\0'; - clif_displaymessage(fd, output); - } - } - } - if (count == 0) - clif_displaymessage(fd, "No item found on this player."); - else { - sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count); - clif_displaymessage(fd, output); - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * #effect by [MouseJstr] - * - * Create a effect localized on another character - *------------------------------------------ - */ -int -charcommand_effect(const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd = NULL; - char target[255]; - int type = 0; - nullpo_retr(-1, sd); - - if (!message || !*message || sscanf(message, "%d %s", &type, target) != 2) { - clif_displaymessage(fd, "usage: #effect <type+> <target>."); - return -1; - } - - if((pl_sd=map_nick2sd((char *) target)) == NULL) - return -1; - - clif_specialeffect(&pl_sd->bl, type, 0); - clif_displaymessage(fd, msg_table[229]); // Your effect has changed. - - return 0; -} - -/*========================================== - * #storagelist <character>: Displays the items list of a player's storage. - *------------------------------------------ - */ -int -charcommand_storagelist( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct storage *stor; - struct map_session_data *pl_sd; - struct item_data *item_data, *item_temp; - int i, j, count, counter, counter2; - char character[100], output[200], outputtmp[200]; - nullpo_retr(-1, sd); - - memset(character, '\0', sizeof(character)); - memset(output, '\0', sizeof(output)); - memset(outputtmp, '\0', sizeof(outputtmp)); - - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) { - clif_displaymessage(fd, "Please, enter a player name (usage: #itemlist <char name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level - if((stor = account2storage2(pl_sd->status.account_id)) != NULL) { - counter = 0; - count = 0; - for (i = 0; i < MAX_STORAGE; i++) { - if (stor->storage_[i].nameid > 0 && (item_data = itemdb_search(stor->storage_[i].nameid)) != NULL) { - counter = counter + stor->storage_[i].amount; - count++; - if (count == 1) { - sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name); - clif_displaymessage(fd, output); - } - if (stor->storage_[i].refine) - sprintf(output, "%d %s %+d (%s %+d, id: %d)", stor->storage_[i].amount, item_data->name, stor->storage_[i].refine, item_data->jname, stor->storage_[i].refine, stor->storage_[i].nameid); - else - sprintf(output, "%d %s (%s, id: %d)", stor->storage_[i].amount, item_data->name, item_data->jname, stor->storage_[i].nameid); - clif_displaymessage(fd, output); - memset(output, '\0', sizeof(output)); - counter2 = 0; - for (j = 0; j < item_data->slot; j++) { - if (stor->storage_[i].card[j]) { - if ((item_temp = itemdb_search(stor->storage_[i].card[j])) != NULL) { - if (output[0] == '\0') - sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); - else - sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); - strcat(output, outputtmp); - } - } - } - if (output[0] != '\0') { - output[strlen(output) - 2] = ')'; - output[strlen(output) - 1] = '\0'; - clif_displaymessage(fd, output); - } - } - } - if (count == 0) - clif_displaymessage(fd, "No item found in the storage of this player."); - else { - sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count); - clif_displaymessage(fd, output); - } - } else { - clif_displaymessage(fd, "This player has no storage."); - return 0; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -static void -charcommand_giveitem_sub(struct map_session_data *sd,struct item_data *item_data,int number) -{ - int flag = 0; - int loop = 1, get_count = number,i; - struct item item_tmp; - - if(sd && item_data){ - if (item_data->type == 4 || item_data->type == 5 || - item_data->type == 7 || item_data->type == 8) { - loop = number; - get_count = 1; - } - for (i = 0; i < loop; i++) { - memset(&item_tmp, 0, sizeof(item_tmp)); - item_tmp.nameid = item_data->nameid; - item_tmp.identify = 1; - if ((flag = pc_additem((struct map_session_data*)sd, - &item_tmp, get_count))) - clif_additem((struct map_session_data*)sd, 0, 0, flag); - } - } -} -/*========================================== - * #item command (usage: #item <name/id_of_item> <quantity> <player>) - * by MC Cameri - *------------------------------------------ - */ -int charcommand_item( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char item_name[100]; - char character[100]; - struct map_session_data *pl_sd; - int number = 0, item_id, flag; - struct item item_tmp; - struct item_data *item_data; - int get_count, i, pet_id; - nullpo_retr(-1, sd); - - memset(item_name, '\0', sizeof(item_name)); - - if (!message || !*message || sscanf(message, "%99s %d %99[^\n]", item_name, &number, character) < 3) { - clif_displaymessage(fd, "Please, enter an item name/id (usage: #item <item name or ID> <quantity> <char name>)."); - return -1; - } - - if (number <= 0) - number = 1; - - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) - item_id = item_data->nameid; - - if (item_id >= 500) { - get_count = number; - // check pet egg - pet_id = search_petDB_index(item_id, PET_EGG); - if (item_data->type == 4 || item_data->type == 5 || - item_data->type == 7 || item_data->type == 8) { - get_count = 1; - } - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level - for (i = 0; i < number; i += get_count) { - // if pet egg - if (pet_id >= 0) { - pl_sd->catch_target_class = pet_db[pet_id].class_; - intif_create_pet(pl_sd->status.account_id, pl_sd->status.char_id, - (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv, - (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate, - 100, 0, 1, pet_db[pet_id].jname); - // if not pet egg - } else { - memset(&item_tmp, 0, sizeof(item_tmp)); - item_tmp.nameid = item_id; - item_tmp.identify = 1; - if ((flag = pc_additem(pl_sd, &item_tmp, get_count))) - clif_additem(pl_sd, 0, 0, flag); - } - } - clif_displaymessage(fd, msg_table[18]); // Item created. - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else if(/* from jA's @giveitem */strcmpi(character,"all")==0 || strcmpi(character,"everyone")==0){ - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data)){ - charcommand_giveitem_sub(pl_sd,item_data,number); - snprintf(tmp_output, sizeof(tmp_output), "You got %s %d.", item_name,number); - clif_displaymessage(pl_sd->fd, tmp_output); - } - } - snprintf(tmp_output, sizeof(tmp_output), "%s received %s %d.","Everyone",item_name,number); - clif_displaymessage(fd, tmp_output); - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name. - return -1; - } - - return 0; -} - -/*========================================== - * #warp/#rura/#rura+ <mapname> <x> <y> <char name> - *------------------------------------------ - */ -int charcommand_warp( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - char map_name[100]; - char character[100]; - int x = 0, y = 0; - struct map_session_data *pl_sd; - int m; - - nullpo_retr(-1, sd); - - memset(map_name, '\0', sizeof(map_name)); - memset(character, '\0', sizeof(character)); - - if (!message || !*message || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, character) < 4) { - clif_displaymessage(fd, "Usage: #warp/#rura/#rura+ <mapname> <x> <y> <char name>"); - return -1; - } - - if (x <= 0) - x = rand() % 399 + 1; - if (y <= 0) - y = rand() % 399 + 1; - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - - if ((pl_sd = map_nick2sd(character)) != NULL) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can rura+ only lower or same GM level - if (x > 0 && x < 400 && y > 0 && y < 400) { - m = map_mapname2mapid(map_name); - if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp someone to this map."); - return -1; - } - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { - clif_displaymessage(fd, "You are not authorised to warp this player from its actual map."); - return -1; - } - if (pc_setpos(pl_sd, map_name, x, y, 3) == 0) { - clif_displaymessage(pl_sd->fd, msg_table[0]); // Warped. - clif_displaymessage(fd, msg_table[15]); // Player warped (message sends to player too). - } else { - clif_displaymessage(fd, msg_table[1]); // Map not found. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[2]); // Coordinates out of range. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*========================================== - * #zeny <charname> - *------------------------------------------ - */ -int charcommand_zeny( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - struct map_session_data *pl_sd; - char character[100]; - int zeny = 0, new_zeny; - nullpo_retr(-1, sd); - - memset(character, '\0', sizeof(character)); - - if (!message || !*message || sscanf(message, "%d %99[^\n]", &zeny, character) < 2 || zeny == 0) { - clif_displaymessage(fd, "Please, enter a number and a player name (usage: #zeny <zeny> <name>)."); - return -1; - } - - if ((pl_sd = map_nick2sd(character)) != NULL) { - new_zeny = pl_sd->status.zeny + zeny; - if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow - new_zeny = MAX_ZENY; - else if (zeny < 0 && (zeny < -MAX_ZENY || new_zeny < 0)) // fix negativ overflow - new_zeny = 0; - if (new_zeny != pl_sd->status.zeny) { - pl_sd->status.zeny = new_zeny; - clif_updatestatus(pl_sd, SP_ZENY); - clif_displaymessage(fd, msg_table[211]); // Character's number of zenys changed! - } else { - if (zeny < 0) - clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value. - else - clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value. - return -1; - } - } else { - clif_displaymessage(fd, msg_table[3]); // Character not found. - return -1; - } - - return 0; -} - -/*=================================== - * Remove some messages - *----------------------------------- - */ -int charcommand_showexp( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - if (sd->noexp) { - sd->noexp = 0; - clif_displaymessage(fd, "Gained exp is now shown"); - return 0; - } - else { - sd->noexp = 1; - clif_displaymessage(fd, "Gained exp is now NOT shown"); - return 0; - } -} - -int charcommand_showdelay( - const int fd, struct map_session_data* sd, - const char* command, const char* message) -{ - if (sd->nodelay) { - sd->nodelay = 0; - clif_displaymessage(fd, "Skill delay failure is now shown"); - return 0; - } - else { - sd->nodelay = 1; - clif_displaymessage(fd, "Skill delay failure is NOT now shown"); - return 0; - } -} - diff --git a/src/map/charcommand.h b/src/map/charcommand.h deleted file mode 100644 index 7c1618cca..000000000 --- a/src/map/charcommand.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _CHARCOMMAND_H_ -#define _CHARCOMMAND_H_ - -enum CharCommandType { - CharCommand_None = -1, - CharCommandJobChange, - CharCommandPetRename, - CharCommandPetFriendly, - CharCommandReset, - CharCommandStats, - CharCommandOption, - CharCommandSave, - CharCommandStatsAll, - CharCommandSpiritball, - CharCommandItemList, - CharCommandEffect, - CharCommandStorageList, - CharCommandItem, // by MC Cameri - CharCommandWarp, - CharCommandZeny, - CharCommandShowDelay, - CharCommandShowExp, - -#ifdef TXT_ONLY -/* TXT_ONLY */ - -/* TXT_ONLY */ -#else -/* SQL-only */ - -/* SQL Only */ -#endif - - // End. No more commans after this line. - CharCommand_Unknown, - CharCommand_MAX -}; - -typedef enum CharCommandType CharCommandType; - -typedef struct CharCommandInfo { - CharCommandType type; - const char* command; - int level; - int (*proc)(const int, struct map_session_data*, - const char* command, const char* message); -} CharCommandInfo; - -CharCommandType -is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl); - -CharCommandType charcommand( - const int level, const char* message, CharCommandInfo* info); -int get_charcommand_level(const CharCommandType type); - -int charcommand_config_read(const char *cfgName); - -#endif - diff --git a/src/map/chat.c b/src/map/chat.c deleted file mode 100644 index 3bd29fec3..000000000 --- a/src/map/chat.c +++ /dev/null @@ -1,378 +0,0 @@ -// $Id: chat.c,v 1.2 2004/09/22 02:59:47 Akitasha Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "db.h" -#include "nullpo.h" -#include "malloc.h" -#include "map.h" -#include "clif.h" -#include "pc.h" -#include "chat.h" -#include "npc.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -int chat_triggerevent(struct chat_data *cd); - - -/*========================================== - * チャットルーム作成 - *------------------------------------------ - */ -int chat_createchat(struct map_session_data *sd,int limit,int pub,char* pass,char* title,int titlelen) -{ - struct chat_data *cd; - - nullpo_retr(0, sd); - - cd = (struct chat_data *) aCalloc(1,sizeof(struct chat_data)); - - cd->limit = limit; - cd->pub = pub; - cd->users = 1; - memcpy(cd->pass,pass,8); - if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1; - memcpy(cd->title,title,titlelen); - cd->title[titlelen]=0; - - cd->owner = (struct block_list **)(&cd->usersd[0]); - cd->usersd[0] = sd; - cd->bl.m = sd->bl.m; - cd->bl.x = sd->bl.x; - cd->bl.y = sd->bl.y; - cd->bl.type = BL_CHAT; - - cd->bl.id = map_addobject(&cd->bl); - if(cd->bl.id==0){ - clif_createchat(sd,1); - aFree(cd); - return 0; - } - pc_setchatid(sd,cd->bl.id); - - clif_createchat(sd,0); - clif_dispchat(cd,0); - - return 0; -} - -/*========================================== - * 既存チャットルームに参加 - *------------------------------------------ - */ -int chat_joinchat(struct map_session_data *sd,int chatid,char* pass) -{ - struct chat_data *cd; - - nullpo_retr(0, sd); - - cd=(struct chat_data*)map_id2bl(chatid); - if(cd==NULL) - return 1; - - if(cd->bl.m != sd->bl.m || cd->limit <= cd->users){ - clif_joinchatfail(sd,0); - return 0; - } - if(cd->pub==0 && strncmp(pass,(char *) cd->pass,8)){ - clif_joinchatfail(sd,1); - return 0; - } - if(chatid == (int)sd->chatID) //Double Chat fix by Alex14, thx CHaNGeTe - { - clif_joinchatfail(sd,1); - return 0; - } - - cd->usersd[cd->users] = sd; - cd->users++; - - pc_setchatid(sd,cd->bl.id); - - - clif_joinchatok(sd,cd); // 新たに参加した人には全員のリスト - clif_addchat(cd,sd); // 既に中に居た人には追加した人の報告 - clif_dispchat(cd,0); // 周囲の人には人数変化報告 - - chat_triggerevent(cd); // イベント - - return 0; -} - -/*========================================== - * チャットルームから抜ける - *------------------------------------------ - */ -int chat_leavechat(struct map_session_data *sd) -{ - struct chat_data *cd; - int i,leavechar; - - nullpo_retr(1, sd); - - cd=(struct chat_data*)map_id2bl(sd->chatID); - if(cd==NULL) - return 1; - - for(i = 0,leavechar=-1;i < cd->users;i++){ - if(cd->usersd[i] == sd){ - leavechar=i; - break; - } - } - if(leavechar<0) // そのchatに所属していないらしい (バグ時のみ) - return -1; - - if(leavechar==0 && cd->users>1 && (*cd->owner)->type==BL_PC){ - // 所有者だった&他に人が居る&PCのチャット - clif_changechatowner(cd,cd->usersd[1]); - clif_clearchat(cd,0); - } - - // 抜けるPCにも送るのでusersを減らす前に実行 - clif_leavechat(cd,sd); - - cd->users--; - pc_setchatid(sd,0); - - if(cd->users == 0 && (*cd->owner)->type==BL_PC){ - // 全員居なくなった&PCのチャットなので消す - clif_clearchat(cd,0); - map_delobject(cd->bl.id); // freeまでしてくれる - } else { - for(i=leavechar;i < cd->users;i++) - cd->usersd[i] = cd->usersd[i+1]; - if(leavechar==0 && (*cd->owner)->type==BL_PC){ - // PCのチャットなので所有者が抜けたので位置変更 - cd->bl.x=cd->usersd[0]->bl.x; - cd->bl.y=cd->usersd[0]->bl.y; - } - clif_dispchat(cd,0); - } - - return 0; -} - -/*========================================== - * チャットルームの持ち主を譲る - *------------------------------------------ - */ -int chat_changechatowner(struct map_session_data *sd,char *nextownername) -{ - struct chat_data *cd; - struct map_session_data *tmp_sd; - int i,nextowner; - - nullpo_retr(1, sd); - - cd=(struct chat_data*)map_id2bl(sd->chatID); - if(cd==NULL || (struct block_list *)sd!=(*cd->owner)) - return 1; - - for(i = 1,nextowner=-1;i < cd->users;i++){ - if(strcmp(cd->usersd[i]->status.name,nextownername)==0){ - nextowner=i; - break; - } - } - if(nextowner<0) // そんな人は居ない - return -1; - - clif_changechatowner(cd,cd->usersd[nextowner]); - // 一旦消す - clif_clearchat(cd,0); - - // userlistの順番変更 (0が所有者なので) - if( (tmp_sd = cd->usersd[0]) == NULL ) - return 1; //ありえるのかな? - cd->usersd[0] = cd->usersd[nextowner]; - cd->usersd[nextowner] = tmp_sd; - - // 新しい所有者の位置へ変更 - cd->bl.x=cd->usersd[0]->bl.x; - cd->bl.y=cd->usersd[0]->bl.y; - - // 再度表示 - clif_dispchat(cd,0); - - return 0; -} - -/*========================================== - * チャットの状態(タイトル等)を変更 - *------------------------------------------ - */ -int chat_changechatstatus(struct map_session_data *sd,int limit,int pub,char* pass,char* title,int titlelen) -{ - struct chat_data *cd; - - nullpo_retr(1, sd); - - cd=(struct chat_data*)map_id2bl(sd->chatID); - if(cd==NULL || (struct block_list *)sd!=(*cd->owner)) - return 1; - - cd->limit = limit; - cd->pub = pub; - memcpy(cd->pass,pass,8); - if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1; - memcpy(cd->title,title,titlelen); - cd->title[titlelen]=0; - - clif_changechatstatus(cd); - clif_dispchat(cd,0); - - return 0; -} - -/*========================================== - * チャットルームから蹴り出す - *------------------------------------------ - */ -int chat_kickchat(struct map_session_data *sd,char *kickusername) -{ - struct chat_data *cd; - int i,kickuser; - - nullpo_retr(1, sd); - - cd=(struct chat_data*)map_id2bl(sd->chatID); - if(cd==NULL || (struct block_list *)sd!=(*cd->owner)) - return 1; - - for(i = 0,kickuser=-1;i < cd->users;i++){ - if(strcmp(cd->usersd[i]->status.name,kickusername)==0){ - kickuser=i; - break; - } - } - if(kickuser<0) // そんな人は居ない - return -1; - - chat_leavechat(cd->usersd[kickuser]); - - return 0; -} - -/*========================================== - * npcチャットルーム作成 - *------------------------------------------ - */ -int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,char* title,int titlelen,const char *ev) -{ - struct chat_data *cd; - - nullpo_retr(1, nd); - - cd = (struct chat_data *) aCalloc(1,sizeof(struct chat_data)); - - cd->limit = cd->trigger = limit; - if(trigger>0) - cd->trigger = trigger; - cd->pub = pub; - cd->users = 0; - memcpy(cd->pass,"",1); - if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1; - memcpy(cd->title,title,titlelen); - cd->title[titlelen]=0; - - cd->bl.m = nd->bl.m; - cd->bl.x = nd->bl.x; - cd->bl.y = nd->bl.y; - cd->bl.type = BL_CHAT; - cd->owner_ = (struct block_list *)nd; - cd->owner = &cd->owner_; - memcpy(cd->npc_event,ev,strlen(ev)); - - cd->bl.id = map_addobject(&cd->bl); - if(cd->bl.id==0){ - aFree(cd); - return 0; - } - nd->chat_id=cd->bl.id; - - clif_dispchat(cd,0); - - return 0; -} -/*========================================== - * npcチャットルーム削除 - *------------------------------------------ - */ -int chat_deletenpcchat(struct npc_data *nd) -{ - struct chat_data *cd; - - nullpo_retr(0, nd); - nullpo_retr(0, cd=(struct chat_data*)map_id2bl(nd->chat_id)); - - chat_npckickall(cd); - clif_clearchat(cd,0); - map_delobject(cd->bl.id); // freeまでしてくれる - nd->chat_id=0; - - return 0; -} - -/*========================================== - * 規定人数以上でイベントが定義されてるなら実行 - *------------------------------------------ - */ -int chat_triggerevent(struct chat_data *cd) -{ - nullpo_retr(0, cd); - - if(cd->users>=cd->trigger && cd->npc_event[0]) - npc_event_do(cd->npc_event); - return 0; -} - -/*========================================== - * イベントの有効化 - *------------------------------------------ - */ -int chat_enableevent(struct chat_data *cd) -{ - nullpo_retr(0, cd); - - cd->trigger&=0x7f; - chat_triggerevent(cd); - return 0; -} -/*========================================== - * イベントの無効化 - *------------------------------------------ - */ -int chat_disableevent(struct chat_data *cd) -{ - nullpo_retr(0, cd); - - cd->trigger|=0x80; - return 0; -} -/*========================================== - * チャットルームから全員蹴り出す - *------------------------------------------ - */ -int chat_npckickall(struct chat_data *cd) -{ - nullpo_retr(0, cd); - - while(cd->users>0){ - chat_leavechat(cd->usersd[cd->users-1]); - } - return 0; -} - -/*========================================== - * 終了 - *------------------------------------------ - */ -int do_final_chat(void) -{ - return 0; -} diff --git a/src/map/chat.h b/src/map/chat.h deleted file mode 100644 index 276160251..000000000 --- a/src/map/chat.h +++ /dev/null @@ -1,22 +0,0 @@ -// $Id: chat.h,v 1.3 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _CHAT_H_ -#define _CHAT_H_ - -#include "map.h" - -int chat_createchat(struct map_session_data *,int,int,char*,char*,int); -int chat_joinchat(struct map_session_data *,int,char*); -int chat_leavechat(struct map_session_data* ); -int chat_changechatowner(struct map_session_data *,char *); -int chat_changechatstatus(struct map_session_data *,int,int,char*,char*,int); -int chat_kickchat(struct map_session_data *,char *); - -int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,char* title,int titlelen,const char *ev); -int chat_deletenpcchat(struct npc_data *nd); -int chat_enableevent(struct chat_data *cd); -int chat_disableevent(struct chat_data *cd); -int chat_npckickall(struct chat_data *cd); - -int do_final_chat(void); - -#endif diff --git a/src/map/chrif.c b/src/map/chrif.c deleted file mode 100644 index e250c8a18..000000000 --- a/src/map/chrif.c +++ /dev/null @@ -1,1179 +0,0 @@ -// $Id: chrif.c,v 1.6 2004/09/25 11:39:17 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef _WIN32 -#include <winsock.h> -#else -#include <unistd.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif -#include <sys/types.h> -#include <time.h> - -#include "socket.h" -#include "timer.h" -#include "map.h" -#include "battle.h" -#include "chrif.h" -#include "clif.h" -#include "intif.h" -#include "npc.h" -#include "pc.h" -#include "nullpo.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -static const int packet_len_table[0x20] = { - 60, 3,-1,27,22,-1, 6,-1, // 2af8-2aff - 6,-1,18, 7,-1,49,44, 0, // 2b00-2b07 - 6,30,-1,10,86, 7,44,34, // 2b08-2b0f - -1,-1,10, 6,11,-1, 0, 0, // 2b10-2b17 -}; - -int chrif_connected; -int char_fd = -1; -int srvinfo; -static char char_ip_str[16]; -static int char_ip; -static int char_port = 6121; -static char userid[24], passwd[24]; -static int chrif_state = 0; -static int char_init_done = 0; - -// 設定ファイル読み込み関係 -/*========================================== - * - *------------------------------------------ - */ -void chrif_setuserid(char *id) -{ - strncpy(userid, id, 24); -} - -/*========================================== - * - *------------------------------------------ - */ -void chrif_setpasswd(char *pwd) -{ - strncpy(passwd, pwd, 24); -} - -/*========================================== - * - *------------------------------------------ - */ -void chrif_setip(char *ip) -{ - strncpy(char_ip_str, ip, 16); - char_ip = inet_addr(char_ip_str); -} - -/*========================================== - * - *------------------------------------------ - */ -void chrif_setport(int port) -{ - char_port = port; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_isconnect(void) -{ - return chrif_state == 2; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_save(struct map_session_data *sd) -{ - nullpo_retr(-1, sd); - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - pc_makesavestatus(sd); - - WFIFOW(char_fd,0) = 0x2b01; - WFIFOW(char_fd,2) = sizeof(sd->status) + 12; - WFIFOL(char_fd,4) = sd->bl.id; - WFIFOL(char_fd,8) = sd->char_id; - memcpy(WFIFOP(char_fd,12), &sd->status, sizeof(sd->status)); - WFIFOSET(char_fd, WFIFOW(char_fd,2)); - - storage_storage_save(sd); // to synchronise storage with character [Yor] - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_connect(int fd) -{ - WFIFOW(fd,0) = 0x2af8; - memcpy(WFIFOP(fd,2), userid, 24); - memcpy(WFIFOP(fd,26), passwd, 24); - WFIFOL(fd,50) = 0; - WFIFOL(fd,54) = clif_getip(); - WFIFOW(fd,58) = clif_getport(); // [Valaris] thanks to fov - WFIFOSET(fd,60); - - return 0; -} - -/*========================================== - * マップ送信 - *------------------------------------------ - */ -int chrif_sendmap(int fd) -{ - int i; - - WFIFOW(fd,0) = 0x2afa; - for(i = 0; i < map_num; i++) - if (map[i].alias != '\0') // [MouseJstr] map aliasing - memcpy(WFIFOP(fd,4+i*16), map[i].alias, 16); - else - memcpy(WFIFOP(fd,4+i*16), map[i].name, 16); - WFIFOW(fd,2) = 4 + i * 16; - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -/*========================================== - * マップ受信 - *------------------------------------------ - */ -int chrif_recvmap(int fd) -{ - int i, j, ip, port; - unsigned char *p = (unsigned char *)&ip; - - if (chrif_state < 2) // まだ準備中 - return -1; - - ip = RFIFOL(fd,4); - port = RFIFOW(fd,8); - for(i = 10, j = 0; i < RFIFOW(fd,2); i += 16, j++) { - map_setipport((char*)RFIFOP(fd,i), ip, port); -// if (battle_config.etc_log) -// printf("recv map %d %s\n", j, RFIFOP(fd,i)); - } - if (battle_config.etc_log) - printf("recv map on %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j); - - return 0; -} - -/*========================================== - * マップ鯖間移動のためのデータ準備要求 - *------------------------------------------ - */ -int chrif_changemapserver(struct map_session_data *sd, char *name, int x, int y, int ip, short port) -{ - int i, s_ip; - - nullpo_retr(-1, sd); - - if( !sd || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - s_ip = 0; - for(i = 0; i < fd_max; i++) - if (session[i] && session[i]->session_data == sd) { - s_ip = session[i]->client_addr.sin_addr.s_addr; - break; - } - - WFIFOW(char_fd, 0) = 0x2b05; - WFIFOL(char_fd, 2) = sd->bl.id; - WFIFOL(char_fd, 6) = sd->login_id1; - WFIFOL(char_fd,10) = sd->login_id2; - WFIFOL(char_fd,14) = sd->status.char_id; - memcpy(WFIFOP(char_fd,18), name, 16); - WFIFOW(char_fd,34) = x; - WFIFOW(char_fd,36) = y; - WFIFOL(char_fd,38) = ip; - WFIFOL(char_fd,42) = port; - WFIFOB(char_fd,44) = sd->status.sex; - WFIFOL(char_fd,45) = s_ip; - WFIFOSET(char_fd,49); - - return 0; -} - -/*========================================== - * マップ鯖間移動ack - *------------------------------------------ - */ -int chrif_changemapserverack(int fd) -{ - struct map_session_data *sd = map_id2sd(RFIFOL(fd,2)); - - if (sd == NULL || sd->status.char_id != RFIFOL(fd,14)) - return -1; - - if (RFIFOL(fd,6) == 1) { - if (battle_config.error_log) - printf("map server change failed.\n"); - pc_authfail(sd->fd); - return 0; - } - clif_changemapserver(sd, (char*)RFIFOP(fd,18), RFIFOW(fd,34), RFIFOW(fd,36), RFIFOL(fd,38), RFIFOW(fd,42)); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_connectack(int fd) -{ - if (RFIFOB(fd,2)) { - printf("Connected to char-server failed %d.\n", RFIFOB(fd,2)); - exit(1); - } - sprintf(tmp_output,"Successfully connected to Char Server (Connection: '"CL_WHITE"%d"CL_RESET"').\n",fd); - ShowStatus(tmp_output); - chrif_state = 1; - chrif_connected=1; - - chrif_sendmap(fd); - - sprintf(tmp_output,"Event '"CL_WHITE"OnCharIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnCharIfInit")); - ShowStatus(tmp_output); - sprintf(tmp_output,"Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit")); - ShowStatus(tmp_output); - if(!char_init_done) { - char_init_done = 1; - sprintf(tmp_output,"Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce")); - ShowStatus(tmp_output); - } - - // <Agit> Run Event [AgitInit] -// printf("NPC_Event:[OnAgitInit] do (%d) events (Agit Initialize).\n", npc_event_doall("OnAgitInit")); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_sendmapack(int fd) -{ - if (RFIFOB(fd,2)) { - printf("chrif : send map list to char server failed %d\n", RFIFOB(fd,2)); - exit(1); - } - - memcpy(wisp_server_name, RFIFOP(fd,3), 24); - - chrif_state = 2; - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_authreq(struct map_session_data *sd) -{ - int i; - - nullpo_retr(-1, sd); - - if(!sd || !sd->bl.id || !sd->login_id1) - return -1; - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - for(i = 0; i < fd_max; i++) - if (session[i] && session[i]->session_data == sd) { - WFIFOW(char_fd, 0) = 0x2afc; - WFIFOL(char_fd, 2) = sd->bl.id; - WFIFOL(char_fd, 6) = sd->char_id; - WFIFOL(char_fd,10) = sd->login_id1; - WFIFOL(char_fd,14) = sd->login_id2; - WFIFOL(char_fd,18) = session[i]->client_addr.sin_addr.s_addr; - WFIFOSET(char_fd,22); - break; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_charselectreq(struct map_session_data *sd) -{ - int i, s_ip; - - nullpo_retr(-1, sd); - - if( !sd || !sd->bl.id || !sd->login_id1 ) - return -1; - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - s_ip = 0; - for(i = 0; i < fd_max; i++) - if (session[i] && session[i]->session_data == sd) { - s_ip = session[i]->client_addr.sin_addr.s_addr; - break; - } - - WFIFOW(char_fd, 0) = 0x2b02; - WFIFOL(char_fd, 2) = sd->bl.id; - WFIFOL(char_fd, 6) = sd->login_id1; - WFIFOL(char_fd,10) = sd->login_id2; - WFIFOL(char_fd,14) = s_ip; - WFIFOSET(char_fd,18); - - return 0; -} - -/*========================================== - * キャラ名問い合わせ - *------------------------------------------ - */ -int chrif_searchcharid(int char_id) -{ - if( !char_id ) - return -1; - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b08; - WFIFOL(char_fd,2) = char_id; - WFIFOSET(char_fd,6); - - return 0; -} - -/*========================================== - * GMに変化要求 - *------------------------------------------ - */ -int chrif_changegm(int id, const char *pass, int len) -{ - if (battle_config.etc_log) - printf("chrif_changegm: account: %d, password: '%s'.\n", id, pass); - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b0a; - WFIFOW(char_fd,2) = len + 8; - WFIFOL(char_fd,4) = id; - memcpy(WFIFOP(char_fd,8), pass, len); - WFIFOSET(char_fd, len + 8); - - return 0; -} - -/*========================================== - * Change Email - *------------------------------------------ - */ -int chrif_changeemail(int id, const char *actual_email, const char *new_email) -{ - if (battle_config.etc_log) - printf("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email); - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b0c; - WFIFOL(char_fd,2) = id; - memcpy(WFIFOP(char_fd,6), actual_email, 40); - memcpy(WFIFOP(char_fd,46), new_email, 40); - WFIFOSET(char_fd,86); - - return 0; -} - -/*========================================== - * Send message to char-server with a character name to do some operations (by Yor) - * Used to ask Char-server about a character name to have the account number to modify account file in login-server. - * type of operation: - * 1: block - * 2: ban - * 3: unblock - * 4: unban - * 5: changesex - *------------------------------------------ - */ -int chrif_char_ask_name(int id, char * character_name, short operation_type, int year, int month, int day, int hour, int minute, int second) -{ - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd, 0) = 0x2b0e; - WFIFOL(char_fd, 2) = id; // account_id of who ask (for answer) -1 if nobody - memcpy(WFIFOP(char_fd,6), character_name, 24); - WFIFOW(char_fd, 30) = operation_type; // type of operation - if (operation_type == 2) { - WFIFOW(char_fd, 32) = year; - WFIFOW(char_fd, 34) = month; - WFIFOW(char_fd, 36) = day; - WFIFOW(char_fd, 38) = hour; - WFIFOW(char_fd, 40) = minute; - WFIFOW(char_fd, 42) = second; - } - printf("chrif : sended 0x2b0e\n"); - WFIFOSET(char_fd,44); - - return 0; -} - -/*========================================== - * 性別変化要求 - *------------------------------------------ - */ -int chrif_changesex(int id, int sex) { - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b11; - WFIFOW(char_fd,2) = 9; - WFIFOL(char_fd,4) = id; - WFIFOB(char_fd,8) = sex; - printf("chrif : sent 0x3000(changesex)\n"); - WFIFOSET(char_fd,9); - return 0; -} - -/*========================================== - * Answer after a request about a character name to do some operations (by Yor) - * Used to answer of chrif_char_ask_name. - * type of operation: - * 1: block - * 2: ban - * 3: unblock - * 4: unban - * 5: changesex - * type of answer: - * 0: login-server resquest done - * 1: player not found - * 2: gm level too low - * 3: login-server offline - *------------------------------------------ - */ -int chrif_char_ask_name_answer(int fd) -{ - int acc; - struct map_session_data *sd; - char output[256]; - char player_name[24]; - - acc = RFIFOL(fd,2); // account_id of who has asked (-1 if nobody) - memcpy(player_name, RFIFOP(fd,6), sizeof(player_name)); - player_name[sizeof(player_name)-1] = '\0'; - - sd = map_id2sd(acc); - if (acc >= 0 && sd != NULL) { - if (RFIFOW(fd, 32) == 1) // player not found - sprintf(output, "The player '%s' doesn't exist.", player_name); - else { - switch(RFIFOW(fd, 30)) { - case 1: // block - switch(RFIFOW(fd, 32)) { - case 0: // login-server resquest done - sprintf(output, "Login-server has been asked to block the player '%s'.", player_name); - break; - //case 1: // player not found - case 2: // gm level too low - sprintf(output, "Your GM level don't authorise you to block the player '%s'.", player_name); - break; - case 3: // login-server offline - sprintf(output, "Login-server is offline. Impossible to block the the player '%s'.", player_name); - break; - } - break; - case 2: // ban - switch(RFIFOW(fd, 32)) { - case 0: // login-server resquest done - sprintf(output, "Login-server has been asked to ban the player '%s'.", player_name); - break; - //case 1: // player not found - case 2: // gm level too low - sprintf(output, "Your GM level don't authorise you to ban the player '%s'.", player_name); - break; - case 3: // login-server offline - sprintf(output, "Login-server is offline. Impossible to ban the the player '%s'.", player_name); - break; - } - break; - case 3: // unblock - switch(RFIFOW(fd, 32)) { - case 0: // login-server resquest done - sprintf(output, "Login-server has been asked to unblock the player '%s'.", player_name); - break; - //case 1: // player not found - case 2: // gm level too low - sprintf(output, "Your GM level don't authorise you to unblock the player '%s'.", player_name); - break; - case 3: // login-server offline - sprintf(output, "Login-server is offline. Impossible to unblock the the player '%s'.", player_name); - break; - } - break; - case 4: // unban - switch(RFIFOW(fd, 32)) { - case 0: // login-server resquest done - sprintf(output, "Login-server has been asked to unban the player '%s'.", player_name); - break; - //case 1: // player not found - case 2: // gm level too low - sprintf(output, "Your GM level don't authorise you to unban the player '%s'.", player_name); - break; - case 3: // login-server offline - sprintf(output, "Login-server is offline. Impossible to unban the the player '%s'.", player_name); - break; - } - break; - case 5: // changesex - switch(RFIFOW(fd, 32)) { - case 0: // login-server resquest done - sprintf(output, "Login-server has been asked to change the sex of the player '%s'.", player_name); - break; - //case 1: // player not found - case 2: // gm level too low - sprintf(output, "Your GM level don't authorise you to change the sex of the player '%s'.", player_name); - break; - case 3: // login-server offline - sprintf(output, "Login-server is offline. Impossible to change the sex of the the player '%s'.", player_name); - break; - } - break; - } - } - if (output[0] != '\0') { - output[sizeof(output)-1] = '\0'; - clif_displaymessage(sd->fd, output); - } - } else - printf("chrif_char_ask_name_answer failed - player not online.\n"); - - return 0; -} - -/*========================================== - * End of GM change (@GM) (modified by Yor) - *------------------------------------------ - */ -int chrif_changedgm(int fd) -{ - int acc, level; - struct map_session_data *sd = NULL; - - acc = RFIFOL(fd,2); - level = RFIFOL(fd,6); - - sd = map_id2sd(acc); - - if (battle_config.etc_log) - printf("chrif_changedgm: account: %d, GM level 0 -> %d.\n", acc, level); - if (sd != NULL) { - if (level > 0) - clif_displaymessage(sd->fd, "GM modification success."); - else - clif_displaymessage(sd->fd, "Failure of GM modification."); - } - - return 0; -} - -/*========================================== - * 性別変化終了 (modified by Yor) - *------------------------------------------ - */ -int chrif_changedsex(int fd) -{ - int acc, sex, i; - struct map_session_data *sd; - struct pc_base_job s_class; - - acc = RFIFOL(fd,2); - sex = RFIFOL(fd,6); - if (battle_config.etc_log) - printf("chrif_changedsex %d.\n", acc); - sd = map_id2sd(acc); - if (acc > 0) { - if (sd != NULL && sd->status.sex != sex) { - s_class = pc_calc_base_job(sd->status.class_); - if (sd->status.sex == 0) { - sd->status.sex = 1; - sd->sex = 1; - } else if (sd->status.sex == 1) { - sd->status.sex = 0; - sd->sex = 0; - } - // to avoid any problem with equipment and invalid sex, equipment is unequiped. - for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid && sd->status.inventory[i].equip) - pc_unequipitem((struct map_session_data*)sd, i, 2); - } - // reset skill of some job - if (s_class.job == 19 || s_class.job == 4020 || s_class.job == 4042 || - s_class.job == 20 || s_class.job == 4021 || s_class.job == 4043) { - // remove specifical skills of classes 19, 4020 and 4042 - for(i = 315; i <= 322; i++) { - if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) { - sd->status.skill_point += sd->status.skill[i].lv; - sd->status.skill[i].id = 0; - sd->status.skill[i].lv = 0; - } - } - // remove specifical skills of classes 20, 4021 and 4043 - for(i = 323; i <= 330; i++) { - if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) { - sd->status.skill_point += sd->status.skill[i].lv; - sd->status.skill[i].id = 0; - sd->status.skill[i].lv = 0; - } - } - clif_updatestatus(sd, SP_SKILLPOINT); - // change job if necessary - if (s_class.job == 20 || s_class.job == 4021 || s_class.job == 4043) - sd->status.class_ -= 1; - else if (s_class.job == 19 || s_class.job == 4020 || s_class.job == 4042) - sd->status.class_ += 1; - } - // save character - chrif_save(sd); - sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters - // do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it) - clif_displaymessage(sd->fd, "Your sex has been changed (need disconnection by the server)..."); - clif_setwaitclose(sd->fd); // forced to disconnect for the change - } - } else { - if (sd != NULL) { - printf("chrif_changedsex failed.\n"); - } - } - - return 0; -} - -/*========================================== - * アカウント変数保存要求 - *------------------------------------------ - */ -int chrif_saveaccountreg2(struct map_session_data *sd) -{ - int p, j; - nullpo_retr(-1, sd); - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - p = 8; - for(j = 0; j < sd->status.account_reg2_num; j++) { - struct global_reg *reg = &sd->status.account_reg2[j]; - if (reg->str[0] && reg->value != 0) { - memcpy(WFIFOP(char_fd,p), reg->str, 32); - WFIFOL(char_fd,p+32) = reg->value; - p += 36; - } - } - WFIFOW(char_fd,0) = 0x2b10; - WFIFOW(char_fd,2) = p; - WFIFOL(char_fd,4) = sd->bl.id; - WFIFOSET(char_fd,p); - - return 0; -} - -/*========================================== - * アカウント変数通知 - *------------------------------------------ - */ -int chrif_accountreg2(int fd) -{ - int j, p; - struct map_session_data *sd; - - if ((sd = map_id2sd(RFIFOL(fd,4))) == NULL) - return 1; - - for(p = 8, j = 0; p < RFIFOW(fd,2) && j < ACCOUNT_REG2_NUM; p += 36, j++) { - memcpy(sd->status.account_reg2[j].str, RFIFOP(fd,p), 32); - sd->status.account_reg2[j].value = RFIFOL(fd, p + 32); - } - sd->status.account_reg2_num = j; -// printf("chrif: accountreg2\n"); - - return 0; -} - -/*========================================== - * 離婚情報同期要求 - *------------------------------------------ - */ -int chrif_divorce(int char_id, int partner_id) -{ - struct map_session_data *sd = NULL; - - if (!char_id || !partner_id) - return 0; - - nullpo_retr(0, sd = map_nick2sd(map_charid2nick(partner_id))); - if (sd->status.partner_id == char_id) { - int i; - //離婚(相方は既にキャラが消えている筈なので) - sd->status.partner_id = 0; - - //相方の結婚指輪を剥奪 - for(i = 0; i < MAX_INVENTORY; i++) - if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) - pc_delitem(sd, i, 1, 0); - } - - return 0; -} - -/*========================================== - * Disconnection of a player (account has been deleted in login-server) by [Yor] - *------------------------------------------ - */ -int chrif_accountdeletion(int fd) -{ - int acc; - struct map_session_data *sd; - - acc = RFIFOL(fd,2); - if (battle_config.etc_log) - printf("chrif_accountdeletion %d.\n", acc); - sd = map_id2sd(acc); - if (acc > 0) { - if (sd != NULL) { - sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters - clif_displaymessage(sd->fd, "Your account has been deleted (disconnection)..."); - clif_setwaitclose(sd->fd); // forced to disconnect for the change - } - } else { - if (sd != NULL) - printf("chrif_accountdeletion failed - player not online.\n"); - } - - return 0; -} - -/*========================================== - * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor] - *------------------------------------------ - */ -int chrif_accountban(int fd) -{ - int acc; - struct map_session_data *sd; - - acc = RFIFOL(fd,2); - if (battle_config.etc_log) - printf("chrif_accountban %d.\n", acc); - sd = map_id2sd(acc); - if (acc > 0) { - if (sd != NULL) { - sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters - if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban - switch (RFIFOL(fd,7)) { // status or final date of a banishment - case 1: // 0 = Unregistered ID - clif_displaymessage(sd->fd, "Your account has 'Unregistered'."); - break; - case 2: // 1 = Incorrect Password - clif_displaymessage(sd->fd, "Your account has an 'Incorrect Password'..."); - break; - case 3: // 2 = This ID is expired - clif_displaymessage(sd->fd, "Your account has expired."); - break; - case 4: // 3 = Rejected from Server - clif_displaymessage(sd->fd, "Your account has been rejected from server."); - break; - case 5: // 4 = You have been blocked by the GM Team - clif_displaymessage(sd->fd, "Your account has been blocked by the GM Team."); - break; - case 6: // 5 = Your Game's EXE file is not the latest version - clif_displaymessage(sd->fd, "Your Game's EXE file is not the latest version."); - break; - case 7: // 6 = Your are Prohibited to log in until %s - clif_displaymessage(sd->fd, "Your account has been prohibited to log in."); - break; - case 8: // 7 = Server is jammed due to over populated - clif_displaymessage(sd->fd, "Server is jammed due to over populated."); - break; - case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this) - clif_displaymessage(sd->fd, "Your account has not more authorised."); - break; - case 100: // 99 = This ID has been totally erased - clif_displaymessage(sd->fd, "Your account has been totally erased."); - break; - default: - clif_displaymessage(sd->fd, "Your account has not more authorised."); - break; - } - } else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban - time_t timestamp; - char tmpstr[2048]; - timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment - strcpy(tmpstr, "Your account has been banished until "); - strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); - clif_displaymessage(sd->fd, tmpstr); - } - clif_setwaitclose(sd->fd); // forced to disconnect for the change - } - } else { - if (sd != NULL) - printf("chrif_accountban failed - player not online.\n"); - } - - return 0; -} - -/*========================================== - * キャラクター切断通知 - *------------------------------------------ - */ -int chrif_chardisconnect(struct map_session_data *sd) -{ - nullpo_retr(-1, sd); - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0)=0x2b18; - WFIFOL(char_fd,2)=sd->status.account_id; - WFIFOL(char_fd,6)=sd->status.char_id; - WFIFOSET(char_fd,10); - //printf("chrif: char disconnect: %d %s\n",sd->bl.id,sd->status.name); - return 0; - -} - -/*========================================== - * Receiving GM accounts and their levels from char-server by [Yor] - *------------------------------------------ - */ -int chrif_recvgmaccounts(int fd) -{ - sprintf(tmp_output,"From login-server: receiving information of '"CL_WHITE"%d"CL_RESET"' GM accounts.\n", pc_read_gm_account(fd)); - ShowInfo(tmp_output); - memset(tmp_output,'\0',sizeof(tmp_output)); - return 0; -} - -/*========================================== - * Request to reload GM accounts and their levels: send to char-server by [Yor] - *------------------------------------------ - */ -int chrif_reloadGMdb(void) -{ - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2af7; - WFIFOSET(char_fd, 2); - - return 0; -} - -/*========================================== - * Send rates and motd to char server [Wizputer] - *------------------------------------------ - */ - int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) -{ - char buf[256]; - FILE *fp; - int i; - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b16; - WFIFOW(char_fd,2) = base_rate; - WFIFOW(char_fd,4) = job_rate; - WFIFOW(char_fd,6) = drop_rate; - - if ((fp = fopen(motd_txt, "r")) != NULL) { - if (fgets(buf, 250, fp) != NULL) { - for(i = 0; buf[i]; i++) { - if (buf[i] == '\r' || buf[i] == '\n') { - buf[i] = 0; - break; - } - } - WFIFOW(char_fd,8) = sizeof(buf) + 10; - memcpy(WFIFOP(char_fd,10), buf, sizeof(buf)); - } - fclose(fp); - } else { - WFIFOW(char_fd,8) = sizeof(buf) + 10; - memcpy(WFIFOP(char_fd,10), buf, sizeof(buf)); - } - WFIFOSET(char_fd,WFIFOW(char_fd,8)); - - return 0; -} - -/*========================================= - * Tell char-server charcter disconnected [Wizputer] - *----------------------------------------- - */ - -int chrif_char_offline(struct map_session_data *sd) -{ - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b17; - WFIFOL(char_fd,2) = sd->status.char_id; - WFIFOL(char_fd,6) = sd->status.account_id; - WFIFOSET(char_fd,10); - - return 0; -} - -/*========================================= - * Tell char-server to reset all chars offline [Wizputer] - *----------------------------------------- - */ -int chrif_flush_fifo(void) { - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - set_nonblocking(char_fd, 0); - flush_fifos(); - set_nonblocking(char_fd, 1); - - return 0; -} - -/*========================================= - * Tell char-server to reset all chars offline [Wizputer] - *----------------------------------------- - */ -int chrif_char_reset_offline(void) { - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b18; - WFIFOSET(char_fd,2); - - return 0; -} - -/*========================================= - * Tell char-server charcter is online [Wizputer] - *----------------------------------------- - */ - -int chrif_char_online(struct map_session_data *sd) -{ - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) - return -1; - - WFIFOW(char_fd,0) = 0x2b19; - WFIFOL(char_fd,2) = sd->status.char_id; - WFIFOL(char_fd,6) = sd->status.account_id; - WFIFOSET(char_fd,10); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_disconnect_sub(struct map_session_data* sd,va_list va) { - clif_authfail_fd(sd->fd,1); - map_quit(sd); - return 0; -} - -int chrif_disconnect(int fd) { - if(fd == char_fd) { - char_fd = 0; - sprintf(tmp_output,"Map Server disconnected from Char Server.\n\n"); - ShowWarning(tmp_output); - clif_foreachclient(chrif_disconnect_sub); - chrif_connected = 0; - // 他のmap 鯖のデータを消す - map_eraseallipport(); - } - close(fd); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int chrif_parse(int fd) -{ - int packet_len, cmd; - // only char-server can have an access to here. - // so, if it isn't the char-server, we disconnect the session (fd != char_fd). - if (fd != char_fd || session[fd]->eof) { - if (fd == char_fd && chrif_connected == 1) { - chrif_disconnect (fd); -// check_connect_char_server(0, 0, 0, 0); - } - close(fd); - delete_session(fd); - return 0; - } - - while (RFIFOREST(fd) >= 2) { - cmd = RFIFOW(fd,0); - if (cmd < 0x2af8 || cmd >= 0x2af8 + (sizeof(packet_len_table) / sizeof(packet_len_table[0])) || - packet_len_table[cmd-0x2af8] == 0) { - - int r = intif_parse(fd); // intifに渡す - - if (r == 1) continue; // intifで処理した - if (r == 2) return 0; // intifで処理したが、データが足りない - - session[fd]->eof = 1; - return 0; - } - packet_len = packet_len_table[cmd-0x2af8]; - if (packet_len == -1) { - if (RFIFOREST(fd) < 4) - return 0; - packet_len = RFIFOW(fd,2); - } - if (RFIFOREST(fd) < packet_len) - return 0; - - switch(cmd) { - case 0x2af9: chrif_connectack(fd); break; - case 0x2afb: chrif_sendmapack(fd); break; - case 0x2afd: pc_authok(RFIFOL(fd,4), RFIFOL(fd,8), (time_t)RFIFOL(fd,12), (struct mmo_charstatus*)RFIFOP(fd,16)); break; - case 0x2afe: pc_authfail(RFIFOL(fd,2)); break; - case 0x2b00: map_setusers(fd); break; - case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break; - case 0x2b04: chrif_recvmap(fd); break; - case 0x2b06: chrif_changemapserverack(fd); break; - case 0x2b09: map_addchariddb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break; - case 0x2b0b: chrif_changedgm(fd); break; - case 0x2b0d: chrif_changedsex(fd); break; - case 0x2b0f: chrif_char_ask_name_answer(fd); break; - case 0x2b11: chrif_accountreg2(fd); break; - case 0x2b12: chrif_divorce(RFIFOL(fd,2), RFIFOL(fd,6)); break; - case 0x2b13: chrif_accountdeletion(fd); break; - case 0x2b14: chrif_accountban(fd); break; - case 0x2b15: chrif_recvgmaccounts(fd); break; - - default: - if (battle_config.error_log) - printf("chrif_parse : unknown packet %d %d\n", fd, RFIFOW(fd,0)); - session[fd]->eof = 1; - return 0; - } - RFIFOSKIP(fd, packet_len); - } - - return 0; -} - -/*========================================== - * timer関数 - * 今このmap鯖に繋がっているクライアント人数をchar鯖へ送る - *------------------------------------------ - */ -int send_users_tochar(int tid, unsigned int tick, int id, int data) { - int users = 0, i; - struct map_session_data *sd; - - if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) // Thanks to Toster - return 0; - - WFIFOW(char_fd,0) = 0x2aff; - for (i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->state.auth && - !((battle_config.hide_GM_session || (sd->status.option & OPTION_HIDE)) && pc_isGM(sd))) { - WFIFOL(char_fd,6+4*users) = sd->status.char_id; - users++; - } - } - WFIFOW(char_fd,2) = 6 + 4 * users; - WFIFOW(char_fd,4) = users; - WFIFOSET(char_fd,6+4*users); - - return 0; -} - -/*========================================== - * timer関数 - * char鯖との接続を確認し、もし切れていたら再度接続する - *------------------------------------------ - */ -int check_connect_char_server(int tid, unsigned int tick, int id, int data) { - static int displayed = 0; - if (char_fd <= 0 || session[char_fd] == NULL) { - if (!displayed) { - ShowStatus("Attempting to connect to Char Server. Please wait.\n"); - displayed = 1; - } - chrif_state = 0; - char_fd = make_connection(char_ip, char_port); - session[char_fd]->func_parse = chrif_parse; - realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); - - chrif_connect(char_fd); - chrif_connected = chrif_isconnect(); -#ifndef TXT_ONLY - srvinfo = 0; - } else { - if (srvinfo == 0) { - chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common); - srvinfo = 1; - } -#endif /* not TXT_ONLY */ - } - if (chrif_isconnect()) displayed = 0; - return 0; -} -/*========================================== - * 終了 - *------------------------------------------ - */ -int do_final_chrif(void) -{ - delete_session(char_fd); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int do_init_chrif(void) { - add_timer_func_list(check_connect_char_server, "check_connect_char_server"); - add_timer_func_list(send_users_tochar, "send_users_tochar"); - add_timer_interval(gettick() + 1000, check_connect_char_server, 0, 0, 10 * 1000); - add_timer_interval(gettick() + 1000, send_users_tochar, 0, 0, 5 * 1000); - - return 0; -} diff --git a/src/map/chrif.h b/src/map/chrif.h deleted file mode 100644 index f2b258ea9..000000000 --- a/src/map/chrif.h +++ /dev/null @@ -1,39 +0,0 @@ -// $Id: chrif.h,v 1.3 2004/09/25 11:39:17 MouseJstr Exp $ -#ifndef _CHRIF_H_ -#define _CHRIF_H_ - -void chrif_setuserid(char*); -void chrif_setpasswd(char*); -void chrif_setip(char*); -void chrif_setport(int); - -int chrif_isconnect(void); - -extern int chrif_connected; - -int chrif_authreq(struct map_session_data *); -int chrif_save(struct map_session_data*); -int chrif_charselectreq(struct map_session_data *); - -int chrif_changemapserver(struct map_session_data *sd,char *name,int x,int y,int ip,short port); - -int chrif_searchcharid(int char_id); -int chrif_changegm(int id,const char *pass,int len); -int chrif_changeemail(int id, const char *actual_email, const char *new_email); -int chrif_char_ask_name(int id, char * character_name, short operation_type, int year, int month, int day, int hour, int minute, int second); -int chrif_saveaccountreg2(struct map_session_data *sd); -int chrif_reloadGMdb(void); -int chrif_ragsrvinfo(int base_rate,int job_rate, int drop_rate); -int chrif_char_offline(struct map_session_data *sd); -int chrif_char_reset_offline(void); -int chrif_char_online(struct map_session_data *sd); -int chrif_changesex(int id, int sex); -int chrif_chardisconnect(struct map_session_data *sd); -int check_connect_char_server(int tid, unsigned int tick, int id, int data); - -int do_final_chrif(void); -int do_init_chrif(void); - -int chrif_flush_fifo(void); - -#endif diff --git a/src/map/clif.c b/src/map/clif.c deleted file mode 100644 index 70d7cdaa9..000000000 --- a/src/map/clif.c +++ /dev/null @@ -1,11474 +0,0 @@ -// $Id: clif.c 2200 2004-11-07 11:49:58Z Yor $ - -#define DUMP_UNKNOWN_PACKET 1 -#define DUMP_ALL_PACKETS 0 - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#ifdef __WIN32 -#define __USE_W32_SOCKETS -#include <windows.h> -#else -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif -#include <time.h> - -#include "../common/socket.h" -#include "../common/timer.h" -#include "../common/malloc.h" -#include "../common/version.h" -#include "../common/nullpo.h" -#include "../common/showmsg.h" - -#include "map.h" -#include "chrif.h" -#include "clif.h" -#include "pc.h" -#include "status.h" -#include "npc.h" -#include "itemdb.h" -#include "chat.h" -#include "trade.h" -#include "storage.h" -#include "script.h" -#include "skill.h" -#include "atcommand.h" -#include "charcommand.h" -#include "intif.h" -#include "battle.h" -#include "mob.h" -#include "party.h" -#include "guild.h" -#include "vending.h" -#include "pet.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define STATE_BLIND 0x10 - -struct Clif_Config clif_config; -struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB]; - -#define USE_PACKET_DB(sd) \ - clif_config.enable_packet_db && sd->packet_ver == clif_config.packet_db_ver - -#define IS_PACKET_DB_VER(cmd) \ - cmd == clif_config.connect_cmd - -static const int packet_len_table[MAX_PACKET_DB] = { - 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//#0x0040 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2, -#if PACKETVER < 2 - 3, 28, 19, 11, 3, -1, 9, 5, 52, 51, 56, 58, 41, 2, 6, 6, -#else // 78-7b 亀島以降 lv99エフェクト用 - 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6, -#endif -//#0x0080 - 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 2, -1, -1, -1, 0, // 0x8b changed to 2 (was 23) - 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6, - 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6, - 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3, -//#0x00C0 - 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 3, 2, 27, // 0xcd change to 3 (was 6) - 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1, - 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2, - 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10, - -//#0x0100 - 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1, - 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16, - 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1, - 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26, -//#0x0140 - 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6, - 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42, - -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182, - 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1, -//#0x0180 - 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6, -#if PACKETVER < 1 - 90, 86, 24, 6, 30,102, 8, 4, 8, 4, 14, 10, -1, 6, 2, 6, -#else // 196 comodo以降 状態表示アイコン用 - 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, -1, 6, 2, 6, -#endif - 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4, - 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3, -//#0x01C0, Set 0x1d5=-1 - 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 30, 6, 28, - 8, 14, 10, 35, 6, -1, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6, - 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1, - -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10, -//#0x200 - 26, -1, 26, 10, 18, 26, 11, 34, 14, 36, 10, 0, 0, -1, 24, 0, // 0x20c change to 0 (was 19) - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; - -// local define -enum { - ALL_CLIENT, - ALL_SAMEMAP, - AREA, - AREA_WOS, - AREA_WOC, - AREA_WOSC, - AREA_CHAT_WOC, - CHAT, - CHAT_WOS, - PARTY, - PARTY_WOS, - PARTY_SAMEMAP, - PARTY_SAMEMAP_WOS, - PARTY_AREA, - PARTY_AREA_WOS, - GUILD, - GUILD_WOS, - GUILD_SAMEMAP, // [Valaris] - GUILD_SAMEMAP_WOS, - GUILD_AREA, - GUILD_AREA_WOS, // end additions [Valaris] - SELF -}; - -#define WBUFPOS(p,pos,x,y) { unsigned char *__p = (p); __p+=(pos); __p[0] = (x)>>2; __p[1] = ((x)<<6) | (((y)>>4)&0x3f); __p[2] = (y)<<4; } -#define WBUFPOS2(p,pos,x0,y0,x1,y1) { unsigned char *__p = (p); __p+=(pos); __p[0] = (x0)>>2; __p[1] = ((x0)<<6) | (((y0)>>4)&0x3f); __p[2] = ((y0)<<4) | (((x1)>>6)&0x0f); __p[3]=((x1)<<2) | (((y1)>>8)&0x03); __p[4]=(y1); } - -#define WFIFOPOS(fd,pos,x,y) { WBUFPOS (WFIFOP(fd,pos),0,x,y); } -#define WFIFOPOS2(fd,pos,x0,y0,x1,y1) { WBUFPOS2(WFIFOP(fd,pos),0,x0,y0,x1,y1); } - -static char map_ip_str[16]; -static in_addr_t map_ip; -static in_addr_t bind_ip = INADDR_ANY; -static int map_port = 5121; -int map_fd; -char talkie_mes[80]; - -/*========================================== - * map鯖のip設定 - *------------------------------------------ - */ -void clif_setip(char *ip) -{ - memcpy(map_ip_str, ip, 16); - map_ip = inet_addr(map_ip_str); -} - -void clif_setbindip(char *ip) -{ - bind_ip = inet_addr(ip); -} - -/*========================================== - * map鯖のport設定 - *------------------------------------------ - */ -void clif_setport(int port) -{ - map_port = port; -} - -/*========================================== - * map鯖のip読み出し - *------------------------------------------ - */ -in_addr_t clif_getip(void) -{ - return map_ip; -} - -/*========================================== - * map鯖のport読み出し - *------------------------------------------ - */ -int clif_getport(void) -{ - return map_port; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_countusers(void) -{ - int users = 0, i; - struct map_session_data *sd; - - for(i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd && sd->state.auth && - !(battle_config.hide_GM_session && pc_isGM(sd))) - users++; - } - return users; -} - -/*========================================== - * 全てのclientに対してfunc()実行 - *------------------------------------------ - */ -int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...) -{ - int i; - va_list ap; - struct map_session_data *sd; - - va_start(ap,func); - for(i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd && sd->state.auth) - func(sd, ap); - } - va_end(ap); - return 0; -} - -/*========================================== - * clif_sendでAREA*指定時用 - *------------------------------------------ - */ -int clif_send_sub(struct block_list *bl, va_list ap) -{ - struct block_list *src_bl; - struct map_session_data *sd; - unsigned char *buf; - int len, type; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd = (struct map_session_data *)bl); - - buf = va_arg(ap,unsigned char*); - len = va_arg(ap,int); - nullpo_retr(0, src_bl = va_arg(ap,struct block_list*)); - type = va_arg(ap,int); - - switch(type) { - case AREA_WOS: - if (bl == src_bl) - return 0; - break; - case AREA_WOC: - if (sd->chatID || bl == src_bl) - return 0; - break; - case AREA_WOSC: - { - struct map_session_data *ssd = (struct map_session_data *)src_bl; - if (ssd && sd->chatID && sd->chatID == ssd->chatID) - return 0; - } - break; - } - - if (session[sd->fd] != NULL) { - if (WFIFOP(sd->fd,0) == buf) { - printf("WARNING: Invalid use of clif_send function\n"); - printf(" Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0)); - printf(" Please correct your code.\n"); - // don't send to not move the pointer of the packet for next sessions in the loop - } else { - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) { - int i; - struct map_session_data *sd = NULL; - struct party *p = NULL; - struct guild *g = NULL; - int x0 = 0, x1 = 0, y0 = 0, y1 = 0; - - if (type != ALL_CLIENT) { - nullpo_retr(0, bl); - } - if (bl && bl->type == BL_PC) { - nullpo_retr (0, sd=(struct map_session_data*)bl); - } - - switch(type) { - case ALL_CLIENT: // 全クライアントに送信 - for(i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth) { - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(i,0), buf, len); - WFIFOSET(i,len); - } - } - } - break; - case ALL_SAMEMAP: // 同じマップの全クライアントに送信 - for(i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == bl->m) { - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(i,0), buf, len); - WFIFOSET(i,len); - } - } - } - break; - case AREA: - case AREA_WOS: - case AREA_WOC: - case AREA_WOSC: - map_foreachinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE, BL_PC, buf, len, bl, type); - break; - case AREA_CHAT_WOC: - map_foreachinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5), bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC); - break; - case CHAT: - case CHAT_WOS: - { - struct chat_data *cd; - if (sd) { - cd = (struct chat_data*)map_id2bl(sd->chatID); - } else if (bl->type == BL_CHAT) { - cd = (struct chat_data*)bl; - } else if (bl->type != BL_CHAT) - break; - if (cd == NULL) - break; - for(i = 0; i < cd->users; i++) { - if (type == CHAT_WOS && cd->usersd[i] == sd) - continue; - if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - if (cd->usersd[i]->fd >=0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW] - memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len); - WFIFOSET(cd->usersd[i]->fd,len); - } - } - } - break; - - case PARTY_AREA: // 同じ画面内の全パーティーメンバに送信 - case PARTY_AREA_WOS: // 自分以外の同じ画面内の全パーティーメンバに送信 - x0 = bl->x - AREA_SIZE; - y0 = bl->y - AREA_SIZE; - x1 = bl->x + AREA_SIZE; - y1 = bl->y + AREA_SIZE; - case PARTY: // 全パーティーメンバに送信 - case PARTY_WOS: // 自分以外の全パーティーメンバに送信 - case PARTY_SAMEMAP: // 同じマップの全パーティーメンバに送信 - case PARTY_SAMEMAP_WOS: // 自分以外の同じマップの全パーティーメンバに送信 - if (sd) { - if (sd->partyspy > 0) { - p = party_search(sd->partyspy); - } else if (sd->status.party_id > 0) { - p = party_search(sd->status.party_id); - } - } - if (p) { - for(i=0;i<MAX_PARTY;i++){ - if ((sd = p->member[i].sd) != NULL) { - if ((session[sd->fd] == NULL) || (session[sd->fd]->session_data == NULL)) - continue; - if (sd->bl.id == bl->id && (type == PARTY_WOS || - type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS)) - continue; - if (type != PARTY && type != PARTY_WOS && bl->m != sd->bl.m) // マップチェック - continue; - if ((type == PARTY_AREA || type == PARTY_AREA_WOS) && - (sd->bl.x < x0 || sd->bl.y < y0 || - sd->bl.x > x1 || sd->bl.y > y1)) - continue; - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } -// if(battle_config.etc_log) -// printf("send party %d %d %d\n",p->party_id,i,flag) - - } - } - for (i = 0; i < fd_max; i++){ - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth) { - if (sd->partyspy == p->party_id) { - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } - } - } - } - } - break; - case SELF: - if (sd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } - break; - -/* New definitions for guilds [Valaris] */ - - case GUILD_AREA: - case GUILD_AREA_WOS: - x0 = bl->x - AREA_SIZE; - y0 = bl->y - AREA_SIZE; - x1 = bl->x + AREA_SIZE; - y1 = bl->y + AREA_SIZE; - case GUILD: - case GUILD_WOS: - if (sd) { // guildspy [Syrus22] - if (sd->guildspy > 0) { - g = guild_search(sd->guildspy); - } else if (sd->status.guild_id > 0) { - g = guild_search(sd->status.guild_id); - } - } - if (g) { - for(i = 0; i < g->max_member; i++) { - if ((sd = g->member[i].sd) != NULL) { - if (type == GUILD_WOS && sd->bl.id == bl->id) - continue; - if (sd->packet_ver > MAX_PACKET_VER) - continue; - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } - } - } - for (i = 0; i < fd_max; i++){ - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth) { - if (sd->guildspy == g->guild_id) { - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } - } - } - } - } - break; - case GUILD_SAMEMAP: - case GUILD_SAMEMAP_WOS: - if (sd && sd->status.guild_id > 0) { - g = guild_search(sd->status.guild_id); - } - if (g) { - for(i = 0; i < g->max_member; i++) { - if ((sd = g->member[i].sd) != NULL) { - if (sd->bl.id == bl->id && (type == GUILD_WOS || - type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS)) - continue; - if (type != GUILD && type != GUILD_WOS && bl->m != sd->bl.m) // マップチェック - continue; - if ((type == GUILD_AREA || type == GUILD_AREA_WOS) && - (sd->bl.x < x0 || sd->bl.y < y0 || - sd->bl.x > x1 || sd->bl.y > y1)) - continue; - if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); - } - } - } - } - break; -/* End [Valaris] */ - - default: - if (battle_config.error_log) - printf("clif_send まだ作ってないよー\n"); - return -1; - } - - return 0; -} - -// -// パケット作って送信 -// -/*========================================== - * - *------------------------------------------ - */ -int clif_authok(struct map_session_data *sd) { - int fd; - - nullpo_retr(0, sd); - - if (!sd) - return 0; - - if (!sd->fd) - return 0; - - fd = sd->fd; - - WFIFOW(fd, 0) = 0x73; - WFIFOL(fd, 2) = gettick(); - WFIFOPOS(fd, 6, sd->bl.x, sd->bl.y); - WFIFOB(fd, 9) = 5; - WFIFOB(fd,10) = 5; - WFIFOSET(fd,packet_len_table[0x73]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_authfail_fd(int fd, int type) { - if (!fd || !session[fd]) - return 0; - - WFIFOW(fd,0) = 0x81; - WFIFOL(fd,2) = type; - WFIFOSET(fd,packet_len_table[0x81]); - - clif_setwaitclose(fd); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_charselectok(int id) { - struct map_session_data *sd; - int fd; - - if ((sd = map_id2sd(id)) == NULL) - return 1; - - if (!sd->fd) - return 1; - - fd = sd->fd; - WFIFOW(fd,0) = 0xb3; - WFIFOB(fd,2) = 1; - WFIFOSET(fd,packet_len_table[0xb3]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_set009e(struct flooritem_data *fitem,unsigned char *buf) { - int view; - - nullpo_retr(0, fitem); - - //009e <ID>.l <name ID>.w <identify flag>.B <X>.w <Y>.w <subX>.B <subY>.B <amount>.w - WBUFW(buf, 0) = 0x9e; - WBUFL(buf, 2) = fitem->bl.id; - if ((view = itemdb_viewid(fitem->item_data.nameid)) > 0) - WBUFW(buf, 6) = view; - else - WBUFW(buf, 6) = fitem->item_data.nameid; - WBUFB(buf, 8) = fitem->item_data.identify; - WBUFW(buf, 9) = fitem->bl.x; - WBUFW(buf,11) = fitem->bl.y; - WBUFB(buf,13) = fitem->subx; - WBUFB(buf,14) = fitem->suby; - WBUFW(buf,15) = fitem->item_data.amount; - - return packet_len_table[0x9e]; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_dropflooritem(struct flooritem_data *fitem) { - unsigned char buf[64]; - - nullpo_retr(0, fitem); - - if (fitem->item_data.nameid <= 0) - return 0; - clif_set009e(fitem, buf); - clif_send(buf, packet_len_table[0x9e], &fitem->bl, AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_clearflooritem(struct flooritem_data *fitem, int fd) { - unsigned char buf[16]; - - nullpo_retr(0, fitem); - - WBUFW(buf,0) = 0xa1; - WBUFL(buf,2) = fitem->bl.id; - - if (fd == 0) { - clif_send(buf, packet_len_table[0xa1], &fitem->bl, AREA); - } else { - memcpy(WFIFOP(fd,0), buf, 6); - WFIFOSET(fd,packet_len_table[0xa1]); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_clearchar(struct block_list *bl, int type) { - unsigned char buf[16]; - - nullpo_retr(0, bl); - - WBUFW(buf,0) = 0x80; - WBUFL(buf,2) = bl->id; - if (type == 9) { - WBUFB(buf,6) = 0; - clif_send(buf, packet_len_table[0x80], bl, AREA); - } else { - WBUFB(buf,6) = type; - clif_send(buf, packet_len_table[0x80], bl, type == 1 ? AREA : AREA_WOS); - } - - return 0; -} - -static int clif_clearchar_delay_sub(int tid, unsigned int tick, int id, int data) { - struct block_list *bl = (struct block_list *)id; - - clif_clearchar(bl,data); - map_freeblock(bl); - - return 0; -} - -int clif_clearchar_delay(unsigned int tick, struct block_list *bl, int type) { - struct block_list *tmpbl; - - tmpbl = (struct block_list*)aCalloc(1, sizeof(struct block_list)); - - memcpy(tmpbl, bl, sizeof(struct block_list)); - add_timer(tick, clif_clearchar_delay_sub, (int)tmpbl, type); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_clearchar_id(int id, int type, int fd) { - unsigned char buf[16]; - - WBUFW(buf,0) = 0x80; - WBUFL(buf,2) = id; - WBUFB(buf,6) = type; - memcpy(WFIFOP(fd,0), buf, 7); - WFIFOSET(fd, packet_len_table[0x80]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_set0078(struct map_session_data *sd, unsigned char *buf) { - int level; - - nullpo_retr(0, sd); - - if (sd->disguise > 23 && sd->disguise < 4001) { // mob disguises [Valaris] - - WBUFW(buf,0) = 0x78; - WBUFL(buf,2) = sd->bl.id; - WBUFW(buf,6) = status_get_speed(&sd->bl); - WBUFW(buf,8) = sd->opt1; - WBUFW(buf,10) = sd->opt2; - WBUFW(buf,12) = sd->status.option; - WBUFW(buf,14) = sd->disguise; - WBUFW(buf,42) = 0; - WBUFB(buf,44) = 0; - WBUFPOS(buf, 46, sd->bl.x, sd->bl.y); - WBUFB(buf,48) |= sd->dir & 0x0f; - WBUFB(buf,49) = 5; - WBUFB(buf,50) = 5; - WBUFB(buf,51) = 0; - WBUFW(buf,52) = ((level = status_get_lv(&sd->bl)) > battle_config.max_lv) ? battle_config.max_lv : level; - - return packet_len_table[0x78]; - } - -#if PACKETVER < 4 - WBUFW(buf,0)= 0x78; - WBUFL(buf,2)= sd->bl.id; - WBUFW(buf,6)= sd->speed; - WBUFW(buf,8)= sd->opt1; - WBUFW(buf,10)= sd->opt2; - WBUFW(buf,12)= sd->status.option; - WBUFW(buf,14)= sd->view_class; - WBUFW(buf,16)= sd->status.hair; - if (sd->view_class != 22) - WBUFW(buf,18) = sd->status.weapon; - else - WBUFW(buf,18)=0; - WBUFW(buf,20)=sd->status.head_bottom; - WBUFW(buf,22)=sd->status.shield; - WBUFW(buf,24)=sd->status.head_top; - WBUFW(buf,26)=sd->status.head_mid; - WBUFW(buf,28)=sd->status.hair_color; - WBUFW(buf,30)=sd->status.clothes_color; - WBUFW(buf,32)=sd->head_dir; - WBUFL(buf,34)=sd->status.guild_id; - WBUFL(buf,38)=sd->guild_emblem_id; - WBUFW(buf,42)=sd->status.manner; - WBUFB(buf,44)=sd->status.karma; - WBUFB(buf,45)=sd->sex; - WBUFPOS(buf,46,sd->bl.x,sd->bl.y); - WBUFB(buf,48)|=sd->dir&0x0f; - WBUFB(buf,49)=5; - WBUFB(buf,50)=5; - WBUFB(buf,51)=sd->state.dead_sit; - WBUFW(buf,52)=(sd->status.base_level>battle_config.max_lv)?battle_config.max_lv:sd->status.base_level; - - return packet_len_table[0x78]; -#else - WBUFW(buf,0) = 0x1d8; - WBUFL(buf,2) = sd->bl.id; - WBUFW(buf,6) = sd->speed; - WBUFW(buf,8) = sd->opt1; - WBUFW(buf,10) = sd->opt2; - WBUFW(buf,12) = sd->status.option; - WBUFW(buf,14) = sd->view_class; - WBUFW(buf,16) = sd->status.hair; - if (sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]] && sd->view_class != 22) { - if (sd->inventory_data[sd->equip_index[9]]->view_id > 0) - WBUFW(buf,18) = sd->inventory_data[sd->equip_index[9]]->view_id; - else - WBUFW(buf,18) = sd->status.inventory[sd->equip_index[9]].nameid; - } else - WBUFW(buf,18) = 0; - if (sd->equip_index[8] >= 0 && sd->equip_index[8] != sd->equip_index[9] && sd->inventory_data[sd->equip_index[8]] && sd->view_class != 22) { - if (sd->inventory_data[sd->equip_index[8]]->view_id > 0) - WBUFW(buf,20) = sd->inventory_data[sd->equip_index[8]]->view_id; - else - WBUFW(buf,20) = sd->status.inventory[sd->equip_index[8]].nameid; - } else - WBUFW(buf,20) = 0; - WBUFW(buf,22) = sd->status.head_bottom; - WBUFW(buf,24) = sd->status.head_top; - WBUFW(buf,26) = sd->status.head_mid; - WBUFW(buf,28) = sd->status.hair_color; - WBUFW(buf,30) = sd->status.clothes_color; - WBUFW(buf,32) = sd->head_dir; - WBUFL(buf,34) = sd->status.guild_id; - WBUFW(buf,38) = sd->guild_emblem_id; - WBUFW(buf,40) = sd->status.manner; - WBUFW(buf,42)=sd->opt3; - WBUFB(buf,44) = sd->status.karma; - WBUFB(buf,45) = sd->sex; - WBUFPOS(buf, 46, sd->bl.x, sd->bl.y); - WBUFB(buf,48) |= sd->dir & 0x0f; - WBUFB(buf,49) = 5; - WBUFB(buf,50) = 5; - WBUFB(buf,51) = sd->state.dead_sit; - WBUFW(buf,52) = ((level = status_get_lv(&sd->bl)) > battle_config.max_lv) ? battle_config.max_lv : level; - - return packet_len_table[0x1d8]; -#endif -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_set007b(struct map_session_data *sd,unsigned char *buf) { - int level; - - nullpo_retr(0, sd); - - if (sd->disguise > 23 && sd->disguise < 4001) { // mob disguises [Valaris] - - WBUFW(buf,0)=0x7b; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=status_get_speed(&sd->bl); - WBUFW(buf,8)=sd->opt1; - WBUFW(buf,10)=sd->opt2; - WBUFW(buf,12)=sd->status.option; - WBUFW(buf,14)=sd->disguise; - WBUFL(buf,22)=gettick(); - WBUFW(buf,46)=0; - WBUFB(buf,48)=0; - WBUFPOS2(buf,50,sd->bl.x,sd->bl.y,sd->to_x,sd->to_y); - WBUFB(buf,55)=0; - WBUFB(buf,56)=5; - WBUFB(buf,57)=5; - WBUFW(buf,58)=((level = status_get_lv(&sd->bl))>battle_config.max_lv)? battle_config.max_lv:level; - - return packet_len_table[0x7b]; - } - -#if PACKETVER < 4 - WBUFW(buf,0)=0x7b; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=sd->speed; - WBUFW(buf,8)=sd->opt1; - WBUFW(buf,10)=sd->opt2; - WBUFW(buf,12)=sd->status.option; - WBUFW(buf,14)=sd->view_class; - WBUFW(buf,16)=sd->status.hair; - if(sd->view_class != 22) - WBUFW(buf,18)=sd->status.weapon; - else - WBUFW(buf,18)=0; - WBUFW(buf,20)=sd->status.head_bottom; - WBUFL(buf,22)=gettick(); - WBUFW(buf,26)=sd->status.shield; - WBUFW(buf,28)=sd->status.head_top; - WBUFW(buf,30)=sd->status.head_mid; - WBUFW(buf,32)=sd->status.hair_color; - WBUFW(buf,34)=sd->status.clothes_color; - WBUFW(buf,36)=sd->head_dir; - WBUFL(buf,38)=sd->status.guild_id; - WBUFL(buf,42)=sd->guild_emblem_id; - WBUFW(buf,46)=sd->status.manner; - WBUFB(buf,48)=sd->status.karma; - WBUFB(buf,49)=sd->sex; - WBUFPOS2(buf,50,sd->bl.x,sd->bl.y,sd->to_x,sd->to_y); - WBUFB(buf,55)=0; - WBUFB(buf,56)=5; - WBUFB(buf,57)=5; - WBUFW(buf,58)=(sd->status.base_level>battle_config.max_lv)?battle_config.max_lv:sd->status.base_level; - - return packet_len_table[0x7b]; -#else - WBUFW(buf,0)=0x1da; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=sd->speed; - WBUFW(buf,8)=sd->opt1; - WBUFW(buf,10)=sd->opt2; - WBUFW(buf,12)=sd->status.option; - WBUFW(buf,14)=sd->view_class; - WBUFW(buf,16)=sd->status.hair; - if(sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]] && sd->view_class != 22) { - if(sd->inventory_data[sd->equip_index[9]]->view_id > 0) - WBUFW(buf,18)=sd->inventory_data[sd->equip_index[9]]->view_id; - else - WBUFW(buf,18)=sd->status.inventory[sd->equip_index[9]].nameid; - } - else - WBUFW(buf,18)=0; - if(sd->equip_index[8] >= 0 && sd->equip_index[8] != sd->equip_index[9] && sd->inventory_data[sd->equip_index[8]] && sd->view_class != 22) { - if(sd->inventory_data[sd->equip_index[8]]->view_id > 0) - WBUFW(buf,20)=sd->inventory_data[sd->equip_index[8]]->view_id; - else - WBUFW(buf,20)=sd->status.inventory[sd->equip_index[8]].nameid; - } - else - WBUFW(buf,20)=0; - WBUFW(buf,22)=sd->status.head_bottom; - WBUFL(buf,24)=gettick(); - WBUFW(buf,28)=sd->status.head_top; - WBUFW(buf,30)=sd->status.head_mid; - WBUFW(buf,32)=sd->status.hair_color; - WBUFW(buf,34)=sd->status.clothes_color; - WBUFW(buf,36)=sd->head_dir; - WBUFL(buf,38)=sd->status.guild_id; - WBUFW(buf,42)=sd->guild_emblem_id; - WBUFW(buf,44)=sd->status.manner; - WBUFW(buf,46)=sd->opt3; - WBUFB(buf,48)=sd->status.karma; - WBUFB(buf,49)=sd->sex; - WBUFPOS2(buf,50,sd->bl.x,sd->bl.y,sd->to_x,sd->to_y); - WBUFB(buf,55)=0; - WBUFB(buf,56)=5; - WBUFB(buf,57)=5; - WBUFW(buf,58)=(sd->status.base_level>battle_config.max_lv)?battle_config.max_lv:sd->status.base_level; - - return packet_len_table[0x1da]; -#endif -} - -/*========================================== - * クラスチェンジ typeはMobの場合は1で他は0? - *------------------------------------------ - */ -int clif_class_change(struct block_list *bl,int class_,int type) -{ - unsigned char buf[16]; - - nullpo_retr(0, bl); - - if(class_ >= MAX_PC_CLASS) { - WBUFW(buf,0)=0x1b0; - WBUFL(buf,2)=bl->id; - WBUFB(buf,6)=type; - WBUFL(buf,7)=class_; - - clif_send(buf,packet_len_table[0x1b0],bl,AREA); - } - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int clif_mob_class_change(struct mob_data *md, int class_) { - unsigned char buf[16]; - int view = mob_get_viewclass(class_); - - nullpo_retr(0, md); - - if(view >= MAX_PC_CLASS) { - WBUFW(buf,0)=0x1b0; - WBUFL(buf,2)=md->bl.id; - WBUFB(buf,6)=1; - WBUFL(buf,7)=view; - - clif_send(buf,packet_len_table[0x1b0],&md->bl,AREA); - } - return 0; -} -// mob equipment [Valaris] - -int clif_mob_equip(struct mob_data *md, int nameid) { - unsigned char buf[16]; - - nullpo_retr(0, md); - - memset(buf,0,packet_len_table[0x1a4]); - - WBUFW(buf,0)=0x1a4; - WBUFB(buf,2)=3; - WBUFL(buf,3)=md->bl.id; - WBUFL(buf,7)=nameid; - - clif_send(buf,packet_len_table[0x1a4],&md->bl,AREA); - - return 0; -} - -/*========================================== - * MOB表示1 - *------------------------------------------ - */ -static int clif_mob0078(struct mob_data *md, unsigned char *buf) -{ - int level, i; - - memset(buf,0,packet_len_table[0x78]); - - nullpo_retr(0, md); - - WBUFW(buf,0)=0x78; - WBUFL(buf,2)=md->bl.id; - WBUFW(buf,6)=status_get_speed(&md->bl); - WBUFW(buf,8)=md->opt1; - WBUFW(buf,10)=md->opt2; - WBUFW(buf,12)=md->option; - WBUFW(buf,14)=mob_get_viewclass(md->class_); - if((i=mob_get_viewclass(md->class_)) <= 23 || i == 812 || i >= 4001) { - WBUFW(buf,12)|=mob_db[md->class_].option; - WBUFW(buf,16)=mob_get_hair(md->class_); - WBUFW(buf,18)=mob_get_weapon(md->class_); - WBUFW(buf,20)=mob_get_head_buttom(md->class_); - WBUFW(buf,22)=mob_get_shield(md->class_); - WBUFW(buf,24)=mob_get_head_top(md->class_); - WBUFW(buf,26)=mob_get_head_mid(md->class_); - WBUFW(buf,28)=mob_get_hair_color(md->class_); - WBUFW(buf,30)=mob_get_clothes_color(md->class_); //Add for player monster dye - Valaris - WBUFB(buf,45)=mob_get_sex(md->class_); - } - - if (md->class_ >= 1285 && md->class_ <= 1287 && md->guild_id) { // Added guardian emblems [Valaris] - struct guild *g; - struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name); - if (gc && gc->guild_id > 0) { - g=guild_search(gc->guild_id); - if (g) { - WBUFL(buf,22)=g->emblem_id; - WBUFL(buf,26)=gc->guild_id; - } - } - } // End addition - - WBUFPOS(buf,46,md->bl.x,md->bl.y); - WBUFB(buf,48)|=md->dir&0x0f; - WBUFB(buf,49)=5; - WBUFB(buf,50)=5; - WBUFW(buf,52)=((level = status_get_lv(&md->bl))>battle_config.max_lv)? battle_config.max_lv:level; - - return packet_len_table[0x78]; -} - -/*========================================== - * MOB表示2 - *------------------------------------------ - */ -static int clif_mob007b(struct mob_data *md, unsigned char *buf) { - int level; - - memset(buf,0,packet_len_table[0x7b]); - - nullpo_retr(0, md); - - WBUFW(buf,0)=0x7b; - WBUFL(buf,2)=md->bl.id; - WBUFW(buf,6)=status_get_speed(&md->bl); - WBUFW(buf,8)=md->opt1; - WBUFW(buf,10)=md->opt2; - WBUFW(buf,12)=md->option; - WBUFW(buf,14)=mob_get_viewclass(md->class_); - if ((mob_get_viewclass(md->class_) < 24) || (mob_get_viewclass(md->class_) > 4000)) { - WBUFW(buf,12)|=mob_db[md->class_].option; - WBUFW(buf,16)=mob_get_hair(md->class_); - WBUFW(buf,18)=mob_get_weapon(md->class_); - WBUFW(buf,20)=mob_get_head_buttom(md->class_); - WBUFL(buf,22)=gettick(); - WBUFW(buf,26)=mob_get_shield(md->class_); - WBUFW(buf,28)=mob_get_head_top(md->class_); - WBUFW(buf,30)=mob_get_head_mid(md->class_); - WBUFW(buf,32)=mob_get_hair_color(md->class_); - WBUFW(buf,34)=mob_get_clothes_color(md->class_); //Add for player monster dye - Valaris - WBUFB(buf,49)=mob_get_sex(md->class_); - } else - WBUFL(buf,22)=gettick(); - - if(md->class_ >= 1285 && md->class_ <= 1287 && md->guild_id) { // Added guardian emblems [Valaris] - struct guild *g; - struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name); - if(gc && gc->guild_id > 0){ - g=guild_search(gc->guild_id); - if(g) { - WBUFL(buf,28)=gc->guild_id; - WBUFL(buf,24)=g->emblem_id; - } - } - } // End addition - - WBUFPOS2(buf,50,md->bl.x,md->bl.y,md->to_x,md->to_y); - WBUFB(buf,56)=5; - WBUFB(buf,57)=5; - WBUFW(buf,58)=((level = status_get_lv(&md->bl))>battle_config.max_lv)? battle_config.max_lv:level; - - return packet_len_table[0x7b]; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_npc0078(struct npc_data *nd, unsigned char *buf) { - struct guild *g; - - nullpo_retr(0, nd); - - memset(buf,0,packet_len_table[0x78]); - - WBUFW(buf,0)=0x78; - WBUFL(buf,2)=nd->bl.id; - WBUFW(buf,6)=nd->speed; - WBUFW(buf,14)=nd->class_; - if ((nd->class_ == 722) && (nd->u.scr.guild_id > 0) && ((g=guild_search(nd->u.scr.guild_id)) != NULL)) { - WBUFL(buf,22)=g->emblem_id; - WBUFL(buf,26)=g->guild_id; - } - WBUFPOS(buf,46,nd->bl.x,nd->bl.y); - WBUFB(buf,48)|=nd->dir&0x0f; - WBUFB(buf,49)=5; - WBUFB(buf,50)=5; - - return packet_len_table[0x78]; -} - -// NPC Walking [Valaris] -static int clif_npc007b(struct npc_data *nd, unsigned char *buf) { - struct guild *g; - - nullpo_retr(0, nd); - - memset(buf,0,packet_len_table[0x7b]); - - WBUFW(buf,0)=0x7b; - WBUFL(buf,2)=nd->bl.id; - WBUFW(buf,6)=nd->speed; - WBUFW(buf,14)=nd->class_; - if ((nd->class_ == 722) && (nd->u.scr.guild_id > 0) && ((g=guild_search(nd->u.scr.guild_id)) != NULL)) { - WBUFL(buf,22)=g->emblem_id; - WBUFL(buf,26)=g->guild_id; - } - - WBUFL(buf,22)=gettick(); - WBUFPOS2(buf,50,nd->bl.x,nd->bl.y,nd->to_x,nd->to_y); - WBUFB(buf,56)=5; - WBUFB(buf,57)=5; - - return packet_len_table[0x7b]; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_pet0078(struct pet_data *pd, unsigned char *buf) { - int view,level; - - nullpo_retr(0, pd); - - memset(buf,0,packet_len_table[0x78]); - - WBUFW(buf,0)=0x78; - WBUFL(buf,2)=pd->bl.id; - WBUFW(buf,6)=pd->speed; - WBUFW(buf,14)=mob_get_viewclass(pd->class_); - if((mob_get_viewclass(pd->class_) < 24) || (mob_get_viewclass(pd->class_) > 4000)) { - WBUFW(buf,12)=mob_db[pd->class_].option; - WBUFW(buf,16)=mob_get_hair(pd->class_); - WBUFW(buf,18)=mob_get_weapon(pd->class_); - WBUFW(buf,20)=mob_get_head_buttom(pd->class_); - WBUFW(buf,22)=mob_get_shield(pd->class_); - WBUFW(buf,24)=mob_get_head_top(pd->class_); - WBUFW(buf,26)=mob_get_head_mid(pd->class_); - WBUFW(buf,28)=mob_get_hair_color(pd->class_); - WBUFW(buf,30)=mob_get_clothes_color(pd->class_); //Add for player pet dye - Valaris - WBUFB(buf,45)=mob_get_sex(pd->class_); - } else { - WBUFW(buf,16)=0x14; - if((view = itemdb_viewid(pd->equip)) > 0) - WBUFW(buf,20)=view; - else - WBUFW(buf,20)=pd->equip; - } - WBUFPOS(buf,46,pd->bl.x,pd->bl.y); - WBUFB(buf,48)|=pd->dir&0x0f; - WBUFB(buf,49)=0; - WBUFB(buf,50)=0; - WBUFW(buf,52)=((level = status_get_lv(&pd->bl))>battle_config.max_lv)? battle_config.max_lv:level; - - return packet_len_table[0x78]; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_pet007b(struct pet_data *pd, unsigned char *buf) { - int view,level; - - nullpo_retr(0, pd); - - memset(buf,0,packet_len_table[0x7b]); - - WBUFW(buf,0)=0x7b; - WBUFL(buf,2)=pd->bl.id; - WBUFW(buf,6)=pd->speed; - WBUFW(buf,14)=mob_get_viewclass(pd->class_); - if((mob_get_viewclass(pd->class_) < 24) || (mob_get_viewclass(pd->class_) > 4000)) { - WBUFW(buf,12)=mob_db[pd->class_].option; - WBUFW(buf,16)=mob_get_hair(pd->class_); - WBUFW(buf,18)=mob_get_weapon(pd->class_); - WBUFW(buf,20)=mob_get_head_buttom(pd->class_); - WBUFL(buf,22)=gettick(); - WBUFW(buf,26)=mob_get_shield(pd->class_); - WBUFW(buf,28)=mob_get_head_top(pd->class_); - WBUFW(buf,30)=mob_get_head_mid(pd->class_); - WBUFW(buf,32)=mob_get_hair_color(pd->class_); - WBUFW(buf,34)=mob_get_clothes_color(pd->class_); //Add for player pet dye - Valaris - WBUFB(buf,49)=mob_get_sex(pd->class_); - } else { - WBUFW(buf,16)=0x14; - if ((view = itemdb_viewid(pd->equip)) > 0) - WBUFW(buf,20)=view; - else - WBUFW(buf,20)=pd->equip; - WBUFL(buf,22)=gettick(); - } - WBUFPOS2(buf,50,pd->bl.x,pd->bl.y,pd->to_x,pd->to_y); - WBUFB(buf,56)=0; - WBUFB(buf,57)=0; - WBUFW(buf,58)=((level = status_get_lv(&pd->bl))>battle_config.max_lv)? battle_config.max_lv:level; - - return packet_len_table[0x7b]; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_set01e1(struct map_session_data *sd, unsigned char *buf) { - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x1e1; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=sd->spiritball; - - return packet_len_table[0x1e1]; -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_set0192(int fd, int m, int x, int y, int type) { - WFIFOW(fd,0) = 0x192; - WFIFOW(fd,2) = x; - WFIFOW(fd,4) = y; - WFIFOW(fd,6) = type; - memcpy(WFIFOP(fd,8),map[m].name,16); - WFIFOSET(fd,packet_len_table[0x192]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_spawnpc(struct map_session_data *sd) { - unsigned char buf[128]; - - nullpo_retr(0, sd); - - if (sd->disguise > 23 && sd->disguise < 4001) { // mob disguises [Valaris] - clif_clearchar(&sd->bl, 9); - - memset(buf, 0, packet_len_table[0x119]); - - WBUFW(buf, 0) = 0x119; - WBUFL(buf, 2) = sd->bl.id; - WBUFW(buf, 6) = 0; - WBUFW(buf, 8) = 0; - WBUFW(buf,10) = 0x40; - WBUFB(buf,12) = 0; - - clif_send(buf, packet_len_table[0x119], &sd->bl, SELF); - - memset(buf, 0, packet_len_table[0x7c]); - - WBUFW(buf, 0) = 0x7c; - WBUFL(buf, 2) = sd->bl.id; - WBUFW(buf, 6) = sd->speed; - WBUFW(buf, 8) = sd->opt1; - WBUFW(buf,10) = sd->opt2; - WBUFW(buf,12) = sd->status.option; - WBUFW(buf,20) = sd->disguise; - WBUFPOS(buf, 36, sd->bl.x, sd->bl.y); - clif_send(buf, packet_len_table[0x7c], &sd->bl, AREA); - } - - clif_set0078(sd, buf); - -#if PACKETVER < 4 - WBUFW(buf, 0) = 0x79; - WBUFW(buf,51) = (sd->status.base_level > battle_config.max_lv) ? battle_config.max_lv : sd->status.base_level; - clif_send(buf, packet_len_table[0x79], &sd->bl, AREA_WOS); -#else - WBUFW(buf, 0) = 0x1d9; - WBUFW(buf,51) = (sd->status.base_level > battle_config.max_lv) ? battle_config.max_lv : sd->status.base_level; - clif_send(buf, packet_len_table[0x1d9], &sd->bl, AREA_WOS); -#endif - - - if (sd->spiritball > 0) - clif_spiritball(sd); - - if (sd->status.guild_id > 0) { // force display of guild emblem [Valaris] - struct guild *g = guild_search(sd->status.guild_id); - if (g) - clif_guild_emblem(sd,g); - } // end addition [Valaris] - - if (sd->status.class_==13 || sd->status.class_==21 || sd->status.class_==4014 || sd->status.class_==4022) - pc_setoption(sd,sd->status.option|0x0020); // [Valaris] - - if ((pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0) && (sd->status.class_==7 || - sd->status.class_==14 || sd->status.class_==4008 || sd->status.class_==4015)) - pc_setriding(sd); // update peco riders for people upgrading athena [Valaris] - - - if (map[sd->bl.m].flag.snow) - clif_specialeffect(&sd->bl, 162, 1); - if (map[sd->bl.m].flag.fog) - clif_specialeffect(&sd->bl, 233, 1); - if (map[sd->bl.m].flag.sakura) - clif_specialeffect(&sd->bl, 163, 1); - if (map[sd->bl.m].flag.leaves) - clif_specialeffect(&sd->bl, 333, 1); - if (map[sd->bl.m].flag.rain) - clif_specialeffect(&sd->bl, 161, 1); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_spawnnpc(struct npc_data *nd) -{ - unsigned char buf[64]; - int len; - - nullpo_retr(0, nd); - - if(nd->class_ < 0 || nd->flag&1 || nd->class_ == INVISIBLE_CLASS) - return 0; - - memset(buf,0,packet_len_table[0x7c]); - - WBUFW(buf,0)=0x7c; - WBUFL(buf,2)=nd->bl.id; - WBUFW(buf,6)=nd->speed; - WBUFW(buf,20)=nd->class_; - WBUFPOS(buf,36,nd->bl.x,nd->bl.y); - - clif_send(buf,packet_len_table[0x7c],&nd->bl,AREA); - - len = clif_npc0078(nd,buf); - clif_send(buf,len,&nd->bl,AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_spawnmob(struct mob_data *md) -{ - unsigned char buf[64]; - int len; - - nullpo_retr(0, md); - - if (mob_get_viewclass(md->class_) > 23) { - memset(buf,0,packet_len_table[0x7c]); - - WBUFW(buf,0)=0x7c; - WBUFL(buf,2)=md->bl.id; - WBUFW(buf,6)=md->speed; - WBUFW(buf,8)=md->opt1; - WBUFW(buf,10)=md->opt2; - WBUFW(buf,12)=md->option; - WBUFW(buf,20)=mob_get_viewclass(md->class_); - WBUFPOS(buf,36,md->bl.x,md->bl.y); - clif_send(buf,packet_len_table[0x7c],&md->bl,AREA); - } - - len = clif_mob0078(md,buf); - clif_send(buf,len,&md->bl,AREA); - - if (mob_get_equip(md->class_) > 0) // mob equipment [Valaris] - clif_mob_equip(md,mob_get_equip(md->class_)); - - if(md->size==2) // tiny/big mobs [Valaris] - clif_specialeffect(&md->bl,423,0); - else if(md->size==1) - clif_specialeffect(&md->bl,421,0); - - return 0; -} - -// pet - -/*========================================== - * - *------------------------------------------ - */ -int clif_spawnpet(struct pet_data *pd) -{ - unsigned char buf[64]; - int len; - - nullpo_retr(0, pd); - - if (mob_get_viewclass(pd->class_) >= MAX_PC_CLASS) { - memset(buf,0,packet_len_table[0x7c]); - - WBUFW(buf,0)=0x7c; - WBUFL(buf,2)=pd->bl.id; - WBUFW(buf,6)=pd->speed; - WBUFW(buf,20)=mob_get_viewclass(pd->class_); - WBUFPOS(buf,36,pd->bl.x,pd->bl.y); - - clif_send(buf,packet_len_table[0x7c],&pd->bl,AREA); - } - - len = clif_pet0078(pd,buf); - clif_send(buf,len,&pd->bl,AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_movepet(struct pet_data *pd) { - unsigned char buf[256]; - int len; - - nullpo_retr(0, pd); - - len = clif_pet007b(pd,buf); - clif_send(buf,len,&pd->bl,AREA); - - return 0; -} - -/*========================================== - * npc walking [Valaris] - *------------------------------------------ - */ -int clif_movenpc(struct npc_data *nd) { - unsigned char buf[256]; - int len; - - nullpo_retr(0, nd); - - len = clif_npc007b(nd,buf); - clif_send(buf,len,&nd->bl,AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_servertick(struct map_session_data *sd) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x7f; - WFIFOL(fd,2)=sd->server_tick; - WFIFOSET(fd,packet_len_table[0x7f]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_walkok(struct map_session_data *sd) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x87; - WFIFOL(fd,2)=gettick();; - WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->to_x,sd->to_y); - WFIFOB(fd,11)=0; - WFIFOSET(fd,packet_len_table[0x87]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_movechar(struct map_session_data *sd) { - int fd; - int len; - unsigned char buf[256]; - - nullpo_retr(0, sd); - - fd = sd->fd; - - len = clif_set007b(sd, buf); - - if (sd->disguise > 23 && sd->disguise < 4001) { - clif_send(buf, len, &sd->bl, AREA); - return 0; - } else - clif_send(buf, len, &sd->bl, AREA_WOS); - - if (battle_config.save_clothcolor == 1 && sd->status.clothes_color > 0) - clif_changelook(&sd->bl, LOOK_CLOTHES_COLOR, sd->status.clothes_color); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_quitsave(int fd,struct map_session_data *sd) -{ - map_quit(sd); -} - -/*========================================== - * - *------------------------------------------ - */ -static int clif_waitclose(int tid, unsigned int tick, int id, int data) { - if (session[id]) - session[id]->eof = 1; - - close(id); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_setwaitclose(int fd) { - struct map_session_data *sd; - - // if player is not already in the game (double connection probably) - if ((sd = (struct map_session_data*)session[fd]->session_data) == NULL) { - // limited timer, just to send information. - add_timer(gettick() + 1000, clif_waitclose, fd, 0); - } else - add_timer(gettick() + 5000, clif_waitclose, fd, 0); -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_changemap(struct map_session_data *sd, char *mapname, int x, int y) { - int fd; - - nullpo_retr(0, sd); - - fd = sd->fd; - - WFIFOW(fd,0) = 0x91; - memcpy(WFIFOP(fd,2), mapname, 16); - WFIFOW(fd,18) = x; - WFIFOW(fd,20) = y; - WFIFOSET(fd, packet_len_table[0x91]); - - if (sd->disguise > 23 && sd->disguise < 4001) // mob disguises [Valaris] - clif_spawnpc(sd); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_changemapserver(struct map_session_data *sd, char *mapname, int x, int y, int ip, int port) { - int fd; - - nullpo_retr(0, sd); - - fd = sd->fd; - WFIFOW(fd,0) = 0x92; - memcpy(WFIFOP(fd,2), mapname, 16); - WFIFOW(fd,18) = x; - WFIFOW(fd,20) = y; - WFIFOL(fd,22) = ip; - WFIFOW(fd,26) = port; - WFIFOSET(fd, packet_len_table[0x92]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_fixpos(struct block_list *bl) { - unsigned char buf[16]; - - nullpo_retr(0, bl); - - WBUFW(buf,0)=0x88; - WBUFL(buf,2)=bl->id; - WBUFW(buf,6)=bl->x; - WBUFW(buf,8)=bl->y; - - clif_send(buf, packet_len_table[0x88], bl, AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_npcbuysell(struct map_session_data* sd, int id) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xc4; - WFIFOL(fd,2)=id; - WFIFOSET(fd,packet_len_table[0xc4]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_buylist(struct map_session_data *sd, struct npc_data *nd) { - struct item_data *id; - int fd,i,val; - - nullpo_retr(0, sd); - nullpo_retr(0, nd); - - fd=sd->fd; - WFIFOW(fd,0)=0xc6; - for(i=0;nd->u.shop_item[i].nameid > 0;i++){ - id = itemdb_search(nd->u.shop_item[i].nameid); - val=nd->u.shop_item[i].value; - WFIFOL(fd,4+i*11)=val; - if (!id->flag.value_notdc) - val=pc_modifybuyvalue(sd,val); - WFIFOL(fd,8+i*11)=val; - WFIFOB(fd,12+i*11)=id->type; - if (id->view_id > 0) - WFIFOW(fd,13+i*11)=id->view_id; - else - WFIFOW(fd,13+i*11)=nd->u.shop_item[i].nameid; - } - WFIFOW(fd,2)=i*11+4; - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_selllist(struct map_session_data *sd) { - int fd,i,c=0,val; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xc7; - for(i=0;i<MAX_INVENTORY;i++) { - if(sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) { - val=sd->inventory_data[i]->value_sell; - if (val < 0) - continue; - WFIFOW(fd,4+c*10)=i+2; - WFIFOL(fd,6+c*10)=val; - if (!sd->inventory_data[i]->flag.value_notoc) - val=pc_modifysellvalue(sd,val); - WFIFOL(fd,10+c*10)=val; - c++; - } - } - WFIFOW(fd,2)=c*10+4; - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_scriptmes(struct map_session_data *sd, int npcid, char *mes) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xb4; - WFIFOW(fd,2)=strlen(mes)+9; - WFIFOL(fd,4)=npcid; - strcpy((char*)WFIFOP(fd,8),mes); - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_scriptnext(struct map_session_data *sd,int npcid) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xb5; - WFIFOL(fd,2)=npcid; - WFIFOSET(fd,packet_len_table[0xb5]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_scriptclose(struct map_session_data *sd, int npcid) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xb6; - WFIFOL(fd,2)=npcid; - WFIFOSET(fd,packet_len_table[0xb6]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_scriptmenu(struct map_session_data *sd, int npcid, char *mes) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xb7; - WFIFOW(fd,2)=strlen(mes)+8; - WFIFOL(fd,4)=npcid; - strcpy((char*)WFIFOP(fd,8),mes); - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_scriptinput(struct map_session_data *sd, int npcid) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x142; - WFIFOL(fd,2)=npcid; - WFIFOSET(fd,packet_len_table[0x142]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_scriptinputstr(struct map_session_data *sd, int npcid) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1d4; - WFIFOL(fd,2)=npcid; - WFIFOSET(fd,packet_len_table[0x1d4]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x144; - WFIFOL(fd,2)=npc_id; - WFIFOL(fd,6)=type; - WFIFOL(fd,10)=x; - WFIFOL(fd,14)=y; - WFIFOB(fd,18)=id; - WFIFOL(fd,19)=color; - WFIFOSET(fd,packet_len_table[0x144]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_cutin(struct map_session_data *sd, char *image, int type) { - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1b3; - strncpy((char*)WFIFOP(fd,2),image,64); - WFIFOB(fd,66)=type; - WFIFOSET(fd,packet_len_table[0x1b3]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_additem(struct map_session_data *sd, int n, int amount, int fail) { - int fd,j; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf=WFIFOP(fd,0); - if(fail) { - WBUFW(buf,0)=0xa0; - WBUFW(buf,2)=n+2; - WBUFW(buf,4)=amount; - WBUFW(buf,6)=0; - WBUFB(buf,8)=0; - WBUFB(buf,9)=0; - WBUFB(buf,10)=0; - WBUFW(buf,11)=0; - WBUFW(buf,13)=0; - WBUFW(buf,15)=0; - WBUFW(buf,17)=0; - WBUFW(buf,19)=0; - WBUFB(buf,21)=0; - WBUFB(buf,22)=fail; - } else { - if (n<0 || n>=MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL) - return 1; - - WBUFW(buf,0)=0xa0; - WBUFW(buf,2)=n+2; - WBUFW(buf,4)=amount; - if (sd->inventory_data[n]->view_id > 0) - WBUFW(buf,6)=sd->inventory_data[n]->view_id; - else - WBUFW(buf,6)=sd->status.inventory[n].nameid; - WBUFB(buf,8)=sd->status.inventory[n].identify; - WBUFB(buf,9)=sd->status.inventory[n].attribute; - WBUFB(buf,10)=sd->status.inventory[n].refine; - if(sd->status.inventory[n].card[0]==0x00ff || sd->status.inventory[n].card[0]==0x00fe || sd->status.inventory[n].card[0]==(short)0xff00) { - WBUFW(buf,11)=sd->status.inventory[n].card[0]; - WBUFW(buf,13)=sd->status.inventory[n].card[1]; - WBUFW(buf,15)=sd->status.inventory[n].card[2]; - WBUFW(buf,17)=sd->status.inventory[n].card[3]; - } else { - if (sd->status.inventory[n].card[0] > 0 && (j=itemdb_viewid(sd->status.inventory[n].card[0])) > 0) - WBUFW(buf,11)=j; - else - WBUFW(buf,11)=sd->status.inventory[n].card[0]; - if (sd->status.inventory[n].card[1] > 0 && (j=itemdb_viewid(sd->status.inventory[n].card[1])) > 0) - WBUFW(buf,13)=j; - else - WBUFW(buf,13)=sd->status.inventory[n].card[1]; - if (sd->status.inventory[n].card[2] > 0 && (j=itemdb_viewid(sd->status.inventory[n].card[2])) > 0) - WBUFW(buf,15)=j; - else - WBUFW(buf,15)=sd->status.inventory[n].card[2]; - if (sd->status.inventory[n].card[3] > 0 && (j=itemdb_viewid(sd->status.inventory[n].card[3])) > 0) - WBUFW(buf,17)=j; - else - WBUFW(buf,17)=sd->status.inventory[n].card[3]; - } - WBUFW(buf,19)=pc_equippoint(sd,n); - WBUFB(buf,21)=(sd->inventory_data[n]->type == 7)? 4:sd->inventory_data[n]->type; - WBUFB(buf,22)=fail; - } - - WFIFOSET(fd,packet_len_table[0xa0]); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_delitem(struct map_session_data *sd,int n,int amount) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xaf; - WFIFOW(fd,2)=n+2; - WFIFOW(fd,4)=amount; - - WFIFOSET(fd,packet_len_table[0xaf]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_itemlist(struct map_session_data *sd) -{ - int i,n,fd,arrow=-1; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf = WFIFOP(fd,0); -#if PACKETVER < 5 - WBUFW(buf,0)=0xa3; - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL || itemdb_isequip2(sd->inventory_data[i])) - continue; - WBUFW(buf,n*10+4)=i+2; - if (sd->inventory_data[i]->view_id > 0) - WBUFW(buf,n*10+6)=sd->inventory_data[i]->view_id; - else - WBUFW(buf,n*10+6)=sd->status.inventory[i].nameid; - WBUFB(buf,n*10+8)=sd->inventory_data[i]->type; - WBUFB(buf,n*10+9)=sd->status.inventory[i].identify; - WBUFW(buf,n*10+10)=sd->status.inventory[i].amount; - if (sd->inventory_data[i]->equip == 0x8000) { - WBUFW(buf,n*10+12)=0x8000; - if (sd->status.inventory[i].equip) - arrow=i; // ついでに矢装備チェック - } else - WBUFW(buf,n*10+12)=0; - n++; - } - if (n) { - WBUFW(buf,2)=4+n*10; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#else - WBUFW(buf,0)=0x1ee; - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL || itemdb_isequip2(sd->inventory_data[i])) - continue; - WBUFW(buf,n*18+4)=i+2; - if(sd->inventory_data[i]->view_id > 0) - WBUFW(buf,n*18+6)=sd->inventory_data[i]->view_id; - else - WBUFW(buf,n*18+6)=sd->status.inventory[i].nameid; - WBUFB(buf,n*18+8)=sd->inventory_data[i]->type; - WBUFB(buf,n*18+9)=sd->status.inventory[i].identify; - WBUFW(buf,n*18+10)=sd->status.inventory[i].amount; - if (sd->inventory_data[i]->equip == 0x8000) { - WBUFW(buf,n*18+12)=0x8000; - if(sd->status.inventory[i].equip) - arrow=i; // ついでに矢装備チェック - } else - WBUFW(buf,n*18+12)=0; - WBUFW(buf,n*18+14)=sd->status.inventory[i].card[0]; - WBUFW(buf,n*18+16)=sd->status.inventory[i].card[1]; - WBUFW(buf,n*18+18)=sd->status.inventory[i].card[2]; - WBUFW(buf,n*18+20)=sd->status.inventory[i].card[3]; - n++; - } - if (n) { - WBUFW(buf,2)=4+n*18; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#endif - if(arrow >= 0) - clif_arrowequip(sd,arrow); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_equiplist(struct map_session_data *sd) -{ - int i,j,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf = WFIFOP(fd,0); - WBUFW(buf,0)=0xa4; - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || !itemdb_isequip2(sd->inventory_data[i])) - continue; - WBUFW(buf,n*20+4)=i+2; - if(sd->inventory_data[i]->view_id > 0) - WBUFW(buf,n*20+6)=sd->inventory_data[i]->view_id; - else - WBUFW(buf,n*20+6)=sd->status.inventory[i].nameid; - WBUFB(buf,n*20+8)=(sd->inventory_data[i]->type == 7)? 4:sd->inventory_data[i]->type; - WBUFB(buf,n*20+9)=sd->status.inventory[i].identify; - WBUFW(buf,n*20+10)=pc_equippoint(sd,i); - WBUFW(buf,n*20+12)=sd->status.inventory[i].equip; - WBUFB(buf,n*20+14)=sd->status.inventory[i].attribute; - WBUFB(buf,n*20+15)=sd->status.inventory[i].refine; - if(sd->status.inventory[i].card[0]==0x00ff || sd->status.inventory[i].card[0]==0x00fe || sd->status.inventory[i].card[0]==(short)0xff00) { - WBUFW(buf,n*20+16)=sd->status.inventory[i].card[0]; - WBUFW(buf,n*20+18)=sd->status.inventory[i].card[1]; - WBUFW(buf,n*20+20)=sd->status.inventory[i].card[2]; - WBUFW(buf,n*20+22)=sd->status.inventory[i].card[3]; - } else { - if(sd->status.inventory[i].card[0] > 0 && (j=itemdb_viewid(sd->status.inventory[i].card[0])) > 0) - WBUFW(buf,n*20+16)=j; - else - WBUFW(buf,n*20+16)=sd->status.inventory[i].card[0]; - if(sd->status.inventory[i].card[1] > 0 && (j=itemdb_viewid(sd->status.inventory[i].card[1])) > 0) - WBUFW(buf,n*20+18)=j; - else - WBUFW(buf,n*20+18)=sd->status.inventory[i].card[1]; - if(sd->status.inventory[i].card[2] > 0 && (j=itemdb_viewid(sd->status.inventory[i].card[2])) > 0) - WBUFW(buf,n*20+20)=j; - else - WBUFW(buf,n*20+20)=sd->status.inventory[i].card[2]; - if(sd->status.inventory[i].card[3] > 0 && (j=itemdb_viewid(sd->status.inventory[i].card[3])) > 0) - WBUFW(buf,n*20+22)=j; - else - WBUFW(buf,n*20+22)=sd->status.inventory[i].card[3]; - } - n++; - } - if(n){ - WBUFW(buf,2)=4+n*20; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * カプラさんに預けてある消耗品&収集品リスト - *------------------------------------------ - */ -int clif_storageitemlist(struct map_session_data *sd,struct storage *stor) -{ - struct item_data *id; - int i,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - buf = WFIFOP(fd,0); -#if PACKETVER < 5 - WBUFW(buf,0)=0xa5; - for(i=0,n=0;i<MAX_STORAGE;i++){ - if(stor->storage_[i].nameid<=0) - continue; - nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid)); - if(itemdb_isequip2(id)) - continue; - - WBUFW(buf,n*10+4)=i+1; - if(id->view_id > 0) - WBUFW(buf,n*10+6)=id->view_id; - else - WBUFW(buf,n*10+6)=stor->storage_[i].nameid; - WBUFB(buf,n*10+8)=id->type;; - WBUFB(buf,n*10+9)=stor->storage_[i].identify; - WBUFW(buf,n*10+10)=stor->storage_[i].amount; - WBUFW(buf,n*10+12)=0; - n++; - } - if(n){ - WBUFW(buf,2)=4+n*10; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#else - WBUFW(buf,0)=0x1f0; - for(i=0,n=0;i<MAX_STORAGE;i++){ - if(stor->storage_[i].nameid<=0) - continue; - nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid)); - if(itemdb_isequip2(id)) - continue; - - WBUFW(buf,n*18+4)=i+1; - if(id->view_id > 0) - WBUFW(buf,n*18+6)=id->view_id; - else - WBUFW(buf,n*18+6)=stor->storage_[i].nameid; - WBUFB(buf,n*18+8)=id->type;; - WBUFB(buf,n*18+9)=stor->storage_[i].identify; - WBUFW(buf,n*18+10)=stor->storage_[i].amount; - WBUFW(buf,n*18+12)=0; - WBUFW(buf,n*18+14)=stor->storage_[i].card[0]; - WBUFW(buf,n*18+16)=stor->storage_[i].card[1]; - WBUFW(buf,n*18+18)=stor->storage_[i].card[2]; - WBUFW(buf,n*18+20)=stor->storage_[i].card[3]; - n++; - } - if(n){ - WBUFW(buf,2)=4+n*18; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#endif - return 0; -} - -/*========================================== - * カプラさんに預けてある装備リスト - *------------------------------------------ - */ -int clif_storageequiplist(struct map_session_data *sd,struct storage *stor) -{ - struct item_data *id; - int i,j,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - buf = WFIFOP(fd,0); - WBUFW(buf,0)=0xa6; - for(i=0,n=0;i<MAX_STORAGE;i++){ - if(stor->storage_[i].nameid<=0) - continue; - nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid)); - if(!itemdb_isequip2(id)) - continue; - WBUFW(buf,n*20+4)=i+1; - if(id->view_id > 0) - WBUFW(buf,n*20+6)=id->view_id; - else - WBUFW(buf,n*20+6)=stor->storage_[i].nameid; - WBUFB(buf,n*20+8)=id->type; - WBUFB(buf,n*20+9)=stor->storage_[i].identify; - WBUFW(buf,n*20+10)=id->equip; - WBUFW(buf,n*20+12)=stor->storage_[i].equip; - WBUFB(buf,n*20+14)=stor->storage_[i].attribute; - WBUFB(buf,n*20+15)=stor->storage_[i].refine; - if(stor->storage_[i].card[0]==0x00ff || stor->storage_[i].card[0]==0x00fe || stor->storage_[i].card[0]==(short)0xff00) { - WBUFW(buf,n*20+16)=stor->storage_[i].card[0]; - WBUFW(buf,n*20+18)=stor->storage_[i].card[1]; - WBUFW(buf,n*20+20)=stor->storage_[i].card[2]; - WBUFW(buf,n*20+22)=stor->storage_[i].card[3]; - } else { - if(stor->storage_[i].card[0] > 0 && (j=itemdb_viewid(stor->storage_[i].card[0])) > 0) - WBUFW(buf,n*20+16)=j; - else - WBUFW(buf,n*20+16)=stor->storage_[i].card[0]; - if(stor->storage_[i].card[1] > 0 && (j=itemdb_viewid(stor->storage_[i].card[1])) > 0) - WBUFW(buf,n*20+18)=j; - else - WBUFW(buf,n*20+18)=stor->storage_[i].card[1]; - if(stor->storage_[i].card[2] > 0 && (j=itemdb_viewid(stor->storage_[i].card[2])) > 0) - WBUFW(buf,n*20+20)=j; - else - WBUFW(buf,n*20+20)=stor->storage_[i].card[2]; - if(stor->storage_[i].card[3] > 0 && (j=itemdb_viewid(stor->storage_[i].card[3])) > 0) - WBUFW(buf,n*20+22)=j; - else - WBUFW(buf,n*20+22)=stor->storage_[i].card[3]; - } - n++; - } - if(n){ - WBUFW(buf,2)=4+n*20; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *stor) -{ - struct item_data *id; - int i,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - buf=WFIFOP(fd,0); - -#if PACKETVER < 5 - WBUFW(buf,0)=0xa5; - for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){ - if(stor->storage_[i].nameid<=0) - continue; - nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid)); - if(itemdb_isequip2(id)) - continue; - - WBUFW(buf,n*10+4)=i+1; - if(id->view_id > 0) - WBUFW(buf,n*10+6)=id->view_id; - else - WBUFW(buf,n*10+6)=stor->storage_[i].nameid; - WBUFB(buf,n*10+8)=id->type;; - WBUFB(buf,n*10+9)=stor->storage_[i].identify; - WBUFW(buf,n*10+10)=stor->storage_[i].amount; - WBUFW(buf,n*10+12)=0; - n++; - } - if(n){ - WBUFW(buf,2)=4+n*10; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#else - WBUFW(buf,0)=0x1f0; - for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){ - if(stor->storage_[i].nameid<=0) - continue; - nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid)); - if(itemdb_isequip2(id)) - continue; - - WBUFW(buf,n*18+4)=i+1; - if(id->view_id > 0) - WBUFW(buf,n*18+6)=id->view_id; - else - WBUFW(buf,n*18+6)=stor->storage_[i].nameid; - WBUFB(buf,n*18+8)=id->type;; - WBUFB(buf,n*18+9)=stor->storage_[i].identify; - WBUFW(buf,n*18+10)=stor->storage_[i].amount; - WBUFW(buf,n*18+12)=0; - WBUFW(buf,n*18+14)=stor->storage_[i].card[0]; - WBUFW(buf,n*18+16)=stor->storage_[i].card[1]; - WBUFW(buf,n*18+18)=stor->storage_[i].card[2]; - WBUFW(buf,n*18+20)=stor->storage_[i].card[3]; - n++; - } - if(n){ - WBUFW(buf,2)=4+n*18; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#endif - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_guildstorageequiplist(struct map_session_data *sd,struct guild_storage *stor) -{ - struct item_data *id; - int i,j,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf=WFIFOP(fd,0); - - WBUFW(buf,0)=0xa6; - for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){ - if(stor->storage_[i].nameid<=0) - continue; - nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid)); - if(!itemdb_isequip2(id)) - continue; - WBUFW(buf,n*20+4)=i+1; - if(id->view_id > 0) - WBUFW(buf,n*20+6)=id->view_id; - else - WBUFW(buf,n*20+6)=stor->storage_[i].nameid; - WBUFB(buf,n*20+8)=id->type; - WBUFB(buf,n*20+9)=stor->storage_[i].identify; - WBUFW(buf,n*20+10)=id->equip; - WBUFW(buf,n*20+12)=stor->storage_[i].equip; - WBUFB(buf,n*20+14)=stor->storage_[i].attribute; - WBUFB(buf,n*20+15)=stor->storage_[i].refine; - if(stor->storage_[i].card[0]==0x00ff || stor->storage_[i].card[0]==0x00fe || stor->storage_[i].card[0]==(short)0xff00) { - WBUFW(buf,n*20+16)=stor->storage_[i].card[0]; - WBUFW(buf,n*20+18)=stor->storage_[i].card[1]; - WBUFW(buf,n*20+20)=stor->storage_[i].card[2]; - WBUFW(buf,n*20+22)=stor->storage_[i].card[3]; - } else { - if(stor->storage_[i].card[0] > 0 && (j=itemdb_viewid(stor->storage_[i].card[0])) > 0) - WBUFW(buf,n*20+16)=j; - else - WBUFW(buf,n*20+16)=stor->storage_[i].card[0]; - if(stor->storage_[i].card[1] > 0 && (j=itemdb_viewid(stor->storage_[i].card[1])) > 0) - WBUFW(buf,n*20+18)=j; - else - WBUFW(buf,n*20+18)=stor->storage_[i].card[1]; - if(stor->storage_[i].card[2] > 0 && (j=itemdb_viewid(stor->storage_[i].card[2])) > 0) - WBUFW(buf,n*20+20)=j; - else - WBUFW(buf,n*20+20)=stor->storage_[i].card[2]; - if(stor->storage_[i].card[3] > 0 && (j=itemdb_viewid(stor->storage_[i].card[3])) > 0) - WBUFW(buf,n*20+22)=j; - else - WBUFW(buf,n*20+22)=stor->storage_[i].card[3]; - } - n++; - } - if(n){ - WBUFW(buf,2)=4+n*20; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * ステータスを送りつける - * 表示専用数字はこの中で計算して送る - *------------------------------------------ - */ -int clif_updatestatus(struct map_session_data *sd,int type) -{ - int fd,len=8; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0xb0; - WFIFOW(fd,2)=type; - switch(type){ - // 00b0 - case SP_WEIGHT: - pc_checkweighticon(sd); - WFIFOW(fd,0)=0xb0; - WFIFOW(fd,2)=type; - WFIFOL(fd,4)=sd->weight; - break; - case SP_MAXWEIGHT: - WFIFOL(fd,4)=sd->max_weight; - break; - case SP_SPEED: - WFIFOL(fd,4)=sd->speed; - break; - case SP_BASELEVEL: - WFIFOL(fd,4)=sd->status.base_level; - break; - case SP_JOBLEVEL: - WFIFOL(fd,4)=sd->status.job_level; - break; - case SP_MANNER: - WFIFOL(fd,4)=sd->status.manner; - clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner); - break; - case SP_STATUSPOINT: - WFIFOL(fd,4)=sd->status.status_point; - break; - case SP_SKILLPOINT: - WFIFOL(fd,4)=sd->status.skill_point; - break; - case SP_HIT: - WFIFOL(fd,4)=sd->hit; - break; - case SP_FLEE1: - WFIFOL(fd,4)=sd->flee; - break; - case SP_FLEE2: - WFIFOL(fd,4)=sd->flee2/10; - break; - case SP_MAXHP: - WFIFOL(fd,4)=sd->status.max_hp; - break; - case SP_MAXSP: - WFIFOL(fd,4)=sd->status.max_sp; - break; - case SP_HP: - WFIFOL(fd,4)=sd->status.hp; - if(battle_config.disp_hpmeter) - clif_hpmeter(sd); - break; - case SP_SP: - WFIFOL(fd,4)=sd->status.sp; - break; - case SP_ASPD: - WFIFOL(fd,4)=sd->aspd; - break; - case SP_ATK1: - WFIFOL(fd,4)=sd->base_atk+sd->watk; - break; - case SP_DEF1: - WFIFOL(fd,4)=sd->def; - break; - case SP_MDEF1: - WFIFOL(fd,4)=sd->mdef; - break; - case SP_ATK2: - WFIFOL(fd,4)=sd->watk2; - break; - case SP_DEF2: - WFIFOL(fd,4)=sd->def2; - break; - case SP_MDEF2: - WFIFOL(fd,4)=sd->mdef2; - break; - case SP_CRITICAL: - WFIFOL(fd,4)=sd->critical/10; - break; - case SP_MATK1: - WFIFOL(fd,4)=sd->matk1; - break; - case SP_MATK2: - WFIFOL(fd,4)=sd->matk2; - break; - - - case SP_ZENY: - WFIFOW(fd,0)=0xb1; - if(sd->status.zeny < 0) - sd->status.zeny = 0; - WFIFOL(fd,4)=sd->status.zeny; - break; - case SP_BASEEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=sd->status.base_exp; - break; - case SP_JOBEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=sd->status.job_exp; - break; - case SP_NEXTBASEEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=pc_nextbaseexp(sd); - break; - case SP_NEXTJOBEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=pc_nextjobexp(sd); - break; - - // 00be 終了 - case SP_USTR: - case SP_UAGI: - case SP_UVIT: - case SP_UINT: - case SP_UDEX: - case SP_ULUK: - WFIFOW(fd,0)=0xbe; - WFIFOB(fd,4)=pc_need_status_point(sd,type-SP_USTR+SP_STR); - len=5; - break; - - // 013a 終了 - case SP_ATTACKRANGE: - WFIFOW(fd,0)=0x13a; - WFIFOW(fd,2)=sd->attackrange; - len=4; - break; - - // 0141 終了 - case SP_STR: - WFIFOW(fd,0)=0x141; - WFIFOL(fd,2)=type; - WFIFOL(fd,6)=sd->status.str; - WFIFOL(fd,10)=sd->paramb[0] + sd->parame[0]; - len=14; - break; - case SP_AGI: - WFIFOW(fd,0)=0x141; - WFIFOL(fd,2)=type; - WFIFOL(fd,6)=sd->status.agi; - WFIFOL(fd,10)=sd->paramb[1] + sd->parame[1]; - len=14; - break; - case SP_VIT: - WFIFOW(fd,0)=0x141; - WFIFOL(fd,2)=type; - WFIFOL(fd,6)=sd->status.vit; - WFIFOL(fd,10)=sd->paramb[2] + sd->parame[2]; - len=14; - break; - case SP_INT: - WFIFOW(fd,0)=0x141; - WFIFOL(fd,2)=type; - WFIFOL(fd,6)=sd->status.int_; - WFIFOL(fd,10)=sd->paramb[3] + sd->parame[3]; - len=14; - break; - case SP_DEX: - WFIFOW(fd,0)=0x141; - WFIFOL(fd,2)=type; - WFIFOL(fd,6)=sd->status.dex; - WFIFOL(fd,10)=sd->paramb[4] + sd->parame[4]; - len=14; - break; - case SP_LUK: - WFIFOW(fd,0)=0x141; - WFIFOL(fd,2)=type; - WFIFOL(fd,6)=sd->status.luk; - WFIFOL(fd,10)=sd->paramb[5] + sd->parame[5]; - len=14; - break; - - case SP_CARTINFO: - WFIFOW(fd,0)=0x121; - WFIFOW(fd,2)=sd->cart_num; - WFIFOW(fd,4)=sd->cart_max_num; - WFIFOL(fd,6)=sd->cart_weight; - WFIFOL(fd,10)=sd->cart_max_weight; - len=14; - break; - - default: - if(battle_config.error_log) - printf("clif_updatestatus : make %d routine\n",type); - return 1; - } - WFIFOSET(fd,len); - - return 0; -} -int clif_changestatus(struct block_list *bl,int type,int val) -{ - unsigned char buf[12]; - struct map_session_data *sd = NULL; - - nullpo_retr(0, bl); - - if(bl->type == BL_PC) - sd = (struct map_session_data *)bl; - -//printf("clif_changestatus id:%d type:%d val:%d\n",bl->id,type,val); - if(sd){ - WBUFW(buf,0)=0x1ab; - WBUFL(buf,2)=bl->id; - WBUFW(buf,6)=type; - switch(type){ - case SP_MANNER: - WBUFL(buf,8)=val; - break; - default: - if(battle_config.error_log) - printf("clif_changestatus : make %d routine\n",type); - return 1; - } - clif_send(buf,packet_len_table[0x1ab],bl,AREA_WOS); - } - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int clif_changelook(struct block_list *bl,int type,int val) -{ - - unsigned char buf[32]; - struct map_session_data *sd = NULL; - - nullpo_retr(0, bl); - - if(bl->type == BL_PC) - sd = (struct map_session_data *)bl; - - if(sd && sd->disguise > 23 && sd->disguise < 4001) // mob disguises [Valaris] - return 0; - -#if PACKETVER < 4 - if(sd && (type == LOOK_WEAPON || type == LOOK_SHIELD) && sd->view_class == 22) - val =0; - WBUFW(buf,0)=0xc3; - WBUFL(buf,2)=bl->id; - WBUFB(buf,6)=type; - WBUFB(buf,7)=val; - clif_send(buf,packet_len_table[0xc3],bl,AREA); -#else - if(sd && (type == LOOK_WEAPON || type == LOOK_SHIELD || type == LOOK_SHOES)) { - WBUFW(buf,0)=0x1d7; - WBUFL(buf,2)=bl->id; - if(type == LOOK_SHOES) { - WBUFB(buf,6)=9; - if(sd->equip_index[2] >= 0 && sd->inventory_data[sd->equip_index[2]]) { - if(sd->inventory_data[sd->equip_index[2]]->view_id > 0) - WBUFW(buf,7)=sd->inventory_data[sd->equip_index[2]]->view_id; - else - WBUFW(buf,7)=sd->status.inventory[sd->equip_index[2]].nameid; - } else - WBUFW(buf,7)=0; - WBUFW(buf,9)=0; - } - else { - WBUFB(buf,6)=2; - if(sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]] && sd->view_class != 22) { - if(sd->inventory_data[sd->equip_index[9]]->view_id > 0) - WBUFW(buf,7)=sd->inventory_data[sd->equip_index[9]]->view_id; - else - WBUFW(buf,7)=sd->status.inventory[sd->equip_index[9]].nameid; - } else - WBUFW(buf,7)=0; - if(sd->equip_index[8] >= 0 && sd->equip_index[8] != sd->equip_index[9] && sd->inventory_data[sd->equip_index[8]] && - sd->view_class != 22) { - if(sd->inventory_data[sd->equip_index[8]]->view_id > 0) - WBUFW(buf,9)=sd->inventory_data[sd->equip_index[8]]->view_id; - else - WBUFW(buf,9)=sd->status.inventory[sd->equip_index[8]].nameid; - } else - WBUFW(buf,9)=0; - } - clif_send(buf,packet_len_table[0x1d7],bl,AREA); - } - else if(sd && (type == LOOK_BASE) && (val > 255)) - { - WBUFW(buf,0)=0x1d7; - WBUFL(buf,2)=bl->id; - WBUFB(buf,6)=type; - WBUFW(buf,7)=val; - WBUFW(buf,9)=0; - clif_send(buf,packet_len_table[0x1d7],bl,AREA); - } else { - WBUFW(buf,0)=0xc3; - WBUFL(buf,2)=bl->id; - WBUFB(buf,6)=type; - WBUFB(buf,7)=val; - clif_send(buf,packet_len_table[0xc3],bl,AREA); - } -#endif - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_initialstatus(struct map_session_data *sd) -{ - int fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf=WFIFOP(fd,0); - - WBUFW(buf,0)=0xbd; - WBUFW(buf,2)=sd->status.status_point; - WBUFB(buf,4)=(sd->status.str > 255)? 255:sd->status.str; - WBUFB(buf,5)=pc_need_status_point(sd,SP_STR); - WBUFB(buf,6)=(sd->status.agi > 255)? 255:sd->status.agi; - WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI); - WBUFB(buf,8)=(sd->status.vit > 255)? 255:sd->status.vit; - WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT); - WBUFB(buf,10)=(sd->status.int_ > 255)? 255:sd->status.int_; - WBUFB(buf,11)=pc_need_status_point(sd,SP_INT); - WBUFB(buf,12)=(sd->status.dex > 255)? 255:sd->status.dex; - WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX); - WBUFB(buf,14)=(sd->status.luk > 255)? 255:sd->status.luk; - WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK); - - WBUFW(buf,16) = sd->base_atk + sd->watk; - WBUFW(buf,18) = sd->watk2; //atk bonus - WBUFW(buf,20) = sd->matk1; - WBUFW(buf,22) = sd->matk2; - WBUFW(buf,24) = sd->def; // def - WBUFW(buf,26) = sd->def2; - WBUFW(buf,28) = sd->mdef; // mdef - WBUFW(buf,30) = sd->mdef2; - WBUFW(buf,32) = sd->hit; - WBUFW(buf,34) = sd->flee; - WBUFW(buf,36) = sd->flee2/10; - WBUFW(buf,38) = sd->critical/10; - WBUFW(buf,40) = sd->status.karma; - WBUFW(buf,42) = sd->status.manner; - - WFIFOSET(fd,packet_len_table[0xbd]); - - clif_updatestatus(sd,SP_STR); - clif_updatestatus(sd,SP_AGI); - clif_updatestatus(sd,SP_VIT); - clif_updatestatus(sd,SP_INT); - clif_updatestatus(sd,SP_DEX); - clif_updatestatus(sd,SP_LUK); - - clif_updatestatus(sd,SP_ATTACKRANGE); - clif_updatestatus(sd,SP_ASPD); - - return 0; -} - -/*========================================== - *矢装備 - *------------------------------------------ - */ -int clif_arrowequip(struct map_session_data *sd,int val) -{ - int fd; - - nullpo_retr(0, sd); - - if(sd->attacktarget && sd->attacktarget > 0) // [Valaris] - sd->attacktarget = 0; - - fd=sd->fd; - WFIFOW(fd,0)=0x013c; - WFIFOW(fd,2)=val+2;//矢のアイテムID - - WFIFOSET(fd,packet_len_table[0x013c]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_arrow_fail(struct map_session_data *sd,int type) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x013b; - WFIFOW(fd,2)=type; - - WFIFOSET(fd,packet_len_table[0x013b]); - - return 0; -} - -/*========================================== - * 作成可能 矢リスト送信 - *------------------------------------------ - */ -int clif_arrow_create_list(struct map_session_data *sd) -{ - int i,c,view; - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1ad; - - for(i=0,c=0;i<MAX_SKILL_ARROW_DB;i++){ - if(skill_arrow_db[i].nameid > 0 && pc_search_inventory(sd,skill_arrow_db[i].nameid)>=0){ - if((view = itemdb_viewid(skill_arrow_db[i].nameid)) > 0) - WFIFOW(fd,c*2+4) = view; - else - WFIFOW(fd,c*2+4) = skill_arrow_db[i].nameid; - c++; - } - } - WFIFOW(fd,2)=c*2+4; - WFIFOSET(fd,WFIFOW(fd,2)); - if(c > 0) sd->state.make_arrow_flag = 1; - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_statusupack(struct map_session_data *sd,int type,int ok,int val) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xbc; - WFIFOW(fd,2)=type; - WFIFOB(fd,4)=ok; - WFIFOB(fd,5)=val; - WFIFOSET(fd,packet_len_table[0xbc]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xaa; - WFIFOW(fd,2)=n+2; - WFIFOW(fd,4)=pos; - WFIFOB(fd,6)=ok; - WFIFOSET(fd,packet_len_table[0xaa]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xac; - WFIFOW(fd,2)=n+2; - WFIFOW(fd,4)=pos; - WFIFOB(fd,6)=ok; - WFIFOSET(fd,packet_len_table[0xac]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_misceffect(struct block_list* bl,int type) -{ - unsigned char buf[32]; - - nullpo_retr(0, bl); - - WBUFW(buf,0) = 0x19b; - WBUFL(buf,2) = bl->id; - WBUFL(buf,6) = type; - - clif_send(buf,packet_len_table[0x19b],bl,AREA); - - return 0; -} -int clif_misceffect2(struct block_list *bl, int type) { - unsigned char buf[24]; - - nullpo_retr(0, bl); - - memset(buf, 0, packet_len_table[0x1f3]); - - WBUFW(buf,0) = 0x1f3; - WBUFL(buf,2) = bl->id; - WBUFL(buf,6) = type; - - clif_send(buf, packet_len_table[0x1f3], bl, AREA); - - return 0; - -} -/*========================================== - * 表示オプション変更 - *------------------------------------------ - */ -int clif_changeoption(struct block_list* bl) -{ - unsigned char buf[32]; - short option; - struct status_change *sc_data; - static const int omask[]={ 0x10,0x20 }; - static const int scnum[]={ SC_FALCON, SC_RIDING }; - int i; - - nullpo_retr(0, bl); - - option = *status_get_option(bl); - sc_data = status_get_sc_data(bl); - - WBUFW(buf,0) = 0x119; - WBUFL(buf,2) = bl->id; - WBUFW(buf,6) = *status_get_opt1(bl); - WBUFW(buf,8) = *status_get_opt2(bl); - WBUFW(buf,10) = option; - WBUFB(buf,12) = 0; // ?? - - if(bl->type==BL_PC) { // disguises [Valaris] - struct map_session_data *sd=(struct map_session_data *)bl; - if(sd && sd->disguise > 23 && sd->disguise < 4001) { - clif_send(buf,packet_len_table[0x119],bl,AREA_WOS); - clif_spawnpc(sd); - } else - clif_send(buf,packet_len_table[0x119],bl,AREA); - } else - clif_send(buf,packet_len_table[0x119],bl,AREA); - - // アイコンの表示 - for(i=0;i<sizeof(omask)/sizeof(omask[0]);i++){ - if( option&omask[i] ){ - if( sc_data[scnum[i]].timer==-1) - status_change_start(bl,scnum[i],0,0,0,0,0,0); - } else { - status_change_end(bl,scnum[i],-1); - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_useitemack(struct map_session_data *sd,int index,int amount,int ok) -{ - nullpo_retr(0, sd); - - if(!ok) { - int fd=sd->fd; - WFIFOW(fd,0)=0xa8; - WFIFOW(fd,2)=index+2; - WFIFOW(fd,4)=amount; - WFIFOB(fd,6)=ok; - WFIFOSET(fd,packet_len_table[0xa8]); - } - else { -#if PACKETVER < 3 - int fd=sd->fd; - WFIFOW(fd,0)=0xa8; - WFIFOW(fd,2)=index+2; - WFIFOW(fd,4)=amount; - WFIFOB(fd,6)=ok; - WFIFOSET(fd,packet_len_table[0xa8]); -#else - unsigned char buf[32]; - - WBUFW(buf,0)=0x1c8; - WBUFW(buf,2)=index+2; - if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0) - WBUFW(buf,4)=sd->inventory_data[index]->view_id; - else - WBUFW(buf,4)=sd->status.inventory[index].nameid; - WBUFL(buf,6)=sd->bl.id; - WBUFW(buf,10)=amount; - WBUFB(buf,12)=ok; - clif_send(buf,packet_len_table[0x1c8],&sd->bl,AREA); -#endif - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_createchat(struct map_session_data *sd,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xd6; - WFIFOB(fd,2)=fail; - WFIFOSET(fd,packet_len_table[0xd6]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_dispchat(struct chat_data *cd,int fd) -{ - unsigned char buf[128]; // 最大title(60バイト)+17 - - if(cd==NULL || *cd->owner==NULL) - return 1; - - WBUFW(buf,0)=0xd7; - WBUFW(buf,2)=strlen((const char*)cd->title)+17; - WBUFL(buf,4)=(*cd->owner)->id; - WBUFL(buf,8)=cd->bl.id; - WBUFW(buf,12)=cd->limit; - WBUFW(buf,14)=cd->users; - WBUFB(buf,16)=cd->pub; - strcpy((char*)WBUFP(buf,17),(const char*)cd->title); - if(fd){ - memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2)); - WFIFOSET(fd,WBUFW(buf,2)); - } else { - clif_send(buf,WBUFW(buf,2),*cd->owner,AREA_WOSC); - } - - return 0; -} - -/*========================================== - * chatの状態変更成功 - * 外部の人用と命令コード(d7->df)が違うだけ - *------------------------------------------ - */ -int clif_changechatstatus(struct chat_data *cd) -{ - unsigned char buf[128]; // 最大title(60バイト)+17 - - if(cd==NULL || cd->usersd[0]==NULL) - return 1; - - WBUFW(buf,0)=0xdf; - WBUFW(buf,2)=strlen((char*)cd->title)+17; - WBUFL(buf,4)=cd->usersd[0]->bl.id; - WBUFL(buf,8)=cd->bl.id; - WBUFW(buf,12)=cd->limit; - WBUFW(buf,14)=cd->users; - WBUFB(buf,16)=cd->pub; - strcpy((char*)WBUFP(buf,17),(const char*)cd->title); - clif_send(buf,WBUFW(buf,2),&cd->usersd[0]->bl,CHAT); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_clearchat(struct chat_data *cd,int fd) -{ - unsigned char buf[32]; - - nullpo_retr(0, cd); - - WBUFW(buf,0)=0xd8; - WBUFL(buf,2)=cd->bl.id; - if(fd){ - memcpy(WFIFOP(fd,0),buf,packet_len_table[0xd8]); - WFIFOSET(fd,packet_len_table[0xd8]); - } else { - clif_send(buf,packet_len_table[0xd8],*cd->owner,AREA_WOSC); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_joinchatfail(struct map_session_data *sd,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0xda; - WFIFOB(fd,2)=fail; - WFIFOSET(fd,packet_len_table[0xda]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_joinchatok(struct map_session_data *sd,struct chat_data* cd) -{ - int fd; - int i; - - nullpo_retr(0, sd); - nullpo_retr(0, cd); - - fd=sd->fd; - WFIFOW(fd,0)=0xdb; - WFIFOW(fd,2)=8+(28*cd->users); - WFIFOL(fd,4)=cd->bl.id; - for(i = 0;i < cd->users;i++){ - WFIFOL(fd,8+i*28) = (i!=0)||((*cd->owner)->type==BL_NPC); - memcpy(WFIFOP(fd,8+i*28+4),cd->usersd[i]->status.name,24); - } - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_addchat(struct chat_data* cd,struct map_session_data *sd) -{ - unsigned char buf[32]; - - nullpo_retr(0, sd); - nullpo_retr(0, cd); - - WBUFW(buf, 0) = 0x0dc; - WBUFW(buf, 2) = cd->users; - memcpy(WBUFP(buf, 4),sd->status.name,24); - clif_send(buf,packet_len_table[0xdc],&sd->bl,CHAT_WOS); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_changechatowner(struct chat_data* cd,struct map_session_data *sd) -{ - unsigned char buf[64]; - - nullpo_retr(0, sd); - nullpo_retr(0, cd); - - WBUFW(buf, 0) = 0xe1; - WBUFL(buf, 2) = 1; - memcpy(WBUFP(buf,6),cd->usersd[0]->status.name,24); - WBUFW(buf,30) = 0xe1; - WBUFL(buf,32) = 0; - memcpy(WBUFP(buf,36),sd->status.name,24); - - clif_send(buf,packet_len_table[0xe1]*2,&sd->bl,CHAT); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_leavechat(struct chat_data* cd,struct map_session_data *sd) -{ - unsigned char buf[32]; - - nullpo_retr(0, sd); - nullpo_retr(0, cd); - - WBUFW(buf, 0) = 0xdd; - WBUFW(buf, 2) = cd->users-1; - memcpy(WBUFP(buf,4),sd->status.name,24); - WBUFB(buf,28) = 0; - - clif_send(buf,packet_len_table[0xdd],&sd->bl,CHAT); - - return 0; -} - -/*========================================== - * 取り引き要請受け - *------------------------------------------ - */ -int clif_traderequest(struct map_session_data *sd,char *name) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xe5; - strcpy((char*)WFIFOP(fd,2),name); - WFIFOSET(fd,packet_len_table[0xe5]); - - return 0; -} - -/*========================================== - * 取り引き要求応答 - *------------------------------------------ - */ -int clif_tradestart(struct map_session_data *sd,int type) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xe7; - WFIFOB(fd,2)=type; - WFIFOSET(fd,packet_len_table[0xe7]); - - return 0; -} - -/*========================================== - * 相手方からのアイテム追加 - *------------------------------------------ - */ -int clif_tradeadditem(struct map_session_data *sd,struct map_session_data *tsd,int index,int amount) -{ - int fd,j; - - nullpo_retr(0, sd); - nullpo_retr(0, tsd); - - fd=tsd->fd; - WFIFOW(fd,0)=0xe9; - WFIFOL(fd,2)=amount; - if(index==0){ - WFIFOW(fd,6) = 0; // type id - WFIFOB(fd,8) = 0; //identify flag - WFIFOB(fd,9) = 0; // attribute - WFIFOB(fd,10)= 0; //refine - WFIFOW(fd,11)= 0; //card (4w) - WFIFOW(fd,13)= 0; //card (4w) - WFIFOW(fd,15)= 0; //card (4w) - WFIFOW(fd,17)= 0; //card (4w) - } - else{ - index -= 2; - if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0) - WFIFOW(fd,6) = sd->inventory_data[index]->view_id; - else - WFIFOW(fd,6) = sd->status.inventory[index].nameid; // type id - WFIFOB(fd,8) = sd->status.inventory[index].identify; //identify flag - WFIFOB(fd,9) = sd->status.inventory[index].attribute; // attribute - WFIFOB(fd,10)= sd->status.inventory[index].refine; //refine - if(sd->status.inventory[index].card[0]==0x00ff || sd->status.inventory[index].card[0]==0x00fe || sd->status.inventory[index].card[0]==(short)0xff00) { - WFIFOW(fd,11)= sd->status.inventory[index].card[0]; //card (4w) - WFIFOW(fd,13)= sd->status.inventory[index].card[1]; //card (4w) - WFIFOW(fd,15)= sd->status.inventory[index].card[2]; //card (4w) - WFIFOW(fd,17)= sd->status.inventory[index].card[3]; //card (4w) - } else { - if(sd->status.inventory[index].card[0] > 0 && (j=itemdb_viewid(sd->status.inventory[index].card[0])) > 0) - WFIFOW(fd,11)= j; - else - WFIFOW(fd,11)= sd->status.inventory[index].card[0]; - if(sd->status.inventory[index].card[1] > 0 && (j=itemdb_viewid(sd->status.inventory[index].card[1])) > 0) - WFIFOW(fd,13)= j; - else - WFIFOW(fd,13)= sd->status.inventory[index].card[1]; - if(sd->status.inventory[index].card[2] > 0 && (j=itemdb_viewid(sd->status.inventory[index].card[2])) > 0) - WFIFOW(fd,15)= j; - else - WFIFOW(fd,15)= sd->status.inventory[index].card[2]; - if(sd->status.inventory[index].card[3] > 0 && (j=itemdb_viewid(sd->status.inventory[index].card[3])) > 0) - WFIFOW(fd,17)= j; - else - WFIFOW(fd,17)= sd->status.inventory[index].card[3]; - } - } - WFIFOSET(fd,packet_len_table[0xe9]); - - return 0; -} - -/*========================================== - * アイテム追加成功/失敗 - *------------------------------------------ - */ -int clif_tradeitemok(struct map_session_data *sd,int index,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xea; - WFIFOW(fd,2)=index; - WFIFOB(fd,4)=fail; - WFIFOSET(fd,packet_len_table[0xea]); - - return 0; -} - -/*========================================== - * 取り引きok押し - *------------------------------------------ - */ -int clif_tradedeal_lock(struct map_session_data *sd,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xec; - WFIFOB(fd,2)=fail; // 0=you 1=the other person - WFIFOSET(fd,packet_len_table[0xec]); - - return 0; -} - -/*========================================== - * 取り引きがキャンセルされました - *------------------------------------------ - */ -int clif_tradecancelled(struct map_session_data *sd) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xee; - WFIFOSET(fd,packet_len_table[0xee]); - - return 0; -} - -/*========================================== - * 取り引き完了 - *------------------------------------------ - */ -int clif_tradecompleted(struct map_session_data *sd,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xf0; - WFIFOB(fd,2)=fail; - WFIFOSET(fd,packet_len_table[0xf0]); - - return 0; -} - -/*========================================== - * カプラ倉庫のアイテム数を更新 - *------------------------------------------ - */ -int clif_updatestorageamount(struct map_session_data *sd,struct storage *stor) -{ - int fd; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - WFIFOW(fd,0) = 0xf2; // update storage amount - WFIFOW(fd,2) = stor->storage_amount; //items - WFIFOW(fd,4) = MAX_STORAGE; //items max - WFIFOSET(fd,packet_len_table[0xf2]); - - return 0; -} - -/*========================================== - * カプラ倉庫にアイテムを追加する - *------------------------------------------ - */ -int clif_storageitemadded(struct map_session_data *sd,struct storage *stor,int index,int amount) -{ - int view,fd,j; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - WFIFOW(fd,0) =0xf4; // Storage item added - WFIFOW(fd,2) =index+1; // index - WFIFOL(fd,4) =amount; // amount - if((view = itemdb_viewid(stor->storage_[index].nameid)) > 0) - WFIFOW(fd,8) =view; - else - WFIFOW(fd,8) =stor->storage_[index].nameid; // id - WFIFOB(fd,10)=stor->storage_[index].identify; //identify flag - WFIFOB(fd,11)=stor->storage_[index].attribute; // attribute - WFIFOB(fd,12)=stor->storage_[index].refine; //refine - if(stor->storage_[index].card[0]==0x00ff || stor->storage_[index].card[0]==0x00fe || stor->storage_[index].card[0]==(short)0xff00) { - WFIFOW(fd,13)=stor->storage_[index].card[0]; //card (4w) - WFIFOW(fd,15)=stor->storage_[index].card[1]; //card (4w) - WFIFOW(fd,17)=stor->storage_[index].card[2]; //card (4w) - WFIFOW(fd,19)=stor->storage_[index].card[3]; //card (4w) - } else { - if(stor->storage_[index].card[0] > 0 && (j=itemdb_viewid(stor->storage_[index].card[0])) > 0) - WFIFOW(fd,13)= j; - else - WFIFOW(fd,13)= stor->storage_[index].card[0]; - if(stor->storage_[index].card[1] > 0 && (j=itemdb_viewid(stor->storage_[index].card[1])) > 0) - WFIFOW(fd,15)= j; - else - WFIFOW(fd,15)= stor->storage_[index].card[1]; - if(stor->storage_[index].card[2] > 0 && (j=itemdb_viewid(stor->storage_[index].card[2])) > 0) - WFIFOW(fd,17)= j; - else - WFIFOW(fd,17)= stor->storage_[index].card[2]; - if(stor->storage_[index].card[3] > 0 && (j=itemdb_viewid(stor->storage_[index].card[3])) > 0) - WFIFOW(fd,19)= j; - else - WFIFOW(fd,19)= stor->storage_[index].card[3]; - } - WFIFOSET(fd,packet_len_table[0xf4]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_updateguildstorageamount(struct map_session_data *sd,struct guild_storage *stor) -{ - int fd; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - WFIFOW(fd,0) = 0xf2; // update storage amount - WFIFOW(fd,2) = stor->storage_amount; //items - WFIFOW(fd,4) = MAX_GUILD_STORAGE; //items max - WFIFOSET(fd,packet_len_table[0xf2]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_guildstorageitemadded(struct map_session_data *sd,struct guild_storage *stor,int index,int amount) -{ - int view,fd,j; - - nullpo_retr(0, sd); - nullpo_retr(0, stor); - - fd=sd->fd; - WFIFOW(fd,0) =0xf4; // Storage item added - WFIFOW(fd,2) =index+1; // index - WFIFOL(fd,4) =amount; // amount - if((view = itemdb_viewid(stor->storage_[index].nameid)) > 0) - WFIFOW(fd,8) =view; - else - WFIFOW(fd,8) =stor->storage_[index].nameid; // id - WFIFOB(fd,10)=stor->storage_[index].identify; //identify flag - WFIFOB(fd,11)=stor->storage_[index].attribute; // attribute - WFIFOB(fd,12)=stor->storage_[index].refine; //refine - if(stor->storage_[index].card[0]==0x00ff || stor->storage_[index].card[0]==0x00fe || stor->storage_[index].card[0]==(short)0xff00) { - WFIFOW(fd,13)=stor->storage_[index].card[0]; //card (4w) - WFIFOW(fd,15)=stor->storage_[index].card[1]; //card (4w) - WFIFOW(fd,17)=stor->storage_[index].card[2]; //card (4w) - WFIFOW(fd,19)=stor->storage_[index].card[3]; //card (4w) - } else { - if(stor->storage_[index].card[0] > 0 && (j=itemdb_viewid(stor->storage_[index].card[0])) > 0) - WFIFOW(fd,13)= j; - else - WFIFOW(fd,13)= stor->storage_[index].card[0]; - if(stor->storage_[index].card[1] > 0 && (j=itemdb_viewid(stor->storage_[index].card[1])) > 0) - WFIFOW(fd,15)= j; - else - WFIFOW(fd,15)= stor->storage_[index].card[1]; - if(stor->storage_[index].card[2] > 0 && (j=itemdb_viewid(stor->storage_[index].card[2])) > 0) - WFIFOW(fd,17)= j; - else - WFIFOW(fd,17)= stor->storage_[index].card[2]; - if(stor->storage_[index].card[3] > 0 && (j=itemdb_viewid(stor->storage_[index].card[3])) > 0) - WFIFOW(fd,19)= j; - else - WFIFOW(fd,19)= stor->storage_[index].card[3]; - } - WFIFOSET(fd,packet_len_table[0xf4]); - - return 0; -} - -/*========================================== - * カプラ倉庫からアイテムを取り去る - *------------------------------------------ - */ -int clif_storageitemremoved(struct map_session_data *sd,int index,int amount) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xf6; // Storage item removed - WFIFOW(fd,2)=index+1; - WFIFOL(fd,4)=amount; - WFIFOSET(fd,packet_len_table[0xf6]); - - return 0; -} - -/*========================================== - * カプラ倉庫を閉じる - *------------------------------------------ - */ -int clif_storageclose(struct map_session_data *sd) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xf8; // Storage Closed - WFIFOSET(fd,packet_len_table[0xf8]); - - return 0; -} - -// -// callback系 ? -// -/*========================================== - * PC表示 - *------------------------------------------ - */ -void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* dstsd) -{ - int len; - - nullpo_retv(sd); - nullpo_retv(dstsd); - - if(dstsd->walktimer != -1){ - len = clif_set007b(dstsd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } else { - len = clif_set0078(dstsd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } - - if(dstsd->chatID){ - struct chat_data *cd; - cd=(struct chat_data*)map_id2bl(dstsd->chatID); - if(cd->usersd[0]==dstsd) - clif_dispchat(cd,sd->fd); - } - if(dstsd->vender_id){ - clif_showvendingboard(&dstsd->bl,dstsd->message,sd->fd); - } - if(dstsd->spiritball > 0) { - clif_set01e1(dstsd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,packet_len_table[0x1e1]); - } - if(battle_config.save_clothcolor==1 && dstsd->status.clothes_color > 0) - clif_changelook(&dstsd->bl,LOOK_CLOTHES_COLOR,dstsd->status.clothes_color); - if(sd->status.manner < 0) - clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner); - -} - -/*========================================== - * NPC表示 - *------------------------------------------ - */ -//fixed by Valaris -void clif_getareachar_npc(struct map_session_data* sd,struct npc_data* nd) -{ - int len; - nullpo_retv(sd); - nullpo_retv(nd); - if(nd->class_ < 0 || nd->flag&1 || nd->class_ == INVISIBLE_CLASS) - return; - if(nd->state.state == MS_WALK){ - len = clif_npc007b(nd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } else { - len = clif_npc0078(nd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } - if(nd->chat_id){ - clif_dispchat((struct chat_data*)map_id2bl(nd->chat_id),sd->fd); - } -} - -/*========================================== - * 移動停止 - *------------------------------------------ - */ -int clif_movemob(struct mob_data *md) -{ - unsigned char buf[256]; - int len; - - nullpo_retr(0, md); - - len = clif_mob007b(md,buf); - clif_send(buf,len,&md->bl,AREA); - - if(mob_get_equip(md->class_) > 0) // mob equipment [Valaris] - clif_mob_equip(md,mob_get_equip(md->class_)); - - if(md->size==2) // tiny/big mobs [Valaris] - clif_specialeffect(&md->bl,423,0); - else if(md->size==1) - clif_specialeffect(&md->bl,421,0); - - return 0; -} - -/*========================================== - * モンスターの位置修正 - *------------------------------------------ - */ -int clif_fixmobpos(struct mob_data *md) -{ - unsigned char buf[256]; - int len; - - nullpo_retr(0, md); - - if(md->state.state == MS_WALK){ - len = clif_mob007b(md,buf); - clif_send(buf,len,&md->bl,AREA); - } else { - len = clif_mob0078(md,buf); - clif_send(buf,len,&md->bl,AREA); - } - - return 0; -} - -/*========================================== - * PCの位置修正 - *------------------------------------------ - */ -int clif_fixpcpos(struct map_session_data *sd) -{ - unsigned char buf[256]; - int len; - - nullpo_retr(0, sd); - - if(sd->walktimer != -1){ - len = clif_set007b(sd,buf); - clif_send(buf,len,&sd->bl,AREA); - } else { - len = clif_set0078(sd,buf); - clif_send(buf,len,&sd->bl,AREA); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_fixpetpos(struct pet_data *pd) -{ - unsigned char buf[256]; - int len; - - nullpo_retr(0, pd); - - if(pd->state.state == MS_WALK){ - len = clif_pet007b(pd,buf); - clif_send(buf,len,&pd->bl,AREA); - } else { - len = clif_pet0078(pd,buf); - clif_send(buf,len,&pd->bl,AREA); - } - - return 0; -} - -// npc walking [Valaris] -int clif_fixnpcpos(struct npc_data *nd) -{ - unsigned char buf[256]; - int len; - - nullpo_retr(0, nd); - - if(nd->state.state == MS_WALK){ - len = clif_npc007b(nd,buf); - clif_send(buf,len,&nd->bl,AREA); - } else { - len = clif_npc0078(nd,buf); - clif_send(buf,len,&nd->bl,AREA); - } - - return 0; -} - -/*========================================== - * 通常攻撃エフェクト&ダメージ - *------------------------------------------ - */ -int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int type,int damage2) -{ - unsigned char buf[256]; - struct status_change *sc_data; - - nullpo_retr(0, src); - nullpo_retr(0, dst); - - sc_data = status_get_sc_data(dst); - - if(type != 4 && dst->type == BL_PC && ((struct map_session_data *)dst)->special_state.infinite_endure) - type = 9; - if(sc_data) { - if(type != 4 && sc_data[SC_ENDURE].timer != -1 && - (dst->type == BL_PC && !map[dst->m].flag.gvg)) - type = 9; - if(sc_data[SC_HALLUCINATION].timer != -1) { - if(damage > 0) - damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; - if(damage2 > 0) - damage2 = damage2*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; - } - } - - WBUFW(buf,0)=0x8a; - WBUFL(buf,2)=src->id; - WBUFL(buf,6)=dst->id; - WBUFL(buf,10)=tick; - WBUFL(buf,14)=sdelay; - WBUFL(buf,18)=ddelay; - WBUFW(buf,22)=(damage > 0x7fff)? 0x7fff:damage; - WBUFW(buf,24)=div; - WBUFB(buf,26)=type; - WBUFW(buf,27)=damage2; - clif_send(buf,packet_len_table[0x8a],src,AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_getareachar_mob(struct map_session_data* sd,struct mob_data* md) -{ - int len; - nullpo_retv(sd); - nullpo_retv(md); - - if (session[sd->fd] == NULL) - return; - - if(md->state.state == MS_WALK){ - len = clif_mob007b(md,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } else { - len = clif_mob0078(md,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } - - if(mob_get_equip(md->class_) > 0) // mob equipment [Valaris] - clif_mob_equip(md,mob_get_equip(md->class_)); - - if(md->size==2) // tiny/big mobs [Valaris] - clif_specialeffect(&md->bl,423,0); - else if(md->size==1) - clif_specialeffect(&md->bl,421,0); - - -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_getareachar_pet(struct map_session_data* sd,struct pet_data* pd) -{ - int len; - - nullpo_retv(sd); - nullpo_retv(pd); - - if(pd->state.state == MS_WALK){ - len = clif_pet007b(pd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } else { - len = clif_pet0078(pd,WFIFOP(sd->fd,0)); - WFIFOSET(sd->fd,len); - } -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fitem) -{ - int view,fd; - - nullpo_retv(sd); - nullpo_retv(fitem); - - fd=sd->fd; - //009d <ID>.l <item ID>.w <identify flag>.B <X>.w <Y>.w <amount>.w <subX>.B <subY>.B - WFIFOW(fd,0)=0x9d; - WFIFOL(fd,2)=fitem->bl.id; - if((view = itemdb_viewid(fitem->item_data.nameid)) > 0) - WFIFOW(fd,6)=view; - else - WFIFOW(fd,6)=fitem->item_data.nameid; - WFIFOB(fd,8)=fitem->item_data.identify; - WFIFOW(fd,9)=fitem->bl.x; - WFIFOW(fd,11)=fitem->bl.y; - WFIFOW(fd,13)=fitem->item_data.amount; - WFIFOB(fd,15)=fitem->subx; - WFIFOB(fd,16)=fitem->suby; - - WFIFOSET(fd,packet_len_table[0x9d]); -} -/*========================================== - * 場所スキルエフェクトが視界に入る - *------------------------------------------ - */ -int clif_getareachar_skillunit(struct map_session_data *sd,struct skill_unit *unit) -{ - int fd; - struct block_list *bl; - - nullpo_retr(0, unit); - - fd=sd->fd; - bl=map_id2bl(unit->group->src_id); -#if PACKETVER < 3 - memset(WFIFOP(fd,0),0,packet_len_table[0x11f]); - WFIFOW(fd, 0)=0x11f; - WFIFOL(fd, 2)=unit->bl.id; - WFIFOL(fd, 6)=unit->group->src_id; - WFIFOW(fd,10)=unit->bl.x; - WFIFOW(fd,12)=unit->bl.y; - WFIFOB(fd,14)=unit->group->unit_id; - WFIFOB(fd,15)=0; - WFIFOSET(fd,packet_len_table[0x11f]); -#else - memset(WFIFOP(fd,0),0,packet_len_table[0x1c9]); - WFIFOW(fd, 0)=0x1c9; - WFIFOL(fd, 2)=unit->bl.id; - WFIFOL(fd, 6)=unit->group->src_id; - WFIFOW(fd,10)=unit->bl.x; - WFIFOW(fd,12)=unit->bl.y; - WFIFOB(fd,14)=unit->group->unit_id; - WFIFOB(fd,15)=1; - WFIFOL(fd,15+1)=0; //1-4調べた限り固定 - WFIFOL(fd,15+5)=0; //5-8調べた限り固定 - //9-12マップごとで一定の77-80とはまた違う4バイトのかなり大きな数字 - WFIFOL(fd,15+13)=unit->bl.y - 0x12; //13-16ユニットのY座標-18っぽい(Y:17でFF FF FF FF) - WFIFOL(fd,15+17)=0x004f37dd; //17-20調べた限り固定 - WFIFOL(fd,15+21)=0x0012f674; //21-24調べた限り固定 - WFIFOL(fd,15+25)=0x0012f664; //25-28調べた限り固定 - WFIFOL(fd,15+29)=0x0012f654; //29-32調べた限り固定 - WFIFOL(fd,15+33)=0x77527bbc; //33-36調べた限り固定 - //37-39 - WFIFOB(fd,15+40)=0x2d; //40調べた限り固定 - WFIFOL(fd,15+41)=0; //41-44調べた限り0固定 - WFIFOL(fd,15+45)=0; //45-48調べた限り0固定 - WFIFOL(fd,15+49)=0; //49-52調べた限り0固定 - WFIFOL(fd,15+53)=0x0048d919; //53-56調べた限り固定 - WFIFOL(fd,15+57)=0x0000003e; //57-60調べた限り固定 - WFIFOL(fd,15+61)=0x0012f66c; //61-64調べた限り固定 - //65-68 - //69-72 - if(bl) WFIFOL(fd,15+73)=bl->y; //73-76術者のY座標 - WFIFOL(fd,15+77)=unit->bl.m; //77-80マップIDかなぁ?かなり2バイトで足りそうな数字 - WFIFOB(fd,15+81)=0xaa; //81終端文字0xaa - - /* Graffiti [Valaris] */ - if(unit->group->unit_id==0xb0) { - WFIFOL(fd,15)=1; - WFIFOL(fd,16)=1; - memcpy(WFIFOP(fd,17),unit->group->valstr,80); - } - - WFIFOSET(fd,packet_len_table[0x1c9]); -#endif - if(unit->group->skill_id == WZ_ICEWALL) - clif_set0192(fd,unit->bl.m,unit->bl.x,unit->bl.y,5); - - return 0; -} -/*========================================== - * 場所スキルエフェクトが視界から消える - *------------------------------------------ - */ -int clif_clearchar_skillunit(struct skill_unit *unit,int fd) -{ - nullpo_retr(0, unit); - - WFIFOW(fd, 0)=0x120; - WFIFOL(fd, 2)=unit->bl.id; - WFIFOSET(fd,packet_len_table[0x120]); - if(unit->group && unit->group->skill_id == WZ_ICEWALL) - clif_set0192(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_01ac(struct block_list *bl) -{ - unsigned char buf[32]; - - nullpo_retr(0, bl); - - WBUFW(buf, 0) = 0x1ac; - WBUFL(buf, 2) = bl->id; - - clif_send(buf,packet_len_table[0x1ac],bl,AREA); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ - int clif_getareachar(struct block_list* bl,va_list ap) -{ - struct map_session_data *sd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - sd=va_arg(ap,struct map_session_data*); - - if (sd == NULL || session[sd->fd] == NULL) - return 0; - - switch(bl->type){ - case BL_PC: - if(sd==(struct map_session_data*)bl) - break; - clif_getareachar_pc(sd,(struct map_session_data*) bl); - break; - case BL_NPC: - clif_getareachar_npc(sd,(struct npc_data*) bl); - break; - case BL_MOB: - clif_getareachar_mob(sd,(struct mob_data*) bl); - break; - case BL_PET: - clif_getareachar_pet(sd,(struct pet_data*) bl); - break; - case BL_ITEM: - clif_getareachar_item(sd,(struct flooritem_data*) bl); - break; - case BL_SKILL: - clif_getareachar_skillunit(sd,(struct skill_unit *)bl); - break; - default: - if(battle_config.error_log) - printf("get area char ??? %d\n",bl->type); - break; - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_pcoutsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd,*dstsd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd=va_arg(ap,struct map_session_data*)); - - switch(bl->type){ - case BL_PC: - dstsd = (struct map_session_data*) bl; - if(sd != dstsd) { - clif_clearchar_id(dstsd->bl.id,0,sd->fd); - clif_clearchar_id(sd->bl.id,0,dstsd->fd); - if(dstsd->chatID){ - struct chat_data *cd; - cd=(struct chat_data*)map_id2bl(dstsd->chatID); - if(cd->usersd[0]==dstsd) - clif_dispchat(cd,sd->fd); - } - if(dstsd->vender_id){ - clif_closevendingboard(&dstsd->bl,sd->fd); - } - } - break; - case BL_NPC: - if( ((struct npc_data *)bl)->class_ != INVISIBLE_CLASS ) - clif_clearchar_id(bl->id,0,sd->fd); - break; - case BL_MOB: - case BL_PET: - clif_clearchar_id(bl->id,0,sd->fd); - break; - case BL_ITEM: - clif_clearflooritem((struct flooritem_data*)bl,sd->fd); - break; - case BL_SKILL: - clif_clearchar_skillunit((struct skill_unit *)bl,sd->fd); - break; - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_pcinsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd,*dstsd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd=va_arg(ap,struct map_session_data*)); - - switch(bl->type){ - case BL_PC: - dstsd = (struct map_session_data *)bl; - if(sd != dstsd) { - clif_getareachar_pc(sd,dstsd); - clif_getareachar_pc(dstsd,sd); - } - break; - case BL_NPC: - clif_getareachar_npc(sd,(struct npc_data*)bl); - break; - case BL_MOB: - clif_getareachar_mob(sd,(struct mob_data*)bl); - break; - case BL_PET: - clif_getareachar_pet(sd,(struct pet_data*)bl); - break; - case BL_ITEM: - clif_getareachar_item(sd,(struct flooritem_data*)bl); - break; - case BL_SKILL: - clif_getareachar_skillunit(sd,(struct skill_unit *)bl); - break; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_moboutsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct mob_data *md; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, md=va_arg(ap,struct mob_data*)); - - if(bl->type==BL_PC - && ((sd = (struct map_session_data*) bl) != NULL) - && session[sd->fd] != NULL) { - clif_clearchar_id(md->bl.id,0,sd->fd); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_mobinsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct mob_data *md; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - md=va_arg(ap,struct mob_data*); - if(bl->type==BL_PC - && ((sd = (struct map_session_data*) bl) != NULL) - && session[sd->fd] != NULL) { - clif_getareachar_mob(sd,md); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_petoutsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct pet_data *pd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, pd=va_arg(ap,struct pet_data*)); - - if(bl->type==BL_PC - && ((sd = (struct map_session_data*) bl) != NULL) - && session[sd->fd] != NULL) { - clif_clearchar_id(pd->bl.id,0,sd->fd); - } - - return 0; -} - -// npc walking [Valaris] -int clif_npcoutsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct npc_data *nd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, nd=va_arg(ap,struct npc_data*)); - - if(bl->type==BL_PC - && ((sd = (struct map_session_data*) bl) != NULL) - && session[sd->fd] != NULL) { - clif_clearchar_id(nd->bl.id,0,sd->fd); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_petinsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct pet_data *pd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - pd=va_arg(ap,struct pet_data*); - if(bl->type==BL_PC - && ((sd = (struct map_session_data*) bl) != NULL) - && session[sd->fd] != NULL) { - clif_getareachar_pet(sd,pd); - } - - return 0; -} - -// npc walking [Valaris] -int clif_npcinsight(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct npc_data *nd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - nd=va_arg(ap,struct npc_data*); - if(bl->type==BL_PC - && ((sd = (struct map_session_data*) bl) != NULL) - && session[sd->fd] != NULL) { - clif_getareachar_npc(sd,nd); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range) -{ - int fd,id; - - nullpo_retr(0, sd); - - fd=sd->fd; - if( (id=sd->status.skill[skillid].id) <= 0 ) - return 0; - WFIFOW(fd,0)=0x147; - WFIFOW(fd,2) = id; - if(type < 0) - WFIFOW(fd,4) = skill_get_inf(id); - else - WFIFOW(fd,4) = type; - WFIFOW(fd,6) = 0; - WFIFOW(fd,8) = sd->status.skill[skillid].lv; - WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[skillid].lv); - if(range < 0) { - range = skill_get_range(id,sd->status.skill[skillid].lv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - WFIFOW(fd,12)= range; - } else - WFIFOW(fd,12)= range; - memset(WFIFOP(fd,14),0,24); - if(!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn == 1 || (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) ) - //WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_get_max(id) && sd->status.skill[skillid].flag ==0 )? 1:0; - WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[skillid].flag ==0 )? 1:0; - else - WFIFOB(fd,38) = 0; - WFIFOSET(fd,packet_len_table[0x147]); - - return 0; -} - -/*========================================== - * スキルリストを送信する - *------------------------------------------ - */ -int clif_skillinfoblock(struct map_session_data *sd) -{ - int fd; - int i,c,len=4,id,range; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x10f; - for ( i = c = 0; i < MAX_SKILL; i++){ - if( (id=sd->status.skill[i].id)!=0 ){ - WFIFOW(fd,len ) = id; - WFIFOW(fd,len+2) = skill_get_inf(id); - WFIFOW(fd,len+4) = 0; - WFIFOW(fd,len+6) = sd->status.skill[i].lv; - WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv); - range = skill_get_range(id,sd->status.skill[i].lv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - WFIFOW(fd,len+10)= range; - memset(WFIFOP(fd,len+12),0,24); - if(!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn == 1 || (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) ) - //WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max(id) && sd->status.skill[i].flag ==0 )? 1:0; - WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[i].flag ==0 )? 1:0; - else - WFIFOB(fd,len+36) = 0; - len+=37; - c++; - } - } - WFIFOW(fd,2)=len; - WFIFOSET(fd,len); - - return 0; -} - -/*========================================== - * スキル割り振り通知 - *------------------------------------------ - */ -int clif_skillup(struct map_session_data *sd,int skill_num) -{ - int range,fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0) = 0x10e; - WFIFOW(fd,2) = skill_num; - WFIFOW(fd,4) = sd->status.skill[skill_num].lv; - WFIFOW(fd,6) = skill_get_sp(skill_num,sd->status.skill[skill_num].lv); - range = skill_get_range(skill_num,sd->status.skill[skill_num].lv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - WFIFOW(fd,8) = range; - //WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_get_max(sd->status.skill[skill_num].id)) ? 1 : 0; - WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_tree_get_max(sd->status.skill[skill_num].id, sd->status.class_)) ? 1 : 0; - WFIFOSET(fd,packet_len_table[0x10e]); - - return 0; -} - -/*========================================== - * スキル詠唱エフェクトを送信する - *------------------------------------------ - */ -int clif_skillcasting(struct block_list* bl, - int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int casttime) -{ - unsigned char buf[32]; - WBUFW(buf,0) = 0x13e; - WBUFL(buf,2) = src_id; - WBUFL(buf,6) = dst_id; - WBUFW(buf,10) = dst_x; - WBUFW(buf,12) = dst_y; - WBUFW(buf,14) = skill_num;//魔法詠唱スキル - WBUFL(buf,16) = skill_get_pl(skill_num);//属性 - WBUFL(buf,20) = casttime;//skill詠唱時間 - clif_send(buf,packet_len_table[0x13e], bl, AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_skillcastcancel(struct block_list* bl) -{ - unsigned char buf[16]; - - nullpo_retr(0, bl); - - WBUFW(buf,0) = 0x1b9; - WBUFL(buf,2) = bl->id; - clif_send(buf,packet_len_table[0x1b9], bl, AREA); - - return 0; -} - -/*========================================== - * スキル詠唱失敗 - *------------------------------------------ - */ -int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - // reset all variables [celest] - sd->skillx = sd->skilly = -1; - sd->skillid = sd->skilllv = -1; - sd->skillitem = sd->skillitemlv = -1; - - if(type==0x4 && (battle_config.display_delay_skill_fail==0 || sd->nodelay)){ - return 0; - } - - WFIFOW(fd,0) = 0x110; - WFIFOW(fd,2) = skill_id; - WFIFOW(fd,4) = btype; - WFIFOW(fd,6) = 0; - WFIFOB(fd,8) = 0; - WFIFOB(fd,9) = type; - WFIFOSET(fd,packet_len_table[0x110]); - - return 0; -} - -/*========================================== - * スキル攻撃エフェクト&ダメージ - *------------------------------------------ - */ -int clif_skill_damage(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type) -{ - unsigned char buf[64]; - struct status_change *sc_data; - - nullpo_retr(0, src); - nullpo_retr(0, dst); - - sc_data = status_get_sc_data(dst); - - if(type != 5 && dst->type == BL_PC && ((struct map_session_data *)dst)->special_state.infinite_endure) - type = 9; - if(sc_data) { - if(type != 5 && sc_data[SC_ENDURE].timer != -1) - type = 9; - if(sc_data[SC_HALLUCINATION].timer != -1 && damage > 0) - damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; - } - -#if PACKETVER < 3 - WBUFW(buf,0)=0x114; - WBUFW(buf,2)=skill_id; - WBUFL(buf,4)=src->id; - WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; - WBUFL(buf,16)=sdelay; - WBUFL(buf,20)=ddelay; - WBUFW(buf,24)=damage; - WBUFW(buf,26)=skill_lv; - WBUFW(buf,28)=div; - WBUFB(buf,30)=(type>0)?type:skill_get_hit(skill_id); - clif_send(buf,packet_len_table[0x114],src,AREA); -#else - WBUFW(buf,0)=0x1de; - WBUFW(buf,2)=skill_id; - WBUFL(buf,4)=src->id; - WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; - WBUFL(buf,16)=sdelay; - WBUFL(buf,20)=ddelay; - WBUFL(buf,24)=damage; - WBUFW(buf,28)=skill_lv; - WBUFW(buf,30)=div; - WBUFB(buf,32)=(type>0)?type:skill_get_hit(skill_id); - clif_send(buf,packet_len_table[0x1de],src,AREA); -#endif - - return 0; -} - -/*========================================== - * 吹き飛ばしスキル攻撃エフェクト&ダメージ - *------------------------------------------ - */ -int clif_skill_damage2(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type) -{ - unsigned char buf[64]; - struct status_change *sc_data; - - nullpo_retr(0, src); - nullpo_retr(0, dst); - - sc_data = status_get_sc_data(dst); - - if(type != 5 && dst->type == BL_PC && ((struct map_session_data *)dst)->special_state.infinite_endure) - type = 9; - if(sc_data) { - if(type != 5 && sc_data[SC_ENDURE].timer != -1) - type = 9; - if(sc_data[SC_HALLUCINATION].timer != -1 && damage > 0) - damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; - } - - WBUFW(buf,0)=0x115; - WBUFW(buf,2)=skill_id; - WBUFL(buf,4)=src->id; - WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; - WBUFL(buf,16)=sdelay; - WBUFL(buf,20)=ddelay; - WBUFW(buf,24)=dst->x; - WBUFW(buf,26)=dst->y; - WBUFW(buf,28)=damage; - WBUFW(buf,30)=skill_lv; - WBUFW(buf,32)=div; - WBUFB(buf,34)=(type>0)?type:skill_get_hit(skill_id); - clif_send(buf,packet_len_table[0x115],src,AREA); - - return 0; -} - -/*========================================== - * 支援/回復スキルエフェクト - *------------------------------------------ - */ -int clif_skill_nodamage(struct block_list *src,struct block_list *dst, - int skill_id,int heal,int fail) -{ - unsigned char buf[32]; - - nullpo_retr(0, src); - nullpo_retr(0, dst); - - WBUFW(buf,0)=0x11a; - WBUFW(buf,2)=skill_id; - WBUFW(buf,4)=(heal > 0x7fff)? 0x7fff:heal; - WBUFL(buf,6)=dst->id; - WBUFL(buf,10)=src->id; - WBUFB(buf,14)=fail; - clif_send(buf,packet_len_table[0x11a],src,AREA); - - return 0; -} - -/*========================================== - * 場所スキルエフェクト - *------------------------------------------ - */ -int clif_skill_poseffect(struct block_list *src,int skill_id,int val,int x,int y,int tick) -{ - unsigned char buf[32]; - - nullpo_retr(0, src); - - WBUFW(buf,0)=0x117; - WBUFW(buf,2)=skill_id; - WBUFL(buf,4)=src->id; - WBUFW(buf,8)=val; - WBUFW(buf,10)=x; - WBUFW(buf,12)=y; - WBUFL(buf,14)=tick; - clif_send(buf,packet_len_table[0x117],src,AREA); - - return 0; -} - -/*========================================== - * 場所スキルエフェクト表示 - *------------------------------------------ - */ -int clif_skill_setunit(struct skill_unit *unit) -{ - unsigned char buf[128]; - struct block_list *bl; - - nullpo_retr(0, unit); - - bl=map_id2bl(unit->group->src_id); - -#if PACKETVER < 3 - memset(WBUFP(buf, 0),0,packet_len_table[0x11f]); - WBUFW(buf, 0)=0x11f; - WBUFL(buf, 2)=unit->bl.id; - WBUFL(buf, 6)=unit->group->src_id; - WBUFW(buf,10)=unit->bl.x; - WBUFW(buf,12)=unit->bl.y; - WBUFB(buf,14)=unit->group->unit_id; - WBUFB(buf,15)=0; - clif_send(buf,packet_len_table[0x11f],&unit->bl,AREA); -#else - memset(WBUFP(buf, 0),0,packet_len_table[0x1c9]); - WBUFW(buf, 0)=0x1c9; - WBUFL(buf, 2)=unit->bl.id; - WBUFL(buf, 6)=unit->group->src_id; - WBUFW(buf,10)=unit->bl.x; - WBUFW(buf,12)=unit->bl.y; - WBUFB(buf,14)=unit->group->unit_id; - WBUFB(buf,15)=1; - WBUFL(buf,15+1)=0; //1-4調べた限り固定 - WBUFL(buf,15+5)=0; //5-8調べた限り固定 - //9-12マップごとで一定の77-80とはまた違う4バイトのかなり大きな数字 - WBUFL(buf,15+13)=unit->bl.y - 0x12; //13-16ユニットのY座標-18っぽい(Y:17でFF FF FF FF) - WBUFL(buf,15+17)=0x004f37dd; //17-20調べた限り固定(0x1b2で0x004fdbddだった) - WBUFL(buf,15+21)=0x0012f674; //21-24調べた限り固定 - WBUFL(buf,15+25)=0x0012f664; //25-28調べた限り固定 - WBUFL(buf,15+29)=0x0012f654; //29-32調べた限り固定 - WBUFL(buf,15+33)=0x77527bbc; //33-36調べた限り固定 - //37-39 - WBUFB(buf,15+40)=0x2d; //40調べた限り固定 - WBUFL(buf,15+41)=0; //41-44調べた限り0固定 - WBUFL(buf,15+45)=0; //45-48調べた限り0固定 - WBUFL(buf,15+49)=0; //49-52調べた限り0固定 - WBUFL(buf,15+53)=0x0048d919; //53-56調べた限り固定(0x01b2で0x00495119だった) - WBUFL(buf,15+57)=0x0000003e; //57-60調べた限り固定 - WBUFL(buf,15+61)=0x0012f66c; //61-64調べた限り固定 - //65-68 - //69-72 - if(bl) WBUFL(buf,15+73)=bl->y; //73-76術者のY座標 - WBUFL(buf,15+77)=unit->bl.m; //77-80マップIDかなぁ?かなり2バイトで足りそうな数字 - WBUFB(buf,15+81)=0xaa; //81終端文字0xaa - - /* Graffiti [Valaris] */ - if(unit->group->unit_id==0xb0) { - WBUFL(buf,15)=1; - WBUFL(buf,16)=1; - memcpy(WBUFP(buf,17),unit->group->valstr,80); - } - - clif_send(buf,packet_len_table[0x1c9],&unit->bl,AREA); -#endif - return 0; -} -/*========================================== - * 場所スキルエフェクト削除 - *------------------------------------------ - */ -int clif_skill_delunit(struct skill_unit *unit) -{ - unsigned char buf[16]; - - nullpo_retr(0, unit); - - WBUFW(buf, 0)=0x120; - WBUFL(buf, 2)=unit->bl.id; - clif_send(buf,packet_len_table[0x120],&unit->bl,AREA); - return 0; -} -/*========================================== - * ワープ場所選択 - *------------------------------------------ - */ -int clif_skill_warppoint(struct map_session_data *sd,int skill_num, - const char *map1,const char *map2,const char *map3,const char *map4) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x11c; - WFIFOW(fd,2)=skill_num; - strncpy((char*)WFIFOP(fd, 4),map1,16); - strncpy((char*)WFIFOP(fd,20),map2,16); - strncpy((char*)WFIFOP(fd,36),map3,16); - strncpy((char*)WFIFOP(fd,52),map4,16); - WFIFOSET(fd,packet_len_table[0x11c]); - return 0; -} -/*========================================== - * メモ応答 - *------------------------------------------ - */ -int clif_skill_memo(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0x11e; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x11e]); - return 0; -} -int clif_skill_teleportmessage(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x189; - WFIFOW(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x189]); - return 0; -} - -/*========================================== - * モンスター情報 - *------------------------------------------ - */ -int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst) -{ - struct mob_data *md; - unsigned char buf[64]; - int i; - - nullpo_retr(0, sd); - nullpo_retr(0, dst); - - if(dst->type!=BL_MOB ) - return 0; - if((md=(struct mob_data *)dst) == NULL) - return 0; - - WBUFW(buf, 0)=0x18c; - WBUFW(buf, 2)=mob_get_viewclass(md->class_); - WBUFW(buf, 4)=md->level; - WBUFW(buf, 6)=mob_db[md->class_].size; - WBUFL(buf, 8)=md->hp; - WBUFW(buf,12)=status_get_def2(&md->bl); - WBUFW(buf,14)=mob_db[md->class_].race; - WBUFW(buf,16)=status_get_mdef2(&md->bl) - (mob_db[md->class_].vit>>1); - WBUFW(buf,18)=status_get_elem_type(&md->bl); - for(i=0;i<9;i++) - WBUFB(buf,20+i)= battle_attr_fix(100,i+1,md->def_ele); - - if(sd->status.party_id>0) - clif_send(buf,packet_len_table[0x18c],&sd->bl,PARTY_AREA); - else{ - memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x18c]); - WFIFOSET(sd->fd,packet_len_table[0x18c]); - } - return 0; -} -/*========================================== - * アイテム合成可能リスト - *------------------------------------------ - */ -int clif_skill_produce_mix_list(struct map_session_data *sd,int trigger) -{ - int i,c,view,fd; - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd, 0)=0x18d; - - for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){ - if( skill_can_produce_mix(sd,skill_produce_db[i].nameid,trigger) ){ - if((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0) - WFIFOW(fd,c*8+ 4)= view; - else - WFIFOW(fd,c*8+ 4)= skill_produce_db[i].nameid; - WFIFOW(fd,c*8+ 6)= 0x0012; - WFIFOL(fd,c*8+ 8)= sd->status.char_id; - c++; - } - } - WFIFOW(fd, 2)=c*8+8; - WFIFOSET(fd,WFIFOW(fd,2)); - if(c > 0) sd->state.produce_flag = 1; - return 0; -} - -/*========================================== - * 状態異常アイコン/メッセージ表示 - *------------------------------------------ - */ -int clif_status_change(struct block_list *bl,int type,int flag) -{ - unsigned char buf[16]; - - nullpo_retr(0, bl); - - WBUFW(buf,0)=0x0196; - WBUFW(buf,2)=type; - WBUFL(buf,4)=bl->id; - WBUFB(buf,8)=flag; - clif_send(buf,packet_len_table[0x196],bl,AREA); - return 0; -} - -/*========================================== - * Send message (modified by [Yor]) - *------------------------------------------ - */ -int clif_displaymessage(const int fd, char* mes) -{ - // invalid pointer? - nullpo_retr(-1, mes); - - //Console [Wizputer] - if (fd == 0) - printf("\033[0;36mConsole: \033[0m\033[1m%s\033[0m\n", mes); - else { - int len_mes = strlen(mes); - - if (len_mes > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line. - WFIFOW(fd,0) = 0x8e; - WFIFOW(fd,2) = 5 + len_mes; // 4 + len + NULL teminate - memcpy(WFIFOP(fd,4), mes, len_mes + 1); - WFIFOSET(fd, 5 + len_mes); - } - } - - return 0; -} - -/*========================================== - * 天の声を送信する - *------------------------------------------ - */ -int clif_GMmessage(struct block_list *bl, char* mes, int len, int flag) -{ - unsigned char *buf; - int lp; - - lp = (flag & 0x10) ? 8 : 4; - buf = (unsigned char*)aCallocA(len + lp, sizeof(unsigned char)); - - WBUFW(buf,0) = 0x9a; - WBUFW(buf,2) = len + lp; - WBUFL(buf,4) = 0x65756c62; - memcpy(WBUFP(buf,lp), mes, len); - flag &= 0x07; - clif_send(buf, WBUFW(buf,2), bl, - (flag == 1) ? ALL_SAMEMAP : - (flag == 2) ? AREA : - (flag == 3) ? SELF : - ALL_CLIENT); - - if(buf) aFree(buf); - - return 0; -} - -/*========================================== - * グローバルメッセージ - *------------------------------------------ - */ -void clif_GlobalMessage(struct block_list *bl,char *message) -{ - char buf[100]; - int len,cmd=0x8d; - - if(!bl || !message) - return; - - len=strlen(message)+1; - - WBUFW(buf,0)=cmd; - WBUFW(buf,2)=len+8; - WBUFL(buf,4)=bl->id; - strncpy((char *) WBUFP(buf,8),message,len); - clif_send((unsigned char *) buf,WBUFW(buf,2),bl,AREA_CHAT_WOC); -} - -/*========================================== - * HPSP回復エフェクトを送信する - *------------------------------------------ - */ -int clif_heal(int fd,int type,int val) -{ - WFIFOW(fd,0)=0x13d; - WFIFOW(fd,2)=type; - WFIFOW(fd,4)=val; - WFIFOSET(fd,packet_len_table[0x13d]); - - return 0; -} - -/*========================================== - * 復活する - *------------------------------------------ - */ -int clif_resurrection(struct block_list *bl,int type) -{ - unsigned char buf[16]; - - nullpo_retr(0, bl); - - if(bl->type==BL_PC) { // disguises [Valaris] - struct map_session_data *sd=((struct map_session_data *)bl); - if(sd && sd->disguise > 23 && sd->disguise < 4001) - clif_spawnpc(sd); - } - - WBUFW(buf,0)=0x148; - WBUFL(buf,2)=bl->id; - WBUFW(buf,6)=type; - - clif_send(buf,packet_len_table[0x148],bl,type==1 ? AREA : AREA_WOS); - - return 0; -} - -/*========================================== - * PVP実装?(仮) - *------------------------------------------ - */ -int clif_set0199(int fd,int type) -{ - WFIFOW(fd,0)=0x199; - WFIFOW(fd,2)=type; - WFIFOSET(fd,packet_len_table[0x199]); - - return 0; -} - -/*========================================== - * PVP実装?(仮) - *------------------------------------------ - */ -int clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type) -{ - nullpo_retr(0, sd); - - if(map[sd->bl.m].flag.nopvp) - return 0; - - if(type == 2) { - WFIFOW(sd->fd,0) = 0x19a; - WFIFOL(sd->fd,2) = sd->bl.id; - if(pvprank<=0) - pc_calc_pvprank(sd); - WFIFOL(sd->fd,6) = pvprank; - WFIFOL(sd->fd,10) = pvpnum; - WFIFOSET(sd->fd,packet_len_table[0x19a]); - } else { - unsigned char buf[32]; - - WBUFW(buf,0) = 0x19a; - WBUFL(buf,2) = sd->bl.id; - if(sd->status.option&0x46) - // WTF? a -1 to an unsigned value... - WBUFL(buf,6) = 0xFFFFFFFF; - else - if(pvprank<=0) - pc_calc_pvprank(sd); - WBUFL(buf,6) = pvprank; - WBUFL(buf,10) = pvpnum; - if(!type) - clif_send(buf,packet_len_table[0x19a],&sd->bl,AREA); - else - clif_send(buf,packet_len_table[0x19a],&sd->bl,ALL_SAMEMAP); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_send0199(int map,int type) -{ - struct block_list bl; - unsigned char buf[16]; - - bl.m = map; - WBUFW(buf,0)=0x199; - WBUFW(buf,2)=type; - clif_send(buf,packet_len_table[0x199],&bl,ALL_SAMEMAP); - - return 0; -} - -/*========================================== - * 精錬エフェクトを送信する - *------------------------------------------ - */ -int clif_refine(int fd,struct map_session_data *sd,int fail,int index,int val) -{ - WFIFOW(fd,0)=0x188; - WFIFOW(fd,2)=fail; - WFIFOW(fd,4)=index+2; - WFIFOW(fd,6)=val; - WFIFOSET(fd,packet_len_table[0x188]); - - return 0; -} - -/*========================================== - * Wisp/page is transmitted to the destination player - *------------------------------------------ - */ -int clif_wis_message(int fd, char *nick, char *mes, int mes_len) // R 0097 <len>.w <nick>.24B <message>.?B -{ -// printf("clif_wis_message(%d, %s, %s)\n", fd, nick, mes); - - WFIFOW(fd,0) = 0x97; - WFIFOW(fd,2) = mes_len + 24 + 4; - memcpy(WFIFOP(fd,4), nick, 24); - memcpy(WFIFOP(fd,28), mes, mes_len); - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} - -/*========================================== - * The transmission result of Wisp/page is transmitted to the source player - *------------------------------------------ - */ -int clif_wis_end(int fd, int flag) // R 0098 <type>.B: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target -{ - WFIFOW(fd,0) = 0x98; - WFIFOW(fd,2) = flag; - WFIFOSET(fd,packet_len_table[0x98]); - return 0; -} - -/*========================================== - * キャラID名前引き結果を送信する - *------------------------------------------ - */ -int clif_solved_charname(struct map_session_data *sd,int char_id) -{ - char *p= map_charid2nick(char_id); - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - if(p!=NULL){ - WFIFOW(fd,0)=0x194; - WFIFOL(fd,2)=char_id; - memcpy(WFIFOP(fd,6), p,24 ); - WFIFOSET(fd,packet_len_table[0x194]); - }else{ - map_reqchariddb(sd,char_id); - chrif_searchcharid(char_id); - } - return 0; -} - -/*========================================== - * カードの挿入可能リストを返す - *------------------------------------------ - */ -int clif_use_card(struct map_session_data *sd,int idx) -{ - nullpo_retr(0, sd); - - if(sd->inventory_data[idx]) { - int i,c; - int ep=sd->inventory_data[idx]->equip; - int fd=sd->fd; - WFIFOW(fd,0)=0x017b; - - for(i=c=0;i<MAX_INVENTORY;i++){ - int j; - - if(sd->inventory_data[i] == NULL) - continue; - if(sd->inventory_data[i]->type!=4 && sd->inventory_data[i]->type!=5) // 武器防具じゃない - continue; - if(sd->status.inventory[i].card[0]==0x00ff) // 製造武器 - continue; - if(sd->status.inventory[i].card[0]==(short)0xff00 || sd->status.inventory[i].card[0]==0x00fe) - continue; - if(sd->status.inventory[i].identify==0 ) // 未鑑定 - continue; - - if((sd->inventory_data[i]->equip&ep)==0) // 装備個所が違う - continue; - if(sd->inventory_data[i]->type==4 && ep==32) // 盾カードと両手武器 - continue; - - for(j=0;j<sd->inventory_data[i]->slot;j++){ - if( sd->status.inventory[i].card[j]==0 ) - break; - } - if(j==sd->inventory_data[i]->slot) // すでにカードが一杯 - continue; - - WFIFOW(fd,4+c*2)=i+2; - c++; - } - WFIFOW(fd,2)=4+c*2; - WFIFOSET(fd,WFIFOW(fd,2)); - } - - return 0; -} -/*========================================== - * カードの挿入終了 - *------------------------------------------ - */ -int clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x17d; - WFIFOW(fd,2)=idx_equip+2; - WFIFOW(fd,4)=idx_card+2; - WFIFOB(fd,6)=flag; - WFIFOSET(fd,packet_len_table[0x17d]); - return 0; -} - -/*========================================== - * 鑑定可能アイテムリスト送信 - *------------------------------------------ - */ -int clif_item_identify_list(struct map_session_data *sd) -{ - int i,c; - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0x177; - for(i=c=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){ - WFIFOW(fd,c*2+4)=i+2; - c++; - } - } - if(c > 0) { - WFIFOW(fd,2)=c*2+4; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * 鑑定結果 - *------------------------------------------ - */ -int clif_item_identified(struct map_session_data *sd,int idx,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd, 0)=0x179; - WFIFOW(fd, 2)=idx+2; - WFIFOB(fd, 4)=flag; - WFIFOSET(fd,packet_len_table[0x179]); - return 0; -} - -/*========================================== - * 修理可能アイテムリスト送信 - * ※実際のパケットがわからないので動作しません - *------------------------------------------ - */ -int clif_item_repair_list(struct map_session_data *sd) -{ - int i,c; - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0x177; // temporarily use same packet as clif_item_identify - for(i=c=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].attribute==1){ - WFIFOW(fd,c*2+4)=i+2; - c++; - } - } - if(c > 0) { - WFIFOW(fd,2)=c*2+4; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * Weapon Refining [Celest] - *------------------------------------------ - */ -int clif_item_refine_list(struct map_session_data *sd) -{ - int i,c; - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0x177; // temporarily use same packet as clif_item_identify - for(i=c=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && itemdb_type(sd->status.inventory[i].nameid)==4){ - WFIFOW(fd,c*2+4)=i+2; - c++; - } - } - if(c > 0) { - WFIFOW(fd,2)=c*2+4; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * アイテムによる一時的なスキル効果 - *------------------------------------------ - */ -int clif_item_skill(struct map_session_data *sd,int skillid,int skilllv,const char *name) -{ - int range,fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd, 0)=0x147; - WFIFOW(fd, 2)=skillid; - WFIFOW(fd, 4)=skill_get_inf(skillid); - WFIFOW(fd, 6)=0; - WFIFOW(fd, 8)=skilllv; - WFIFOW(fd,10)=skill_get_sp(skillid,skilllv); - range = skill_get_range(skillid,skilllv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - WFIFOW(fd,12)=range; - strncpy((char*)WFIFOP(fd,14),name,24); - WFIFOB(fd,38)=0; - WFIFOSET(fd,packet_len_table[0x147]); - return 0; -} - -/*========================================== - * カートにアイテム追加 - *------------------------------------------ - */ -int clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail) -{ - int view,j,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf=WFIFOP(fd,0); - if(n<0 || n>=MAX_CART || sd->status.cart[n].nameid<=0) - return 1; - - WBUFW(buf,0)=0x124; - WBUFW(buf,2)=n+2; - WBUFL(buf,4)=amount; - if((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0) - WBUFW(buf,8)=view; - else - WBUFW(buf,8)=sd->status.cart[n].nameid; - WBUFB(buf,10)=sd->status.cart[n].identify; - WBUFB(buf,11)=sd->status.cart[n].attribute; - WBUFB(buf,12)=sd->status.cart[n].refine; - if(sd->status.cart[n].card[0]==0x00ff || sd->status.cart[n].card[0]==0x00fe || sd->status.cart[n].card[0]==(short)0xff00) { - WBUFW(buf,13)=sd->status.cart[n].card[0]; - WBUFW(buf,15)=sd->status.cart[n].card[1]; - WBUFW(buf,17)=sd->status.cart[n].card[2]; - WBUFW(buf,19)=sd->status.cart[n].card[3]; - } else { - if(sd->status.cart[n].card[0] > 0 && (j=itemdb_viewid(sd->status.cart[n].card[0])) > 0) - WBUFW(buf,13)= j; - else - WBUFW(buf,13)= sd->status.cart[n].card[0]; - if(sd->status.cart[n].card[1] > 0 && (j=itemdb_viewid(sd->status.cart[n].card[1])) > 0) - WBUFW(buf,15)= j; - else - WBUFW(buf,15)= sd->status.cart[n].card[1]; - if(sd->status.cart[n].card[2] > 0 && (j=itemdb_viewid(sd->status.cart[n].card[2])) > 0) - WBUFW(buf,17)= j; - else - WBUFW(buf,17)= sd->status.cart[n].card[2]; - if(sd->status.cart[n].card[3] > 0 && (j=itemdb_viewid(sd->status.cart[n].card[3])) > 0) - WBUFW(buf,19)= j; - else - WBUFW(buf,19)= sd->status.cart[n].card[3]; - } - WFIFOSET(fd,packet_len_table[0x124]); - return 0; -} - -/*========================================== - * カートからアイテム削除 - *------------------------------------------ - */ -int clif_cart_delitem(struct map_session_data *sd,int n,int amount) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - - WFIFOW(fd,0)=0x125; - WFIFOW(fd,2)=n+2; - WFIFOL(fd,4)=amount; - - WFIFOSET(fd,packet_len_table[0x125]); - - return 0; -} - -/*========================================== - * カートのアイテムリスト - *------------------------------------------ - */ -int clif_cart_itemlist(struct map_session_data *sd) -{ - struct item_data *id; - int i,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf = WFIFOP(fd,0); -#if PACKETVER < 5 - WBUFW(buf,0)=0x123; - for(i=0,n=0;i<MAX_CART;i++){ - if(sd->status.cart[i].nameid<=0) - continue; - id = itemdb_search(sd->status.cart[i].nameid); - if(itemdb_isequip2(id)) - continue; - WBUFW(buf,n*10+4)=i+2; - if(id->view_id > 0) - WBUFW(buf,n*10+6)=id->view_id; - else - WBUFW(buf,n*10+6)=sd->status.cart[i].nameid; - WBUFB(buf,n*10+8)=id->type; - WBUFB(buf,n*10+9)=sd->status.cart[i].identify; - WBUFW(buf,n*10+10)=sd->status.cart[i].amount; - WBUFW(buf,n*10+12)=0; - n++; - } - if(n){ - WBUFW(buf,2)=4+n*10; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#else - WBUFW(buf,0)=0x1ef; - for(i=0,n=0;i<MAX_CART;i++){ - if(sd->status.cart[i].nameid<=0) - continue; - id = itemdb_search(sd->status.cart[i].nameid); - if(itemdb_isequip2(id)) - continue; - WBUFW(buf,n*18+4)=i+2; - if(id->view_id > 0) - WBUFW(buf,n*18+6)=id->view_id; - else - WBUFW(buf,n*18+6)=sd->status.cart[i].nameid; - WBUFB(buf,n*18+8)=id->type; - WBUFB(buf,n*18+9)=sd->status.cart[i].identify; - WBUFW(buf,n*18+10)=sd->status.cart[i].amount; - WBUFW(buf,n*18+12)=0; - WBUFW(buf,n*18+14)=sd->status.cart[i].card[0]; - WBUFW(buf,n*18+16)=sd->status.cart[i].card[1]; - WBUFW(buf,n*18+18)=sd->status.cart[i].card[2]; - WBUFW(buf,n*18+20)=sd->status.cart[i].card[3]; - n++; - } - if(n){ - WBUFW(buf,2)=4+n*18; - WFIFOSET(fd,WFIFOW(fd,2)); - } -#endif - return 0; -} - -/*========================================== - * カートの装備品リスト - *------------------------------------------ - */ -int clif_cart_equiplist(struct map_session_data *sd) -{ - struct item_data *id; - int i,j,n,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf = WFIFOP(fd,0); - - WBUFW(buf,0)=0x122; - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if(sd->status.cart[i].nameid<=0) - continue; - id = itemdb_search(sd->status.cart[i].nameid); - if(!itemdb_isequip2(id)) - continue; - WBUFW(buf,n*20+4)=i+2; - if(id->view_id > 0) - WBUFW(buf,n*20+6)=id->view_id; - else - WBUFW(buf,n*20+6)=sd->status.cart[i].nameid; - WBUFB(buf,n*20+8)=id->type; - WBUFB(buf,n*20+9)=sd->status.cart[i].identify; - WBUFW(buf,n*20+10)=id->equip; - WBUFW(buf,n*20+12)=sd->status.cart[i].equip; - WBUFB(buf,n*20+14)=sd->status.cart[i].attribute; - WBUFB(buf,n*20+15)=sd->status.cart[i].refine; - if(sd->status.cart[i].card[0]==0x00ff || sd->status.cart[i].card[0]==0x00fe || sd->status.cart[i].card[0]==(short)0xff00) { - WBUFW(buf,n*20+16)=sd->status.cart[i].card[0]; - WBUFW(buf,n*20+18)=sd->status.cart[i].card[1]; - WBUFW(buf,n*20+20)=sd->status.cart[i].card[2]; - WBUFW(buf,n*20+22)=sd->status.cart[i].card[3]; - } else { - if(sd->status.cart[i].card[0] > 0 && (j=itemdb_viewid(sd->status.cart[i].card[0])) > 0) - WBUFW(buf,n*20+16)= j; - else - WBUFW(buf,n*20+16)= sd->status.cart[i].card[0]; - if(sd->status.cart[i].card[1] > 0 && (j=itemdb_viewid(sd->status.cart[i].card[1])) > 0) - WBUFW(buf,n*20+18)= j; - else - WBUFW(buf,n*20+18)= sd->status.cart[i].card[1]; - if(sd->status.cart[i].card[2] > 0 && (j=itemdb_viewid(sd->status.cart[i].card[2])) > 0) - WBUFW(buf,n*20+20)= j; - else - WBUFW(buf,n*20+20)= sd->status.cart[i].card[2]; - if(sd->status.cart[i].card[3] > 0 && (j=itemdb_viewid(sd->status.cart[i].card[3])) > 0) - WBUFW(buf,n*20+22)= j; - else - WBUFW(buf,n*20+22)= sd->status.cart[i].card[3]; - } - n++; - } - if(n){ - WBUFW(buf,2)=4+n*20; - WFIFOSET(fd,WFIFOW(fd,2)); - } - return 0; -} - -/*========================================== - * 露店開設 - *------------------------------------------ - */ -int clif_openvendingreq(struct map_session_data *sd,int num) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x12d; - WFIFOW(fd,2)=num; - WFIFOSET(fd,packet_len_table[0x12d]); - - return 0; -} - -/*========================================== - * 露店看板表示 - *------------------------------------------ - */ -int clif_showvendingboard(struct block_list* bl,char *message,int fd) -{ - unsigned char buf[128]; - - nullpo_retr(0, bl); - - WBUFW(buf,0)=0x131; - WBUFL(buf,2)=bl->id; - strncpy((char*)WBUFP(buf,6),message,80); - if(fd){ - memcpy(WFIFOP(fd,0),buf,packet_len_table[0x131]); - WFIFOSET(fd,packet_len_table[0x131]); - }else{ - clif_send(buf,packet_len_table[0x131],bl,AREA_WOS); - } - return 0; -} - -/*========================================== - * 露店看板消去 - *------------------------------------------ - */ -int clif_closevendingboard(struct block_list* bl,int fd) -{ - unsigned char buf[16]; - - nullpo_retr(0, bl); - - WBUFW(buf,0)=0x132; - WBUFL(buf,2)=bl->id; - if(fd){ - memcpy(WFIFOP(fd,0),buf,packet_len_table[0x132]); - WFIFOSET(fd,packet_len_table[0x132]); - }else{ - clif_send(buf,packet_len_table[0x132],bl,AREA_WOS); - } - - return 0; -} -/*========================================== - * 露店アイテムリスト - *------------------------------------------ - */ -int clif_vendinglist(struct map_session_data *sd,int id,struct vending *vending) -{ - struct item_data *data; - int i,j,n,index,fd; - struct map_session_data *vsd; - unsigned char *buf; - - nullpo_retr(0, sd); - nullpo_retr(0, vending); - nullpo_retr(0, vsd=map_id2sd(id)); - - fd=sd->fd; - buf = WFIFOP(fd,0); - WBUFW(buf,0)=0x133; - WBUFL(buf,4)=id; - for(i=0,n=0;i<vsd->vend_num;i++){ - if(vending[i].amount<=0) - continue; - WBUFL(buf,8+n*22)=vending[i].value; - WBUFW(buf,12+n*22)=vending[i].amount; - WBUFW(buf,14+n*22)=(index=vending[i].index)+2; - if(vsd->status.cart[index].nameid <= 0 || vsd->status.cart[index].amount <= 0) - continue; - data = itemdb_search(vsd->status.cart[index].nameid); - WBUFB(buf,16+n*22)=data->type; - if(data->view_id > 0) - WBUFW(buf,17+n*22)=data->view_id; - else - WBUFW(buf,17+n*22)=vsd->status.cart[index].nameid; - WBUFB(buf,19+n*22)=vsd->status.cart[index].identify; - WBUFB(buf,20+n*22)=vsd->status.cart[index].attribute; - WBUFB(buf,21+n*22)=vsd->status.cart[index].refine; - if(vsd->status.cart[index].card[0]==0x00ff || vsd->status.cart[index].card[0]==0x00fe || vsd->status.cart[index].card[0]==(short)0xff00) { - WBUFW(buf,22+n*22)=vsd->status.cart[index].card[0]; - WBUFW(buf,24+n*22)=vsd->status.cart[index].card[1]; - WBUFW(buf,26+n*22)=vsd->status.cart[index].card[2]; - WBUFW(buf,28+n*22)=vsd->status.cart[index].card[3]; - } else { - if(vsd->status.cart[index].card[0] > 0 && (j=itemdb_viewid(vsd->status.cart[index].card[0])) > 0) - WBUFW(buf,22+n*22)= j; - else - WBUFW(buf,22+n*22)= vsd->status.cart[index].card[0]; - if(vsd->status.cart[index].card[1] > 0 && (j=itemdb_viewid(vsd->status.cart[index].card[1])) > 0) - WBUFW(buf,24+n*22)= j; - else - WBUFW(buf,24+n*22)= vsd->status.cart[index].card[1]; - if(vsd->status.cart[index].card[2] > 0 && (j=itemdb_viewid(vsd->status.cart[index].card[2])) > 0) - WBUFW(buf,26+n*22)= j; - else - WBUFW(buf,26+n*22)= vsd->status.cart[index].card[2]; - if(vsd->status.cart[index].card[3] > 0 && (j=itemdb_viewid(vsd->status.cart[index].card[3])) > 0) - WBUFW(buf,28+n*22)= j; - else - WBUFW(buf,28+n*22)= vsd->status.cart[index].card[3]; - } - n++; - } - if(n > 0){ - WBUFW(buf,2)=8+n*22; - WFIFOSET(fd,WFIFOW(fd,2)); - } - - return 0; -} - -/*========================================== - * 露店アイテム購入失敗 - *------------------------------------------ -*/ -int clif_buyvending(struct map_session_data *sd,int index,int amount,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x135; - WFIFOW(fd,2)=index+2; - WFIFOW(fd,4)=amount; - WFIFOB(fd,6)=fail; - WFIFOSET(fd,packet_len_table[0x135]); - - return 0; -} - -/*========================================== - * 露店開設成功 - *------------------------------------------ -*/ -int clif_openvending(struct map_session_data *sd,int id,struct vending *vending) -{ - struct item_data *data; - int i,j,n,index,fd; - unsigned char *buf; - - nullpo_retr(0, sd); - - fd=sd->fd; - buf = WFIFOP(fd,0); - - WBUFW(buf,0)=0x136; - WBUFL(buf,4)=id; - for(i=0,n=0;i<sd->vend_num;i++){ - if (sd->vend_num > 2+pc_checkskill(sd,MC_VENDING)) return 0; - WBUFL(buf,8+n*22)=vending[i].value; - WBUFW(buf,12+n*22)=(index=vending[i].index)+2; - WBUFW(buf,14+n*22)=vending[i].amount; - if(sd->status.cart[index].nameid <= 0 || sd->status.cart[index].amount <= 0 || sd->status.cart[index].identify==0 || - sd->status.cart[index].attribute==1) // Prevent unidentified and broken items from being sold [Valaris] - continue; - data = itemdb_search(sd->status.cart[index].nameid); - WBUFB(buf,16+n*22)=data->type; - if(data->view_id > 0) - WBUFW(buf,17+n*22)=data->view_id; - else - WBUFW(buf,17+n*22)=sd->status.cart[index].nameid; - WBUFB(buf,19+n*22)=sd->status.cart[index].identify; - WBUFB(buf,20+n*22)=sd->status.cart[index].attribute; - WBUFB(buf,21+n*22)=sd->status.cart[index].refine; - if(sd->status.cart[index].card[0]==0x00ff || sd->status.cart[index].card[0]==0x00fe || sd->status.cart[index].card[0]==(short)0xff00) { - WBUFW(buf,22+n*22)=sd->status.cart[index].card[0]; - WBUFW(buf,24+n*22)=sd->status.cart[index].card[1]; - WBUFW(buf,26+n*22)=sd->status.cart[index].card[2]; - WBUFW(buf,28+n*22)=sd->status.cart[index].card[3]; - } else { - if(sd->status.cart[index].card[0] > 0 && (j=itemdb_viewid(sd->status.cart[index].card[0])) > 0) - WBUFW(buf,22+n*22)= j; - else - WBUFW(buf,22+n*22)= sd->status.cart[index].card[0]; - if(sd->status.cart[index].card[1] > 0 && (j=itemdb_viewid(sd->status.cart[index].card[1])) > 0) - WBUFW(buf,24+n*22)= j; - else - WBUFW(buf,24+n*22)= sd->status.cart[index].card[1]; - if(sd->status.cart[index].card[2] > 0 && (j=itemdb_viewid(sd->status.cart[index].card[2])) > 0) - WBUFW(buf,26+n*22)= j; - else - WBUFW(buf,26+n*22)= sd->status.cart[index].card[2]; - if(sd->status.cart[index].card[3] > 0 && (j=itemdb_viewid(sd->status.cart[index].card[3])) > 0) - WBUFW(buf,28+n*22)= j; - else - WBUFW(buf,28+n*22)= sd->status.cart[index].card[3]; - } - n++; - } - if(n > 0){ - WBUFW(buf,2)=8+n*22; - WFIFOSET(fd,WFIFOW(fd,2)); - } - - return n; -} - -/*========================================== - * 露店アイテム販売報告 - *------------------------------------------ -*/ -int clif_vendingreport(struct map_session_data *sd,int index,int amount) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x137; - WFIFOW(fd,2)=index+2; - WFIFOW(fd,4)=amount; - WFIFOSET(fd,packet_len_table[0x137]); - - return 0; -} - -/*========================================== - * パーティ作成完了 - *------------------------------------------ - */ -int clif_party_created(struct map_session_data *sd,int flag) -{ - int fd; - - // printf("clif_party_message(%s, %d, %s)\n", p->name, account_id, mes); - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xfa; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0xfa]); - return 0; -} -/*========================================== - * パーティ情報送信 - *------------------------------------------ - */ -int clif_party_info(struct party *p,int fd) -{ - unsigned char buf[1024]; - int i,c; - struct map_session_data *sd=NULL; - - nullpo_retr(0, p); - - WBUFW(buf,0)=0xfb; - memcpy(WBUFP(buf,4),p->name,24); - for(i=c=0;i<MAX_PARTY;i++){ - struct party_member *m=&p->member[i]; - if(m->account_id>0){ - if(sd==NULL) sd=m->sd; - WBUFL(buf,28+c*46)=m->account_id; - memcpy(WBUFP(buf,28+c*46+ 4),m->name,24); - memcpy(WBUFP(buf,28+c*46+28),m->map,16); - WBUFB(buf,28+c*46+44)=(m->leader)?0:1; - WBUFB(buf,28+c*46+45)=(m->online)?0:1; - c++; - } - } - WBUFW(buf,2)=28+c*46; - if(fd>=0){ // fdが設定されてるならそれに送る - memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2)); - WFIFOSET(fd,WFIFOW(fd,2)); - return 9; - } - if(sd!=NULL) - clif_send(buf,WBUFW(buf,2),&sd->bl,PARTY); - return 0; -} -/*========================================== - * パーティ勧誘 - *------------------------------------------ - */ -int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd) -{ - int fd; - struct party *p; - - nullpo_retr(0, sd); - nullpo_retr(0, tsd); - - fd=tsd->fd; - - if( (p=party_search(sd->status.party_id))==NULL ) - return 0; - - WFIFOW(fd,0)=0xfe; - WFIFOL(fd,2)=sd->status.account_id; - memcpy(WFIFOP(fd,6),p->name,24); - WFIFOSET(fd,packet_len_table[0xfe]); - return 0; -} - -/*========================================== - * パーティ勧誘結果 - *------------------------------------------ - */ -int clif_party_inviteack(struct map_session_data *sd,char *nick,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xfd; - memcpy(WFIFOP(fd,2),nick,24); - WFIFOB(fd,26)=flag; - WFIFOSET(fd,packet_len_table[0xfd]); - return 0; -} - -/*========================================== - * パーティ設定送信 - * flag & 0x001=exp変更ミス - * 0x010=item変更ミス - * 0x100=一人にのみ送信 - *------------------------------------------ - */ -int clif_party_option(struct party *p,struct map_session_data *sd,int flag) -{ - unsigned char buf[16]; - - nullpo_retr(0, p); - -// if(battle_config.etc_log) -// printf("clif_party_option: %d %d %d\n",p->exp,p->item,flag); - if(sd==NULL && flag==0){ - int i; - for(i=0;i<MAX_PARTY;i++) - if((sd=map_id2sd(p->member[i].account_id))!=NULL) - break; - } - if(sd==NULL) - return 0; - WBUFW(buf,0)=0x101; - WBUFW(buf,2)=((flag&0x01)?2:p->exp); - WBUFW(buf,4)=((flag&0x10)?2:p->item); - if(flag==0) - clif_send(buf,packet_len_table[0x101],&sd->bl,PARTY); - else { - memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x101]); - WFIFOSET(sd->fd,packet_len_table[0x101]); - } - return 0; -} -/*========================================== - * パーティ脱退(脱退前に呼ぶこと) - *------------------------------------------ - */ -int clif_party_leaved(struct party *p,struct map_session_data *sd,int account_id,char *name,int flag) -{ - unsigned char buf[64]; - int i; - - nullpo_retr(0, p); - - WBUFW(buf,0)=0x105; - WBUFL(buf,2)=account_id; - memcpy(WBUFP(buf,6),name,24); - WBUFB(buf,30)=flag&0x0f; - - if((flag&0xf0)==0){ - if(sd==NULL) - for(i=0;i<MAX_PARTY;i++) - if((sd=p->member[i].sd)!=NULL) - break; - if (sd!=NULL) - clif_send(buf,packet_len_table[0x105],&sd->bl,PARTY); - } else if (sd!=NULL) { - memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x105]); - WFIFOSET(sd->fd,packet_len_table[0x105]); - } - return 0; -} -/*========================================== - * パーティメッセージ送信 - *------------------------------------------ - */ -int clif_party_message(struct party *p,int account_id,char *mes,int len) -{ - struct map_session_data *sd; - int i; - - nullpo_retr(0, p); - - for(i=0;i<MAX_PARTY;i++){ - if((sd=p->member[i].sd)!=NULL) - break; - } - if(sd!=NULL){ - unsigned char buf[1024]; - WBUFW(buf,0)=0x109; - WBUFW(buf,2)=len+8; - WBUFL(buf,4)=account_id; - memcpy(WBUFP(buf,8),mes,len); - clif_send(buf,len+8,&sd->bl,PARTY); - } - return 0; -} -/*========================================== - * パーティ座標通知 - *------------------------------------------ - */ -int clif_party_xy(struct party *p,struct map_session_data *sd) -{ - unsigned char buf[16]; - - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x107; - WBUFL(buf,2)=sd->status.account_id; - WBUFW(buf,6)=sd->bl.x; - WBUFW(buf,8)=sd->bl.y; - clif_send(buf,packet_len_table[0x107],&sd->bl,PARTY_SAMEMAP_WOS); -// if(battle_config.etc_log) -// printf("clif_party_xy %d\n",sd->status.account_id); - return 0; -} -/*========================================== - * パーティHP通知 - *------------------------------------------ - */ -int clif_party_hp(struct party *p,struct map_session_data *sd) -{ - unsigned char buf[16]; - - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x106; - WBUFL(buf,2)=sd->status.account_id; - WBUFW(buf,6)=(sd->status.hp > 0x7fff)? 0x7fff:sd->status.hp; - WBUFW(buf,8)=(sd->status.max_hp > 0x7fff)? 0x7fff:sd->status.max_hp; - clif_send(buf,packet_len_table[0x106],&sd->bl,PARTY_AREA_WOS); -// if(battle_config.etc_log) -// printf("clif_party_hp %d\n",sd->status.account_id); - return 0; -} -/*========================================== - * GMへ場所とHP通知 - *------------------------------------------ - */ -int clif_hpmeter(struct map_session_data *sd) -{ - struct map_session_data *md; - unsigned char buf[16]; - unsigned char buf2[16]; - int i; - - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x107; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=sd->bl.x; - WBUFW(buf,8)=sd->bl.y; - - for(i=0;i<fd_max;i++){ - if(session[i] && (md = (struct map_session_data*)session[i]->session_data) && md->state.auth && - md->bl.m == sd->bl.m && pc_isGM(md) && sd != md){ - memcpy(WFIFOP(i,0),buf,packet_len_table[0x107]); - WFIFOSET(i,packet_len_table[0x107]); - } - } - - WBUFW(buf2,0)=0x106; - WBUFL(buf2,2)=sd->status.account_id; - WBUFW(buf2,6)=(sd->status.hp > 0x7fff)? 0x7fff:sd->status.hp; - WBUFW(buf2,8)=(sd->status.max_hp > 0x7fff)? 0x7fff:sd->status.max_hp; - for(i=0;i<fd_max;i++){ - if(session[i] && (md = (struct map_session_data*)session[i]->session_data) && md->state.auth && - md->bl.m == sd->bl.m && pc_isGM(md) && sd != md){ - memcpy(WFIFOP(i,0),buf2,packet_len_table[0x106]); - WFIFOSET(i,packet_len_table[0x106]); - } - } - - return 0; -} -/*================================================== - * Update monster hp view if it has changed [Celest] - *-------------------------------------------------- - */ -int clif_update_mobhp(struct mob_data *md) -{ - unsigned char buf[102]; - char mobhp[50]; - - nullpo_retr(0, md); - - WBUFW(buf,0) = 0x95; - WBUFL(buf,2) = md->bl.id; - - memcpy(WBUFP(buf,6), md->name, 24); - sprintf(mobhp, "hp: %d/%d", md->hp, mob_db[md->class_].max_hp); - WBUFW(buf, 0) = 0x195; - memcpy(WBUFP(buf,30), mobhp, 24); - WBUFL(buf,54) = 0; - WBUFL(buf,78) = 0; - clif_send(buf,packet_len_table[0x195],&md->bl,AREA); - - return 0; -} -/*========================================== - * パーティ場所移動(未使用) - *------------------------------------------ - */ -int clif_party_move(struct party *p,struct map_session_data *sd,int online) -{ - unsigned char buf[128]; - - nullpo_retr(0, sd); - nullpo_retr(0, p); - - WBUFW(buf, 0)=0x104; - WBUFL(buf, 2)=sd->status.account_id; - WBUFL(buf, 6)=0; - WBUFW(buf,10)=sd->bl.x; - WBUFW(buf,12)=sd->bl.y; - WBUFB(buf,14)=!online; - memcpy(WBUFP(buf,15),p->name,24); - memcpy(WBUFP(buf,39),sd->status.name,24); - memcpy(WBUFP(buf,63),map[sd->bl.m].name,16); - clif_send(buf,packet_len_table[0x104],&sd->bl,PARTY); - return 0; -} -/*========================================== - * 攻撃するために移動が必要 - *------------------------------------------ - */ -int clif_movetoattack(struct map_session_data *sd,struct block_list *bl) -{ - int fd; - - nullpo_retr(0, sd); - nullpo_retr(0, bl); - - fd=sd->fd; - WFIFOW(fd, 0)=0x139; - WFIFOL(fd, 2)=bl->id; - WFIFOW(fd, 6)=bl->x; - WFIFOW(fd, 8)=bl->y; - WFIFOW(fd,10)=sd->bl.x; - WFIFOW(fd,12)=sd->bl.y; - WFIFOW(fd,14)=sd->attackrange; - WFIFOSET(fd,packet_len_table[0x139]); - return 0; -} -/*========================================== - * 製造エフェクト - *------------------------------------------ - */ -int clif_produceeffect(struct map_session_data *sd,int flag,int nameid) -{ - int view,fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - // 名前の登録と送信を先にしておく - if( map_charid2nick(sd->status.char_id)==NULL ) - map_addchariddb(sd->status.char_id,sd->status.name); - clif_solved_charname(sd,sd->status.char_id); - - WFIFOW(fd, 0)=0x18f; - WFIFOW(fd, 2)=flag; - if((view = itemdb_viewid(nameid)) > 0) - WFIFOW(fd, 4)=view; - else - WFIFOW(fd, 4)=nameid; - WFIFOSET(fd,packet_len_table[0x18f]); - return 0; -} - -// pet -int clif_catch_process(struct map_session_data *sd) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x19e; - WFIFOSET(fd,packet_len_table[0x19e]); - - return 0; -} - -int clif_pet_rulet(struct map_session_data *sd,int data) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1a0; - WFIFOB(fd,2)=data; - WFIFOSET(fd,packet_len_table[0x1a0]); - - return 0; -} - -/*========================================== - * pet卵リスト作成 - *------------------------------------------ - */ -int clif_sendegg(struct map_session_data *sd) -{ - //R 01a6 <len>.w <index>.w* - int i,n=0,fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1a6; - if(sd->status.pet_id <= 0) { - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || - sd->inventory_data[i]->type!=7 || - sd->status.inventory[i].amount<=0) - continue; - WFIFOW(fd,n*2+4)=i+2; - n++; - } - } - WFIFOW(fd,2)=4+n*2; - WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; -} - -int clif_send_petdata(struct map_session_data *sd,int type,int param) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1a4; - WFIFOB(fd,2)=type; - WFIFOL(fd,3)=sd->pd->bl.id; - WFIFOL(fd,7)=param; - WFIFOSET(fd,packet_len_table[0x1a4]); - - return 0; -} - -int clif_send_petstatus(struct map_session_data *sd) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1a2; - memcpy(WFIFOP(fd,2),sd->pet.name,24); - WFIFOB(fd,26)=(battle_config.pet_rename == 1)? 0:sd->pet.rename_flag; - WFIFOW(fd,27)=sd->pet.level; - WFIFOW(fd,29)=sd->pet.hungry; - WFIFOW(fd,31)=sd->pet.intimate; - WFIFOW(fd,33)=sd->pet.equip; - WFIFOSET(fd,packet_len_table[0x1a2]); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_pet_emotion(struct pet_data *pd,int param) -{ - unsigned char buf[16]; - struct map_session_data *sd; - - nullpo_retr(0, pd); - nullpo_retr(0, sd = pd->msd); - - memset(buf,0,packet_len_table[0x1aa]); - - WBUFW(buf,0)=0x1aa; - WBUFL(buf,2)=pd->bl.id; - if(param >= 100 && sd->petDB->talk_convert_class) { - if(sd->petDB->talk_convert_class < 0) - return 0; - else if(sd->petDB->talk_convert_class > 0) { - param -= (pd->class_ - 100)*100; - param += (sd->petDB->talk_convert_class - 100)*100; - } - } - WBUFL(buf,6)=param; - - clif_send(buf,packet_len_table[0x1aa],&pd->bl,AREA); - - return 0; -} - -int clif_pet_performance(struct block_list *bl,int param) -{ - unsigned char buf[16]; - - nullpo_retr(0, bl); - - memset(buf,0,packet_len_table[0x1a4]); - - WBUFW(buf,0)=0x1a4; - WBUFB(buf,2)=4; - WBUFL(buf,3)=bl->id; - WBUFL(buf,7)=param; - - clif_send(buf,packet_len_table[0x1a4],bl,AREA); - - return 0; -} - -int clif_pet_equip(struct pet_data *pd,int nameid) -{ - unsigned char buf[16]; - int view; - - nullpo_retr(0, pd); - - memset(buf,0,packet_len_table[0x1a4]); - - WBUFW(buf,0)=0x1a4; - WBUFB(buf,2)=3; - WBUFL(buf,3)=pd->bl.id; - if((view = itemdb_viewid(nameid)) > 0) - WBUFL(buf,7)=view; - else - WBUFL(buf,7)=nameid; - - clif_send(buf,packet_len_table[0x1a4],&pd->bl,AREA); - - return 0; -} - -int clif_pet_food(struct map_session_data *sd,int foodid,int fail) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1a3; - WFIFOB(fd,2)=fail; - WFIFOW(fd,3)=foodid; - WFIFOSET(fd,packet_len_table[0x1a3]); - - return 0; -} - -/*========================================== - * オートスペル リスト送信 - *------------------------------------------ - */ -int clif_autospell(struct map_session_data *sd,int skilllv) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd, 0)=0x1cd; - - if(skilllv>0 && pc_checkskill(sd,MG_NAPALMBEAT)>0) - WFIFOL(fd,2)= MG_NAPALMBEAT; - else - WFIFOL(fd,2)= 0x00000000; - if(skilllv>1 && pc_checkskill(sd,MG_COLDBOLT)>0) - WFIFOL(fd,6)= MG_COLDBOLT; - else - WFIFOL(fd,6)= 0x00000000; - if(skilllv>1 && pc_checkskill(sd,MG_FIREBOLT)>0) - WFIFOL(fd,10)= MG_FIREBOLT; - else - WFIFOL(fd,10)= 0x00000000; - if(skilllv>1 && pc_checkskill(sd,MG_LIGHTNINGBOLT)>0) - WFIFOL(fd,14)= MG_LIGHTNINGBOLT; - else - WFIFOL(fd,14)= 0x00000000; - if(skilllv>4 && pc_checkskill(sd,MG_SOULSTRIKE)>0) - WFIFOL(fd,18)= MG_SOULSTRIKE; - else - WFIFOL(fd,18)= 0x00000000; - if(skilllv>7 && pc_checkskill(sd,MG_FIREBALL)>0) - WFIFOL(fd,22)= MG_FIREBALL; - else - WFIFOL(fd,22)= 0x00000000; - if(skilllv>9 && pc_checkskill(sd,MG_FROSTDIVER)>0) - WFIFOL(fd,26)= MG_FROSTDIVER; - else - WFIFOL(fd,26)= 0x00000000; - - WFIFOSET(fd,packet_len_table[0x1cd]); - return 0; -} - -/*========================================== - * ディボーションの青い糸 - *------------------------------------------ - */ -int clif_devotion(struct map_session_data *sd,int target) -{ - unsigned char buf[56]; - int n; - - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x1cf; - WBUFL(buf,2)=sd->bl.id; -// WBUFL(buf,6)=target; - for(n=0;n<5;n++) - WBUFL(buf,6+4*n)=sd->dev.val2[n]; -// WBUFL(buf,10+4*n)=0; - WBUFB(buf,26)=8; - WBUFB(buf,27)=0; - - clif_send(buf,packet_len_table[0x1cf],&sd->bl,AREA); - return 0; -} - -/*========================================== - * 氣球 - *------------------------------------------ - */ -int clif_spiritball(struct map_session_data *sd) -{ - unsigned char buf[16]; - - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x1d0; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=sd->spiritball; - clif_send(buf,packet_len_table[0x1d0],&sd->bl,AREA); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_combo_delay(struct block_list *bl,int wait) -{ - unsigned char buf[32]; - - nullpo_retr(0, bl); - - WBUFW(buf,0)=0x1d2; - WBUFL(buf,2)=bl->id; - WBUFL(buf,6)=wait; - clif_send(buf,packet_len_table[0x1d2],bl,AREA); - - return 0; -} -/*========================================== - *白刃取り - *------------------------------------------ - */ -int clif_bladestop(struct block_list *src,struct block_list *dst, - int _bool) -{ - unsigned char buf[32]; - - nullpo_retr(0, src); - nullpo_retr(0, dst); - - WBUFW(buf,0)=0x1d1; - WBUFL(buf,2)=src->id; - WBUFL(buf,6)=dst->id; - WBUFL(buf,10)=_bool; - - clif_send(buf,packet_len_table[0x1d1],src,AREA); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_changemapcell(int m,int x,int y,int cell_type,int type) -{ - struct block_list bl; - unsigned char buf[32]; - - bl.m = m; - bl.x = x; - bl.y = y; - WBUFW(buf,0) = 0x192; - WBUFW(buf,2) = x; - WBUFW(buf,4) = y; - WBUFW(buf,6) = cell_type; - memcpy(WBUFP(buf,8),map[m].name,16); - if(!type) - clif_send(buf,packet_len_table[0x192],&bl,AREA); - else - clif_send(buf,packet_len_table[0x192],&bl,ALL_SAMEMAP); - - return 0; -} - -/*========================================== - * MVPエフェクト - *------------------------------------------ - */ -int clif_mvp_effect(struct map_session_data *sd) -{ - unsigned char buf[16]; - - nullpo_retr(0, sd); - - WBUFW(buf,0)=0x10c; - WBUFL(buf,2)=sd->bl.id; - clif_send(buf,packet_len_table[0x10c],&sd->bl,AREA); - return 0; -} -/*========================================== - * MVPアイテム所得 - *------------------------------------------ - */ -int clif_mvp_item(struct map_session_data *sd,int nameid) -{ - int view,fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x10a; - if((view = itemdb_viewid(nameid)) > 0) - WFIFOW(fd,2)=view; - else - WFIFOW(fd,2)=nameid; - WFIFOSET(fd,packet_len_table[0x10a]); - return 0; -} -/*========================================== - * MVP経験値所得 - *------------------------------------------ - */ -int clif_mvp_exp(struct map_session_data *sd,int exp) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x10b; - WFIFOL(fd,2)=exp; - WFIFOSET(fd,packet_len_table[0x10b]); - return 0; -} - -/*========================================== - * ギルド作成可否通知 - *------------------------------------------ - */ -int clif_guild_created(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x167; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x167]); - return 0; -} -/*========================================== - * ギルド所属通知 - *------------------------------------------ - */ -int clif_guild_belonginfo(struct map_session_data *sd,struct guild *g) -{ - int ps,fd; - - nullpo_retr(0, sd); - nullpo_retr(0, g); - - fd=sd->fd; - ps=guild_getposition(sd,g); - - memset(WFIFOP(fd,0),0,packet_len_table[0x16c]); - WFIFOW(fd,0)=0x16c; - WFIFOL(fd,2)=g->guild_id; - WFIFOL(fd,6)=g->emblem_id; - WFIFOL(fd,10)=g->position[ps].mode; - memcpy(WFIFOP(fd,19),g->name,24); - WFIFOSET(fd,packet_len_table[0x16c]); - return 0; -} -/*========================================== - * ギルドメンバログイン通知 - *------------------------------------------ - */ -int clif_guild_memberlogin_notice(struct guild *g,int idx,int flag) -{ - unsigned char buf[64]; - - nullpo_retr(0, g); - - // printf("clif_guild_message(%s, %d, %s)\n", g->name, account_id, mes); - - WBUFW(buf, 0)=0x16d; - WBUFL(buf, 2)=g->member[idx].account_id; - WBUFL(buf, 6)=g->member[idx].char_id; - WBUFL(buf,10)=flag; - if(g->member[idx].sd==NULL){ - struct map_session_data *sd=guild_getavailablesd(g); - if(sd!=NULL) - clif_send(buf,packet_len_table[0x16d],&sd->bl,GUILD); - }else - clif_send(buf,packet_len_table[0x16d],&g->member[idx].sd->bl,GUILD_WOS); - return 0; -} -/*========================================== - * ギルドマスター通知(14dへの応答) - *------------------------------------------ - */ -int clif_guild_masterormember(struct map_session_data *sd) -{ - int type=0x57,fd; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g!=NULL && strcmp(g->master,sd->status.name)==0) - type=0xd7; - WFIFOW(fd,0)=0x14e; - WFIFOL(fd,2)=type; - WFIFOSET(fd,packet_len_table[0x14e]); - return 0; -} -/*========================================== - * Basic Info (Territories [Valaris]) - *------------------------------------------ - */ -int clif_guild_basicinfo(struct map_session_data *sd) -{ - int fd,i,t=0; - struct guild *g; - struct guild_castle *gc=NULL; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - - WFIFOW(fd, 0)=0x1b6;//0x150; - WFIFOL(fd, 2)=g->guild_id; - WFIFOL(fd, 6)=g->guild_lv; - WFIFOL(fd,10)=g->connect_member; - WFIFOL(fd,14)=g->max_member; - WFIFOL(fd,18)=g->average_lv; - WFIFOL(fd,22)=g->exp; - WFIFOL(fd,26)=g->next_exp; - WFIFOL(fd,30)=0; // 上納 - WFIFOL(fd,34)=0; // VW(性格の悪さ?:性向グラフ左右) - WFIFOL(fd,38)=0; // RF(正義の度合い?:性向グラフ上下) - WFIFOL(fd,42)=0; // 人数? - memcpy(WFIFOP(fd,46),g->name,24); - memcpy(WFIFOP(fd,70),g->master,24); - - for(i=0;i<MAX_GUILDCASTLE;i++){ - gc=guild_castle_search(i); - if(!gc) continue; - if(g->guild_id == gc->guild_id) t++; - } - - if (t==1) strncpy((char*)WFIFOP(fd,94),"One Castle",20); - else if (t==2) strncpy((char*)WFIFOP(fd,94),"Two Castles",20); - else if (t==3) strncpy((char*)WFIFOP(fd,94),"Three Castles",20); - else if (t==4) strncpy((char*)WFIFOP(fd,94),"Four Castles",20); - else if (t==5) strncpy((char*)WFIFOP(fd,94),"Five Castles",20); - else if (t==6) strncpy((char*)WFIFOP(fd,94),"Six Castles",20); - else if (t==7) strncpy((char*)WFIFOP(fd,94),"Seven Castles",20); - else if (t==8) strncpy((char*)WFIFOP(fd,94),"Eight Castles",20); - else if (t==9) strncpy((char*)WFIFOP(fd,94),"Nine Castles",20); - else if (t==10) strncpy((char*)WFIFOP(fd,94),"Ten Castles",20); - else if (t==11) strncpy((char*)WFIFOP(fd,94),"Eleven Castles",20); - else if (t==12) strncpy((char*)WFIFOP(fd,94),"Twelve Castles",20); - else if (t==13) strncpy((char*)WFIFOP(fd,94),"Thirteen Castles",20); - else if (t==14) strncpy((char*)WFIFOP(fd,94),"Fourteen Castles",20); - else if (t==15) strncpy((char*)WFIFOP(fd,94),"Fifteen Castles",20); - else if (t==16) strncpy((char*)WFIFOP(fd,94),"Sixteen Castles",20); - else if (t==17) strncpy((char*)WFIFOP(fd,94),"Seventeen Castles",20); - else if (t==18) strncpy((char*)WFIFOP(fd,94),"Eighteen Castles",20); - else if (t==19) strncpy((char*)WFIFOP(fd,94),"Nineteen Castles",20); - else if (t==20) strncpy((char*)WFIFOP(fd,94),"Twenty Castles",20); - else if (t==21) strncpy((char*)WFIFOP(fd,94),"Twenty One Castles",20); - else if (t==22) strncpy((char*)WFIFOP(fd,94),"Twenty Two Castles",20); - else if (t==23) strncpy((char*)WFIFOP(fd,94),"Twenty Three Castles",20); - else if (t==24) strncpy((char*)WFIFOP(fd,94),"Twenty Four Castles",20); - else if (t==MAX_GUILDCASTLE) strncpy((char*)WFIFOP(fd,94),"Total Domination",20); - else strncpy((char*)WFIFOP(fd,94),"None Taken",20); - - WFIFOSET(fd,packet_len_table[WFIFOW(fd,0)]); - clif_guild_emblem(sd,g); // Guild emblem vanish fix [Valaris] - return 0; -} - -/*========================================== - * ギルド同盟/敵対情報 - *------------------------------------------ - */ -int clif_guild_allianceinfo(struct map_session_data *sd) -{ - int fd,i,c; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - WFIFOW(fd, 0)=0x14c; - for(i=c=0;i<MAX_GUILDALLIANCE;i++){ - struct guild_alliance *a=&g->alliance[i]; - if(a->guild_id>0){ - WFIFOL(fd,c*32+4)=a->opposition; - WFIFOL(fd,c*32+8)=a->guild_id; - memcpy(WFIFOP(fd,c*32+12),a->name,24); - c++; - } - } - WFIFOW(fd, 2)=c*32+4; - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} - -/*========================================== - * ギルドメンバーリスト - *------------------------------------------ - */ -int clif_guild_memberlist(struct map_session_data *sd) -{ - int fd; - int i,c; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - - WFIFOW(fd, 0)=0x154; - for(i=0,c=0;i<g->max_member;i++){ - struct guild_member *m=&g->member[i]; - if(m->account_id==0) - continue; - WFIFOL(fd,c*104+ 4)=m->account_id; - WFIFOL(fd,c*104+ 8)=m->char_id; - WFIFOW(fd,c*104+12)=m->hair; - WFIFOW(fd,c*104+14)=m->hair_color; - WFIFOW(fd,c*104+16)=m->gender; - WFIFOW(fd,c*104+18)=m->class_; - WFIFOW(fd,c*104+20)=m->lv; - WFIFOL(fd,c*104+22)=m->exp; - WFIFOL(fd,c*104+26)=m->online; - WFIFOL(fd,c*104+30)=m->position; - memset(WFIFOP(fd,c*104+34),0,50); // メモ? - memcpy(WFIFOP(fd,c*104+84),m->name,24); - c++; - } - WFIFOW(fd, 2)=c*104+4; - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} -/*========================================== - * ギルド役職名リスト - *------------------------------------------ - */ -int clif_guild_positionnamelist(struct map_session_data *sd) -{ - int i,fd; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - WFIFOW(fd, 0)=0x166; - for(i=0;i<MAX_GUILDPOSITION;i++){ - WFIFOL(fd,i*28+4)=i; - memcpy(WFIFOP(fd,i*28+8),g->position[i].name,24); - } - WFIFOW(fd,2)=i*28+4; - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} -/*========================================== - * ギルド役職情報リスト - *------------------------------------------ - */ -int clif_guild_positioninfolist(struct map_session_data *sd) -{ - int i,fd; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - WFIFOW(fd, 0)=0x160; - for(i=0;i<MAX_GUILDPOSITION;i++){ - struct guild_position *p=&g->position[i]; - WFIFOL(fd,i*16+ 4)=i; - WFIFOL(fd,i*16+ 8)=p->mode; - WFIFOL(fd,i*16+12)=i; - WFIFOL(fd,i*16+16)=p->exp_mode; - } - WFIFOW(fd, 2)=i*16+4; - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} -/*========================================== - * ギルド役職変更通知 - *------------------------------------------ - */ -int clif_guild_positionchanged(struct guild *g,int idx) -{ - struct map_session_data *sd; - unsigned char buf[128]; - - nullpo_retr(0, g); - - WBUFW(buf, 0)=0x174; - WBUFW(buf, 2)=44; - WBUFL(buf, 4)=idx; - WBUFL(buf, 8)=g->position[idx].mode; - WBUFL(buf,12)=idx; - WBUFL(buf,16)=g->position[idx].exp_mode; - memcpy(WBUFP(buf,20),g->position[idx].name,24); - if( (sd=guild_getavailablesd(g))!=NULL ) - clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD); - return 0; -} -/*========================================== - * ギルドメンバ変更通知 - *------------------------------------------ - */ -int clif_guild_memberpositionchanged(struct guild *g,int idx) -{ - struct map_session_data *sd; - unsigned char buf[64]; - - nullpo_retr(0, g); - - WBUFW(buf, 0)=0x156; - WBUFW(buf, 2)=16; - WBUFL(buf, 4)=g->member[idx].account_id; - WBUFL(buf, 8)=g->member[idx].char_id; - WBUFL(buf,12)=g->member[idx].position; - if( (sd=guild_getavailablesd(g))!=NULL ) - clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD); - return 0; -} -/*========================================== - * ギルドエンブレム送信 - *------------------------------------------ - */ -int clif_guild_emblem(struct map_session_data *sd,struct guild *g) -{ - int fd; - - nullpo_retr(0, sd); - nullpo_retr(0, g); - - fd=sd->fd; - - if(g->emblem_len<=0) - return 0; - WFIFOW(fd,0)=0x152; - WFIFOW(fd,2)=g->emblem_len+12; - WFIFOL(fd,4)=g->guild_id; - WFIFOL(fd,8)=g->emblem_id; - memcpy(WFIFOP(fd,12),g->emblem_data,g->emblem_len); - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} -/*========================================== - * ギルドスキル送信 - *------------------------------------------ - */ -int clif_guild_skillinfo(struct map_session_data *sd) -{ - int fd; - int i,id,c,up=1; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - WFIFOW(fd,0)=0x0162; - WFIFOW(fd,4)=g->skill_point; - for(i=c=0;i<MAX_GUILDSKILL;i++){ - if(g->skill[i].id>0){ - WFIFOW(fd,c*37+ 6) = id = g->skill[i].id; - WFIFOW(fd,c*37+ 8) = guild_skill_get_inf(id); - WFIFOW(fd,c*37+10) = 0; - WFIFOW(fd,c*37+12) = g->skill[i].lv; - WFIFOW(fd,c*37+14) = guild_skill_get_sp(id,g->skill[i].lv); - WFIFOW(fd,c*37+16) = guild_skill_get_range(id); - memset(WFIFOP(fd,c*37+18),0,24); - if(g->skill[i].lv < guild_skill_get_max(id)) { - //Kafra and Guardian changed to require Approval [Sara] - switch (g->skill[i].id) - { - case GD_KAFRACONTACT: - case GD_GUARDIANRESEARCH: - case GD_GUARDUP: - case GD_DEVELOPMENT: - up = guild_checkskill(g,GD_APPROVAL) > 0; - break; - case GD_LEADERSHIP: - //Glory skill requirements -- Pretty sure correct [Sara] - up = (battle_config.require_glory_guild) ? - guild_checkskill(g,GD_GLORYGUILD) > 0 : 1; - // what skill does it need now that glory guild was removed? [celest] - break; - case GD_GLORYWOUNDS: - up = (battle_config.require_glory_guild) ? - guild_checkskill(g,GD_GLORYGUILD) > 0 : 1; - break; - case GD_SOULCOLD: - up = guild_checkskill(g,GD_GLORYWOUNDS) > 0; - break; - case GD_HAWKEYES: - up = guild_checkskill(g,GD_LEADERSHIP) > 0; - break; - case GD_BATTLEORDER: - up = guild_checkskill(g,GD_APPROVAL) > 0 && - guild_checkskill(g,GD_EXTENSION) >= 2; - break; - case GD_REGENERATION: - up = guild_checkskill(g,GD_EXTENSION) >= 5 && - guild_checkskill(g,GD_BATTLEORDER) > 0; - break; - case GD_RESTORE: - up = guild_checkskill(g,GD_REGENERATION) >= 2; - break; - case GD_EMERGENCYCALL: - up = guild_checkskill(g,GD_GUARDIANRESEARCH) > 0 && - guild_checkskill(g,GD_REGENERATION) > 0; - break; - case GD_GLORYGUILD: - up = (battle_config.require_glory_guild) ? 1 : 0; - break; - default: - up = 1; - } - } - else { - up = 0; - } - WFIFOB(fd,c*37+42)= up; - c++; - } - } - WFIFOW(fd,2)=c*37+6; - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} -/*========================================== - * ギルド告知送信 - *------------------------------------------ - */ -int clif_guild_notice(struct map_session_data *sd,struct guild *g) -{ - int fd; - - nullpo_retr(0, sd); - nullpo_retr(0, g); - - fd=sd->fd; - if(*g->mes1==0 && *g->mes2==0) - return 0; - WFIFOW(fd,0)=0x16f; - memcpy(WFIFOP(fd,2),g->mes1,60); - memcpy(WFIFOP(fd,62),g->mes2,120); - WFIFOSET(fd,packet_len_table[0x16f]); - return 0; -} - -/*========================================== - * ギルドメンバ勧誘 - *------------------------------------------ - */ -int clif_guild_invite(struct map_session_data *sd,struct guild *g) -{ - int fd; - - nullpo_retr(0, sd); - nullpo_retr(0, g); - - fd=sd->fd; - WFIFOW(fd,0)=0x16a; - WFIFOL(fd,2)=g->guild_id; - memcpy(WFIFOP(fd,6),g->name,24); - WFIFOSET(fd,packet_len_table[0x16a]); - return 0; -} -/*========================================== - * ギルドメンバ勧誘結果 - *------------------------------------------ - */ -int clif_guild_inviteack(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x169; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x169]); - return 0; -} -/*========================================== - * ギルドメンバ脱退通知 - *------------------------------------------ - */ -int clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes) -{ - unsigned char buf[128]; - - nullpo_retr(0, sd); - - WBUFW(buf, 0)=0x15a; - memcpy(WBUFP(buf, 2),name,24); - memcpy(WBUFP(buf,26),mes,40); - clif_send(buf,packet_len_table[0x15a],&sd->bl,GUILD); - return 0; -} -/*========================================== - * ギルドメンバ追放通知 - *------------------------------------------ - */ -int clif_guild_explusion(struct map_session_data *sd,const char *name,const char *mes, - int account_id) -{ - unsigned char buf[128]; - - nullpo_retr(0, sd); - - WBUFW(buf, 0)=0x15c; - memcpy(WBUFP(buf, 2),name,24); - memcpy(WBUFP(buf,26),mes,40); - memcpy(WBUFP(buf,66),"dummy",24); - clif_send(buf,packet_len_table[0x15c],&sd->bl,GUILD); - return 0; -} -/*========================================== - * ギルド追放メンバリスト - *------------------------------------------ - */ -int clif_guild_explusionlist(struct map_session_data *sd) -{ - int fd; - int i,c; - struct guild *g; - - nullpo_retr(0, sd); - - fd=sd->fd; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - WFIFOW(fd,0)=0x163; - for(i=c=0;i<MAX_GUILDEXPLUSION;i++){ - struct guild_explusion *e=&g->explusion[i]; - if(e->account_id>0){ - memcpy(WFIFOP(fd,c*88+ 4),e->name,24); - memcpy(WFIFOP(fd,c*88+28),e->acc,24); - memcpy(WFIFOP(fd,c*88+52),e->mes,44); - c++; - } - } - WFIFOW(fd,2)=c*88+4; - WFIFOSET(fd,WFIFOW(fd,2)); - return 0; -} - -/*========================================== - * ギルド会話 - *------------------------------------------ - */ -int clif_guild_message(struct guild *g,int account_id,const char *mes,int len) -{ - struct map_session_data *sd; - unsigned char *buf; - - buf = (unsigned char*)aCallocA(len + 4, sizeof(unsigned char)); - - WBUFW(buf, 0) = 0x17f; - WBUFW(buf, 2) = len + 4; - memcpy(WBUFP(buf,4), mes, len); - - if ((sd = guild_getavailablesd(g)) != NULL) - clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD); - - if(buf) aFree(buf); - - return 0; -} -/*========================================== - * ギルドスキル割り振り通知 - *------------------------------------------ - */ -int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0) = 0x10e; - WFIFOW(fd,2) = skill_num; - WFIFOW(fd,4) = lv; - WFIFOW(fd,6) = guild_skill_get_sp(skill_num,lv); - WFIFOW(fd,8) = guild_skill_get_range(skill_num); - WFIFOB(fd,10) = 1; - WFIFOSET(fd,11); - return 0; -} -/*========================================== - * ギルド同盟要請 - *------------------------------------------ - */ -int clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x171; - WFIFOL(fd,2)=account_id; - memcpy(WFIFOP(fd,6),name,24); - WFIFOSET(fd,packet_len_table[0x171]); - return 0; -} -/*========================================== - * ギルド同盟結果 - *------------------------------------------ - */ -int clif_guild_allianceack(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x173; - WFIFOL(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x173]); - return 0; -} -/*========================================== - * ギルド関係解消通知 - *------------------------------------------ - */ -int clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x184; - WFIFOL(fd,2)=guild_id; - WFIFOL(fd,6)=flag; - WFIFOSET(fd,packet_len_table[0x184]); - return 0; -} -/*========================================== - * ギルド敵対結果 - *------------------------------------------ - */ -int clif_guild_oppositionack(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x181; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x181]); - return 0; -} -/*========================================== - * ギルド関係追加 - *------------------------------------------ - */ -/*int clif_guild_allianceadded(struct guild *g,int idx) -{ - unsigned char buf[64]; - WBUFW(fd,0)=0x185; - WBUFL(fd,2)=g->alliance[idx].opposition; - WBUFL(fd,6)=g->alliance[idx].guild_id; - memcpy(WBUFP(fd,10),g->alliance[idx].name,24); - clif_send(buf,packet_len_table[0x185],guild_getavailablesd(g),GUILD); - return 0; -}*/ - -/*========================================== - * ギルド解散通知 - *------------------------------------------ - */ -int clif_guild_broken(struct map_session_data *sd,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x15e; - WFIFOL(fd,2)=flag; - WFIFOSET(fd,packet_len_table[0x15e]); - return 0; -} - -/*========================================== - * エモーション - *------------------------------------------ - */ -void clif_emotion(struct block_list *bl,int type) -{ - unsigned char buf[8]; - - nullpo_retv(bl); - - WBUFW(buf,0)=0xc0; - WBUFL(buf,2)=bl->id; - WBUFB(buf,6)=type; - clif_send(buf,packet_len_table[0xc0],bl,AREA); -} - -/*========================================== - * トーキーボックス - *------------------------------------------ - */ -void clif_talkiebox(struct block_list *bl,char* talkie) -{ - unsigned char buf[86]; - - nullpo_retv(bl); - - WBUFW(buf,0)=0x191; - WBUFL(buf,2)=bl->id; - memcpy(WBUFP(buf,6),talkie,80); - clif_send(buf,packet_len_table[0x191],bl,AREA); -} - -/*========================================== - * 結婚エフェクト - *------------------------------------------ - */ -void clif_wedding_effect(struct block_list *bl) { - unsigned char buf[6]; - - nullpo_retv(bl); - - WBUFW(buf,0) = 0x1ea; - WBUFL(buf,2) = bl->id; - clif_send(buf, packet_len_table[0x1ea], bl, AREA); -} -/*========================================== - * あなたに逢いたい使用時名前叫び - *------------------------------------------ - -void clif_callpartner(struct map_session_data *sd) -{ - unsigned char buf[26]; - char *p; - - nullpo_retv(sd); - - if(sd->status.partner_id){ - WBUFW(buf,0)=0x1e6; - p = map_charid2nick(sd->status.partner_id); - if(p){ - memcpy(WBUFP(buf,2),p,24); - }else{ - map_reqchariddb(sd,sd->status.partner_id); - chrif_searchcharid(sd->status.partner_id); - WBUFB(buf,2) = 0; - } - clif_send(buf,packet_len_table[0x1e6]&sd->bl,AREA); - } - return; -} -*/ -/*========================================== - * Adopt baby [Celest] - *------------------------------------------ - */ -void clif_adopt_process(struct map_session_data *sd) -{ - int fd; - nullpo_retv(sd); - - fd=sd->fd; - WFIFOW(fd,0)=0x1f8; - WFIFOSET(fd,packet_len_table[0x1f8]); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ReqAdopt(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - printf ("%d\n", RFIFOL(fd,2)); -} - -/*========================================== - * 座る - *------------------------------------------ - */ -void clif_sitting(struct map_session_data *sd) -{ - unsigned char buf[64]; - - nullpo_retv(sd); - - WBUFW(buf, 0) = 0x8a; - WBUFL(buf, 2) = sd->bl.id; - WBUFB(buf,26) = 2; - clif_send(buf, packet_len_table[0x8a], &sd->bl, AREA); -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len) -{ - unsigned char *buf; - - nullpo_retr(0, sd); - - buf = (unsigned char*)aCallocA(len + 8, sizeof(unsigned char)); - - WBUFW(buf, 0) = 0x17f; - WBUFW(buf, 2) = len + 8; - memcpy(WBUFP(buf,4), mes, len + 4); - - clif_send(buf, WBUFW(buf,2), &sd->bl, SELF); - - if(buf) aFree(buf); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ - -int clif_GM_kickack(struct map_session_data *sd, int id) -{ - int fd; - - nullpo_retr(0, sd); - - fd = sd->fd; - WFIFOW(fd,0) = 0xcd; - WFIFOL(fd,2) = id; - WFIFOSET(fd, packet_len_table[0xcd]); - return 0; -} - -void clif_parse_QuitGame(int fd,struct map_session_data *sd); - -int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type) -{ - nullpo_retr(0, tsd); - - if(type) - clif_GM_kickack(sd,tsd->status.account_id); - tsd->opt1 = tsd->opt2 = 0; - WFIFOW(tsd->fd,0) = 0x18b; - WFIFOW(tsd->fd,2) = 0; - WFIFOSET(tsd->fd,packet_len_table[0x18b]); - clif_setwaitclose(tsd->fd); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ - -int clif_timedout(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - sprintf(tmp_output,"%sCharacter with Account ID '"CL_WHITE"%d"CL_RESET"' timed out.\n", (pc_isGM(sd))?"GM ":"", sd->bl.id); - ShowInfo(tmp_output); - map_quit(sd); - clif_authfail_fd(sd->fd,3); // Even if player is not on we still send anyway - clif_setwaitclose(sd->fd); // Set session to EOF - - return 0; -} - -/*========================================== - * Wis拒否許可応答 - *------------------------------------------ - */ -int clif_wisexin(struct map_session_data *sd,int type,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xd1; - WFIFOB(fd,2)=type; - WFIFOB(fd,3)=flag; - WFIFOSET(fd,packet_len_table[0xd1]); - - return 0; -} -/*========================================== - * Wis全拒否許可応答 - *------------------------------------------ - */ -int clif_wisall(struct map_session_data *sd,int type,int flag) -{ - int fd; - - nullpo_retr(0, sd); - - fd=sd->fd; - WFIFOW(fd,0)=0xd2; - WFIFOB(fd,2)=type; - WFIFOB(fd,3)=flag; - WFIFOSET(fd,packet_len_table[0xd2]); - - return 0; -} -/*========================================== - * サウンドエフェクト - *------------------------------------------ - */ -void clif_soundeffect(struct map_session_data *sd,struct block_list *bl,char *name,int type) -{ - int fd; - - nullpo_retv(sd); - nullpo_retv(bl); - - fd=sd->fd; - WFIFOW(fd,0)=0x1d3; - memcpy(WFIFOP(fd,2),name,24); - WFIFOB(fd,26)=type; - WFIFOL(fd,27)=0; - WFIFOL(fd,31)=bl->id; - WFIFOSET(fd,packet_len_table[0x1d3]); - - return; -} - -int clif_soundeffectall(struct block_list *bl, char *name, int type) -{ - unsigned char buf[31]; - memset(buf, 0, packet_len_table[0x1d3]); - - nullpo_retr(0, bl); - - WBUFW(buf,0)=0x1d3; - memcpy(WBUFP(buf,2), name, 24); - WBUFB(buf,26)=type; - WBUFL(buf,27)=0; - WBUFL(buf,31)=bl->id; - clif_send(buf, packet_len_table[0x1d3], bl, AREA); - - return 0; -} - -// displaying special effects (npcs, weather, etc) [Valaris] -int clif_specialeffect(struct block_list *bl, int type, int flag) { - unsigned char buf[24]; - - nullpo_retr(0, bl); - - memset(buf, 0, packet_len_table[0x1f3]); - - WBUFW(buf,0) = 0x1f3; - WBUFL(buf,2) = bl->id; - WBUFL(buf,6) = type; - - if (flag == 3) { -// struct map_session_data *sd; - struct map_session_data *pl_sd; - int i; - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data*)session[i]->session_data) != NULL && - pl_sd->state.auth && - (pc_isGM((struct map_session_data *)&bl) > pc_isGM((struct map_session_data *)&pl_sd->bl))) - clif_specialeffect(&pl_sd->bl, type, 1); - } - } - if (flag == 2) { - struct map_session_data *sd; - int i; - for(i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == bl->m) - clif_specialeffect(&sd->bl, type, 1); - } - } - - else if (flag == 1) - clif_send(buf, packet_len_table[0x1f3], bl, SELF); - else if (!flag) - clif_send(buf, packet_len_table[0x1f3], bl, AREA); - - return 0; - -} - -// refresh the client's screen, getting rid of any effects -int clif_refresh(struct map_session_data *sd) { - nullpo_retr(-1, sd); - clif_changemap(sd,sd->mapname,sd->bl.x,sd->bl.y); - return 0; -} - -// ------------ -// clif_parse_* -// ------------ -// パケット読み取って色々操作 -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_WantToConnection(int fd, struct map_session_data *sd) -{ - struct map_session_data *old_sd; - int cmd, account_id; // account_id in the packet 0x72 or 0x7E - - if (sd) { - if (battle_config.error_log) - printf("clif_parse_WantToConnection : invalid request?\n"); - return; - } - - cmd = RFIFOW(fd,0); - - // packet DB - if (IS_PACKET_DB_VER(cmd)) { - //printf("Received bytes %d with packet 0x72.\n", RFIFOREST(fd)); - account_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[0]); - // 0x72 - } else if (cmd == 0x72) { - //printf("Received bytes %d with packet 0x72.\n", RFIFOREST(fd)); - if (RFIFOREST(fd) >= 39 && (RFIFOB(fd,38) == 0 || RFIFOB(fd,38) == 1)) // 00 = Female, 01 = Male - account_id = RFIFOL(fd,12); - else if (RFIFOREST(fd) >= 22 && (RFIFOB(fd,21) == 0 || RFIFOB(fd,21) == 1)) // 00 = Female, 01 = Male - account_id = RFIFOL(fd,5); - else // old packet version - account_id = RFIFOL(fd,2); - // 0x7E - } else if (cmd == 0x7E) { - //printf("Received bytes %d with packet 0x7E.\n", RFIFOREST(fd)); - if (RFIFOREST(fd) >= 37 && (RFIFOB(fd,36) == 0 || RFIFOB(fd,36) == 1)) // 00 = Female, 01 = Male - account_id = RFIFOL(fd,9); - else - account_id = RFIFOL(fd,12); - // 0xF5 - } else if (cmd == 0xF5) { - //printf("Received bytes %d with packet 0xF5.\n", RFIFOREST(fd)); - if (RFIFOREST(fd) >= 34 && (RFIFOB(fd,33) == 0 || RFIFOB(fd,33) == 1)) // 00 = Female, 01 = Male - account_id = RFIFOL(fd,7); - else if (RFIFOREST(fd) >= 33 && (RFIFOB(fd,32) == 0 || RFIFOB(fd,32) == 1)) // 00 = Female, 01 = Male - account_id = RFIFOL(fd,12); - else if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) // 00 = Female, 01 = Male - account_id = RFIFOL(fd,10); - else { // 29 28 28 // search correct value - // if account id and char id of version 14 - if (RFIFOL(fd,3) > 700000 && RFIFOL(fd,10) >= 150000 && RFIFOL(fd,10) < 5000000) // account id / char id (more than 5.000.000 characters?) [Yor] - account_id = RFIFOL(fd,3); - else - account_id = RFIFOL(fd,5); - } - // 0x9B - } else { - account_id = RFIFOL(fd,3); - } - - // if same account already connected, we disconnect the 2 sessions - if ((old_sd = map_id2sd(account_id)) != NULL) { - clif_authfail_fd(fd, 8); // still recognizes last connection - clif_authfail_fd(old_sd->fd, 2); // same id - if (sd != 0) - clif_setwaitclose(sd->fd); // Set session to EOF - } else { - sd = (struct map_session_data*)aCalloc(1, sizeof(struct map_session_data)); - session[fd]->session_data = sd; - sd->fd = fd; - - if (IS_PACKET_DB_VER(cmd)) { - sd->packet_ver = clif_config.packet_db_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[1]), - RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[2]), - RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[3]), - RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[4]), fd); - // 0x72 - } else if (cmd == 0x72) { - if (RFIFOREST(fd) >= 39 && (RFIFOB(fd,38) == 0 || RFIFOB(fd,38) == 1)) { // 00 = Female, 01 = Male - sd->packet_ver = 7; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,22), RFIFOL(fd,30), RFIFOL(fd,34), RFIFOB(fd,38), fd); - } else if (RFIFOREST(fd) >= 22 && (RFIFOB(fd,21) == 0 || RFIFOB(fd,21) == 1)) { // 00 = Female, 01 = Male - sd->packet_ver = 6; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,9), RFIFOL(fd,13), RFIFOL(fd,17), RFIFOB(fd,21), fd); - } else { // old packet version - sd->packet_ver = 5; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOB(fd,18), fd); - } - // 0x7E - } else if (cmd == 0x7E) { - if (RFIFOREST(fd) >= 37 && (RFIFOB(fd,36) == 0 || RFIFOB(fd,36) == 1)) { // 00 = Female, 01 = Male - sd->packet_ver = 9; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,21), RFIFOL(fd,28), RFIFOL(fd,32), RFIFOB(fd,36), fd); - } else { - sd->packet_ver = 8; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,18), RFIFOL(fd,24), RFIFOL(fd,28), RFIFOB(fd,32), fd); - } - // 0xF5 - } else if (cmd == 0xF5) { - if (RFIFOREST(fd) >= 34 && (RFIFOB(fd,33) == 0 || RFIFOB(fd,33) == 1)) { // 00 = Female, 01 = Male - sd->packet_ver = 10; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,15), RFIFOL(fd,25), RFIFOL(fd,29), RFIFOB(fd,33), fd); - } else if (RFIFOREST(fd) >= 33 && (RFIFOB(fd,32) == 0 || RFIFOB(fd,32) == 1)) { // 00 = Female, 01 = Male - sd->packet_ver = 12; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,18), RFIFOL(fd,24), RFIFOL(fd,28), RFIFOB(fd,32), fd); - } else if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) { // 00 = Female, 01 = Male - sd->packet_ver = 11; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,17), RFIFOL(fd,23), RFIFOL(fd,27), RFIFOB(fd,31), fd); - } else { // 29 - // if account id and char id of version 14 - if (RFIFOL(fd,3) > 700000 && RFIFOL(fd,10) >= 150000 && RFIFOL(fd,10) < 5000000) { // account id / char id (more than 5.000.000 characters?) - sd->packet_ver = 15; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,10), RFIFOL(fd,20), RFIFOL(fd,24), RFIFOB(fd,28), fd); - } else { - sd->packet_ver = 13; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - pc_setnewpc(sd, account_id, RFIFOL(fd,14), RFIFOL(fd,20), RFIFOL(fd,24), RFIFOB(fd,28), fd); - } - } - // 0x9B - } else { - sd->packet_ver = 16; // 16: 10jan05 - pc_setnewpc(sd, account_id, RFIFOL(fd,12), RFIFOL(fd,23), RFIFOL(fd,27), RFIFOB(fd,31), fd); - } - - WFIFOL(fd,0) = sd->bl.id; - WFIFOSET(fd,4); - - map_addiddb(&sd->bl); - - chrif_authreq(sd); - } - - return; -} - -/*========================================== - * 007d クライアント側マップ読み込み完了 - * map侵入時に必要なデータを全て送りつける - *------------------------------------------ - */ -void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) -{ -// struct item_data* item; - int i; - nullpo_retv(sd); - - if(sd->bl.prev != NULL) - return; - - // 接続ok時 - //clif_authok(); - if(sd->npc_id) npc_event_dequeue(sd); - clif_skillinfoblock(sd); - pc_checkitem(sd); - //guild_info(); - - // loadendack時 - // next exp - clif_updatestatus(sd,SP_NEXTBASEEXP); - clif_updatestatus(sd,SP_NEXTJOBEXP); - // skill point - clif_updatestatus(sd,SP_SKILLPOINT); - // item - clif_itemlist(sd); - clif_equiplist(sd); - // cart - if(pc_iscarton(sd)){ - clif_cart_itemlist(sd); - clif_cart_equiplist(sd); - clif_updatestatus(sd,SP_CARTINFO); - } - // param all - clif_initialstatus(sd); - // party - party_send_movemap(sd); - // guild - guild_send_memberinfoshort(sd,1); - // 119 - // 78 - - if(battle_config.pc_invincible_time > 0) { - if(map[sd->bl.m].flag.gvg) - pc_setinvincibletimer(sd,battle_config.pc_invincible_time<<1); - else - pc_setinvincibletimer(sd,battle_config.pc_invincible_time); - } - - map_addblock(&sd->bl); // ブロック登録 - clif_spawnpc(sd); // spawn - - // weight max , now - clif_updatestatus(sd,SP_MAXWEIGHT); - clif_updatestatus(sd,SP_WEIGHT); - - // pvp - if(sd->pvp_timer!=-1 && !battle_config.pk_mode) - delete_timer(sd->pvp_timer,pc_calc_pvprank_timer); - if(map[sd->bl.m].flag.pvp){ - if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris] - sd->pvp_timer=add_timer(gettick()+200,pc_calc_pvprank_timer,sd->bl.id,0); - sd->pvp_rank=0; - sd->pvp_lastusers=0; - sd->pvp_point=5; - } - clif_set0199(sd->fd,1); - } else { - sd->pvp_timer=-1; - } - if(map[sd->bl.m].flag.gvg) { - clif_set0199(sd->fd,3); - } - - // pet - if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) { - map_addblock(&sd->pd->bl); - clif_spawnpet(sd->pd); - clif_send_petdata(sd,0,0); - clif_send_petdata(sd,5,0x14); - clif_send_petstatus(sd); - } - - if(sd->state.connect_new) { - sd->state.connect_new = 0; - if(sd->status.class_ != sd->view_class) - clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); - if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 900) - clif_pet_emotion(sd->pd,(sd->pd->class_ - 100)*100 + 50 + pet_hungry_val(sd)); - -/* Stop players from spawning inside castles [Valaris] */ - - { - struct guild_castle *gc=guild_mapname2gc(map[sd->bl.m].name); - if (gc) - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,2); - } - -/* End Addition [Valaris] */ - - } - - // view equipment item -#if PACKETVER < 4 - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); -#else - clif_changelook(&sd->bl,LOOK_WEAPON,0); -#endif - if(battle_config.save_clothcolor==1 && sd->status.clothes_color > 0) - clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color); - - //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 && - if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 && - (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 )) - // オートバーサーク発動 - status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0); - -// if(time(&timer) < ((weddingtime=pc_readglobalreg(sd,"PC_WEDDING_TIME")) + 3600)) -// status_change_start(&sd->bl,SC_WEDDING,0,weddingtime,0,0,36000,0); - - if(battle_config.muting_players && sd->status.manner < 0) - status_change_start(&sd->bl,SC_NOCHAT,0,0,0,0,0,0); - - if (night_flag) { - if (battle_config.night_darkness_level > 0 && !map[sd->bl.m].flag.indoors) - clif_specialeffect(&sd->bl, 474 + battle_config.night_darkness_level, 0); - else { - //clif_specialeffect(&sd->bl, 483, 0); // default darkness level - // night - when changing from indoors to outdoors - celest - if (!map[sd->bl.m].flag.indoors && sd->opt2 != STATE_BLIND) - sd->opt2 |= STATE_BLIND; - // changing from outdoors to indoors - else if (map[sd->bl.m].flag.indoors && sd->opt2 == STATE_BLIND) - sd->opt2 &= ~STATE_BLIND; - } - } - - // option - clif_changeoption(&sd->bl); - if(sd->sc_data[SC_TRICKDEAD].timer != -1) - status_change_end(&sd->bl,SC_TRICKDEAD,-1); - if(sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele)) - status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1); - if(sd->special_state.infinite_endure && sd->sc_data[SC_ENDURE].timer == -1) - status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0); - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0002 && sd->status.inventory[i].attribute==1) - status_change_start(&sd->bl,SC_BROKNWEAPON,0,0,0,0,0,0); - if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0010 && sd->status.inventory[i].attribute==1) - status_change_start(&sd->bl,SC_BROKNARMOR,0,0,0,0,0,0); - } - - map_foreachinarea(clif_getareachar,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,0,sd); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_TickSend(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if (USE_PACKET_DB(sd)) { - sd->client_tick=RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - sd->client_tick = RFIFOL(fd,6); - break; - case 9: - sd->client_tick = RFIFOL(fd,9); - break; - case 10: - sd->client_tick = RFIFOL(fd,7); - break; - case 11: - sd->client_tick = RFIFOL(fd,10); - break; - case 12: - sd->client_tick = RFIFOL(fd,6); - break; - case 13: - case 14: - sd->client_tick = RFIFOL(fd,5); - break; - case 15: - sd->client_tick = RFIFOL(fd,3); - break; - case 16: - sd->client_tick = RFIFOL(fd,5); - break; - - default: // old version by default (and version 6 + 7) - sd->client_tick = RFIFOL(fd,2); - break; - } - } - - sd->server_tick = gettick(); - clif_servertick(sd); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_WalkToXY(int fd, struct map_session_data *sd) { - int x, y; - - nullpo_retv(sd); - - if (pc_isdead(sd)) { - clif_clearchar_area(&sd->bl, 1); - return; - } - - if (sd->npc_id != 0 || sd->vender_id != 0) - return; - - if (sd->skilltimer != -1 && pc_checkskill(sd, SA_FREECAST) <= 0) // フリーキャスト - return; - - if (sd->chatID) - return; - - if (sd->canmove_tick > gettick()) - return; - - // ステータス異常やハイディング中(トンネルドライブ無)で動けない - if ((sd->opt1 > 0 && sd->opt1 != 6) || - sd->sc_data[SC_ANKLE].timer !=-1 || //アンクルスネア - sd->sc_data[SC_AUTOCOUNTER].timer !=-1 || //オートカウンター - sd->sc_data[SC_TRICKDEAD].timer !=-1 || //死んだふり - sd->sc_data[SC_BLADESTOP].timer !=-1 || //白刃取り - sd->sc_data[SC_SPIDERWEB].timer !=-1 || //スパイダーウェッブ - (sd->sc_data[SC_DANCING].timer !=-1 && sd->sc_data[SC_DANCING].val4) || //合奏スキル演奏中は動けない - (sd->sc_data[SC_GOSPEL].timer !=-1 && sd->sc_data[SC_GOSPEL].val4 == BCT_SELF) || // cannot move while gospel is in effect - sd->sc_data[SC_CONFUSION].timer !=-1) - return; - if ((sd->status.option & 2) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0) - return; - - if (sd->invincible_timer != -1) - pc_delinvincibletimer(sd); - - pc_stopattack(sd); - - if (USE_PACKET_DB(sd)) { - int cmd = RFIFOW(fd,0); - x = RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0]) * 4 + - (RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0] + 1) >> 6); - y = ((RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0]+1) & 0x3f) << 4) + - (RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0] + 2) >> 4); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 6: - x = RFIFOB(fd,5) * 4 + (RFIFOB(fd,6) >> 6); - y = ((RFIFOB(fd,6) & 0x3f) << 4) + (RFIFOB(fd,7) >> 4); - break; - case 7: - x = RFIFOB(fd,6) * 4 + (RFIFOB(fd,7) >> 6); - y = ((RFIFOB(fd,7) & 0x3f) << 4) + (RFIFOB(fd,8) >> 4); - break; - case 8: - x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6); - y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4); - break; - case 9: - x = RFIFOB(fd,12) * 4 + (RFIFOB(fd,13) >> 6); - y = ((RFIFOB(fd,13) & 0x3f) << 4) + (RFIFOB(fd,14) >> 4); - break; - case 10: - x = RFIFOB(fd,6) * 4 + (RFIFOB(fd,7) >> 6); - y = ((RFIFOB(fd,7) & 0x3f) << 4) + (RFIFOB(fd,8) >> 4); - break; - case 11: - x = RFIFOB(fd,11) * 4 + (RFIFOB(fd,12) >> 6); - y = ((RFIFOB(fd,12) & 0x3f) << 4) + (RFIFOB(fd,13) >> 4); - break; - case 12: - x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6); - y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4); - break; - case 13: - case 14: - x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6); - y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4); - break; - case 15: - x = RFIFOB(fd,4) * 4 + (RFIFOB(fd,5) >> 6); - y = ((RFIFOB(fd,5) & 0x3f) << 4) + (RFIFOB(fd,6) >> 4); - break; - case 16: - x = RFIFOB(fd,10) * 4 + (RFIFOB(fd,11) >> 6); - y = ((RFIFOB(fd,11) & 0x3f) << 4) + (RFIFOB(fd,12) >> 4); - break; - default: // old version by default - x = RFIFOB(fd,2) * 4 + (RFIFOB(fd,3) >> 6); - y = ((RFIFOB(fd,3) & 0x3f) << 4) + (RFIFOB(fd,4) >> 4); - break; - } - } - pc_walktoxy(sd, x, y); - -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_QuitGame(int fd, struct map_session_data *sd) { - unsigned int tick=gettick(); - struct skill_unit_group* sg; - - nullpo_retv(sd); - - WFIFOW(fd,0) = 0x18b; - if ((!pc_isdead(sd) && (sd->opt1 || (sd->opt2 && !(night_flag == 1 && sd->opt2 == STATE_BLIND)))) || - sd->skilltimer != -1 || - (DIFF_TICK(tick, sd->canact_tick) < 0) || - (sd->sc_data && sd->sc_data[SC_DANCING].timer!=-1 && sd->sc_data[SC_DANCING].val4 && (sg=(struct skill_unit_group *)sd->sc_data[SC_DANCING].val2) && sg->src_id == sd->bl.id)) { - WFIFOW(fd,2)=1; - WFIFOSET(fd,packet_len_table[0x18b]); - return; - } - - /* Rovert's prevent logout option fixed [Valaris] */ - if ((battle_config.prevent_logout && (gettick() - sd->canlog_tick) >= 10000) || (!battle_config.prevent_logout)) { - clif_setwaitclose(fd); - WFIFOW(fd,2)=0; - } else { - WFIFOW(fd,2)=1; - } - WFIFOSET(fd,packet_len_table[0x18b]); - -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) { - struct block_list *bl; - int account_id; - - if (USE_PACKET_DB(sd)) { - account_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - account_id = RFIFOL(fd,11); - break; - case 9: - account_id = RFIFOL(fd,8); - break; - case 10: - account_id = RFIFOL(fd,10); - break; - case 11: - account_id = RFIFOL(fd,6); - break; - case 12: - account_id = RFIFOL(fd,11); - break; - case 13: - case 14: - account_id = RFIFOL(fd,6); - break; - case 15: - account_id = RFIFOL(fd,9); - break; - case 16: - account_id = RFIFOL(fd,4); - break; - default: // old version by default (+ packet version 6 and 7) - account_id = RFIFOL(fd,2); - break; - } - } - bl = map_id2bl(account_id); - if (bl == NULL) - return; - - WFIFOW(fd,0) = 0x95; - WFIFOL(fd,2) = account_id; - - switch(bl->type) { - case BL_PC: - { - struct map_session_data *ssd = (struct map_session_data *)bl; - struct party *p = NULL; - struct guild *g = NULL; - - nullpo_retv(ssd); - - memcpy(WFIFOP(fd,6), ssd->status.name, 24); - if (ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL && - (ssd->status.party_id == 0 || (p = party_search(ssd->status.party_id)) != NULL)) { - // ギルド所属ならパケット0195を返す - int i, ps = -1; - for(i = 0; i < g->max_member; i++) { - if (g->member[i].account_id == ssd->status.account_id && - g->member[i].char_id == ssd->status.char_id ) - ps = g->member[i].position; - } - if (ps >= 0 && ps < MAX_GUILDPOSITION) { - WFIFOW(fd, 0) = 0x195; - if (p) - memcpy(WFIFOP(fd,30), p->name, 24); - else - WFIFOB(fd,30) = 0; - memcpy(WFIFOP(fd,54), g->name,24); - memcpy(WFIFOP(fd,78), g->position[ps].name, 24); - WFIFOSET(fd,packet_len_table[0x195]); - break; - } - } - WFIFOSET(fd,packet_len_table[0x95]); - } - break; - case BL_PET: - memcpy(WFIFOP(fd,6), ((struct pet_data*)bl)->name, 24); - WFIFOSET(fd,packet_len_table[0x95]); - break; - case BL_NPC: - memcpy(WFIFOP(fd,6), ((struct npc_data*)bl)->name, 24); - WFIFOSET(fd,packet_len_table[0x95]); - break; - case BL_MOB: - { - struct mob_data *md = (struct mob_data *)bl; - - nullpo_retv(md); - - memcpy(WFIFOP(fd,6), md->name, 24); - if (md->class_ >= 1285 && md->class_ <= 1288 && md->guild_id) { - struct guild *g; - struct guild_castle *gc = guild_mapname2gc(map[md->bl.m].name); - if (gc && gc->guild_id > 0 && (g = guild_search(gc->guild_id)) != NULL) { - WFIFOW(fd, 0) = 0x195; - WFIFOB(fd,30) = 0; - memcpy(WFIFOP(fd,54), g->name, 24); - memcpy(WFIFOP(fd,78), gc->castle_name, 24); - WFIFOSET(fd,packet_len_table[0x195]); - } else { - WFIFOSET(fd,packet_len_table[0x95]); - } - } else if (battle_config.show_mob_hp == 1) { - char mobhp[50]; - sprintf(mobhp, "hp: %d/%d", md->hp, mob_db[md->class_].max_hp); - WFIFOW(fd, 0) = 0x195; - memcpy(WFIFOP(fd,30), mobhp, 24); - WFIFOB(fd,54) = 0; - WFIFOB(fd,78) = 0; - WFIFOSET(fd,packet_len_table[0x195]); - } else { - WFIFOSET(fd,packet_len_table[0x95]); - } - } - break; - default: - if (battle_config.error_log) - printf("clif_parse_GetCharNameRequest : bad type %d(%d)\n", bl->type, account_id); - break; - } -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <len>.w <str>.?B - char *message; - unsigned char *buf; - - nullpo_retv(sd); - if ((is_atcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != AtCommand_None) || - (is_charcommand(fd, sd, (char*)RFIFOP(fd,4),0)!= CharCommand_None) || - (sd->sc_data && - (sd->sc_data[SC_BERSERK].timer != -1 || //バーサーク時は会話も不可 - sd->sc_data[SC_NOCHAT].timer != -1 ))) //チャット禁止 - return; - - message = (char*)aCallocA(RFIFOW(fd,2) + 128, sizeof(char)); - buf = (unsigned char*)aCallocA(RFIFOW(fd,2) + 4, sizeof(char)); - - //printf("clif_parse_GlobalMessage: message: '%s'.\n", RFIFOP(fd,4)); - if (strncmp((char*)RFIFOP(fd,4), sd->status.name, strlen(sd->status.name)) != 0) { - printf("Hack on global message: character '%s' (account: %d), use an other name to send a (normal) message.\n", sd->status.name, sd->status.account_id); - - // information is sended to all online GM - sprintf(message, "Hack on global message (normal message): character '%s' (account: %d) uses another name.", sd->status.name, sd->status.account_id); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message); - if (strlen((char*)RFIFOP(fd,4)) == 0) - strcpy(message, " This player sends a void name and a void message."); - else - sprintf(message, " This player sends (name:message): '%s'.", RFIFOP(fd,4)); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message); - // message about the ban - if (battle_config.ban_spoof_namer > 0) - sprintf(message, " This player has been banned for %d minute(s).", battle_config.ban_spoof_namer); - else - sprintf(message, " This player hasn't been banned (Ban option is disabled)."); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message); - - // if we ban people - if (battle_config.ban_spoof_namer > 0) { - chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_spoof_namer, 0); // type: 2 - ban (year, month, day, hour, minute, second) - clif_setwaitclose(fd); // forced to disconnect because of the hack - - if(message) aFree(message); - if(buf) aFree(buf); - - return; - } - // but for the hacker, we display on his screen (he see/look no difference). - } else { - // send message to others - WBUFW(buf,0) = 0x8d; - WBUFW(buf,2) = RFIFOW(fd,2) + 4; // len of message - 4 + 8 - WBUFL(buf,4) = sd->bl.id; - memcpy(WBUFP(buf,8), RFIFOP(fd,4), RFIFOW(fd,2) - 4); - clif_send(buf, WBUFW(buf,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC); - } - - // send back message to the speaker - memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2)); - WFIFOW(fd,0) = 0x8e; - WFIFOSET(fd, WFIFOW(fd,2)); - -#ifdef PCRE_SUPPORT - map_foreachinarea(npc_chat_sub, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_NPC, RFIFOP(fd,4), strlen((char *) RFIFOP(fd,4)), &sd->bl); -#endif - - // Celest - if (pc_calc_base_job2 (sd->status.class_) == 23 ) { - int next = pc_nextbaseexp(sd)>0 ? pc_nextbaseexp(sd) : sd->status.base_exp; - if (next > 0 && (sd->status.base_exp*100/next)%10 == 0) { - estr_lower((char*)RFIFOP(fd,4)); - if (sd->state.snovice_flag == 0 && strstr((char*)RFIFOP(fd,4), msg_txt(504))) - sd->state.snovice_flag = 1; - else if (sd->state.snovice_flag == 1) { - sprintf(message, msg_txt(505), sd->status.name); - estr_lower(message); - if (strstr((char*)RFIFOP(fd,4), message)) - sd->state.snovice_flag = 2; - } - else if (sd->state.snovice_flag == 2 && strstr((char*)RFIFOP(fd,4), msg_txt(506))) - sd->state.snovice_flag = 3; - else if (sd->state.snovice_flag == 3) { - int i; - status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],1,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,1),0 ); - for(i=0;i<5;i++) - pc_addspiritball(sd,skill_get_time(MO_CALLSPIRITS,1),5); - sd->state.snovice_flag = 0; - } - } - } - - if(message) aFree(message); - if(buf) aFree(buf); - - return; -} - -int clif_message(struct block_list *bl, char* msg) -{ - unsigned short msg_len = strlen(msg) + 1; - unsigned char buf[256]; - - nullpo_retr(0, bl); - - WBUFW(buf, 0) = 0x8d; - WBUFW(buf, 2) = msg_len + 8; - WBUFL(buf, 4) = bl->id; - memcpy(WBUFP(buf, 8), msg, msg_len); - - clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); // by Gengar - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_MapMove(int fd, struct map_session_data *sd) { -// /m /mapmove (as @rura GM command) - char output[30]; // 17+4+4=26, 30 max. - char map_name[17]; - - nullpo_retv(sd); - -// not needed at all as far as sprintf is used // [Ilpalazzo-sama] -// memset(output, '\0', sizeof(output)); -// not needed -- map_name[16]='\0'; will do -// memset(map_name, '\0', sizeof(map_name)); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_MapMove))) { - memcpy(map_name, RFIFOP(fd,2), 16); - map_name[16]='\0'; - sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20)); - atcommand_rura(fd, sd, "@rura", output); - } - - return; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_changed_dir(struct block_list *bl) { - unsigned char buf[64]; - struct map_session_data *sd = NULL; - - if (bl->type == BL_PC) - nullpo_retv (sd=(struct map_session_data *)bl); - - WBUFW(buf,0) = 0x9c; - WBUFL(buf,2) = bl->id; - if (sd) - WBUFW(buf,6) = sd->head_dir; - WBUFB(buf,8) = status_get_dir(bl); - if (sd && sd->disguise > 23 && sd->disguise < 4001) // mob disguises [Valaris] - clif_send(buf, packet_len_table[0x9c], &sd->bl, AREA); - else - clif_send(buf, packet_len_table[0x9c], bl, AREA_WOS); - - return; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ChangeDir(int fd, struct map_session_data *sd) { - short headdir, dir; - - nullpo_retv(sd); - - if (USE_PACKET_DB(sd)) { - headdir = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - dir = RFIFOB(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 7: - headdir = RFIFOW(fd,5); - dir = RFIFOB(fd,12); - break; - case 8: - headdir = RFIFOW(fd,5); - dir = RFIFOB(fd,12); - break; - case 9: - headdir = RFIFOW(fd,7); - dir = RFIFOB(fd,11); - break; - case 10: - headdir = RFIFOW(fd,4); - dir = RFIFOB(fd,9); - break; - case 11: - headdir = RFIFOW(fd,8); - dir = RFIFOB(fd,17); - break; - case 12: - headdir = RFIFOW(fd,5); - dir = RFIFOB(fd,12); - break; - case 13: - case 14: - headdir = RFIFOW(fd,6); - dir = RFIFOB(fd,14); - break; - case 15: - headdir = RFIFOW(fd,3); - dir = RFIFOB(fd,7); - break; - case 16: - headdir = RFIFOW(fd,12); - dir = RFIFOB(fd,22); - break; - - default: // old version by default (and packet version 6) - headdir = RFIFOW(fd,2); - dir = RFIFOB(fd,4); - break; - } - } - - pc_setdir(sd, dir, headdir); - - clif_changed_dir(&sd->bl); - return; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_Emotion(int fd, struct map_session_data *sd) { - unsigned char buf[64]; - - nullpo_retv(sd); - - if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) { - if (RFIFOB(fd,2) == 34) {// prevent use of the mute emote [Valaris] - clif_skill_fail(sd, 1, 0, 1); - return; - } - // fix flood of emotion icon (ro-proxy): flood only the hacker player - if (sd->emotionlasttime >= time(NULL)) { - sd->emotionlasttime = time(NULL) + 2; // not more than 1 every 2 seconds (normal client is every 3-4 seconds) - clif_skill_fail(sd, 1, 0, 1); - return; - } - sd->emotionlasttime = time(NULL) + 2; // not more than 1 every 2 seconds (normal client is every 3-4 seconds) - - WBUFW(buf,0) = 0xc0; - WBUFL(buf,2) = sd->bl.id; - WBUFB(buf,6) = RFIFOB(fd,2); - clif_send(buf, packet_len_table[0xc0], &sd->bl, AREA); - } else - clif_skill_fail(sd, 1, 0, 1); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_HowManyConnections(int fd, struct map_session_data *sd) { - WFIFOW(fd,0) = 0xc2; - WFIFOL(fd,2) = map_getusers(); - WFIFOSET(fd,packet_len_table[0xc2]); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ActionRequest(int fd, struct map_session_data *sd) { - unsigned int tick; - unsigned char buf[64]; - int action_type, target_id; - - nullpo_retv(sd); - - if (pc_isdead(sd)) { - clif_clearchar_area(&sd->bl, 1); - return; - } - if (sd->npc_id != 0 || sd->opt1 > 0 || sd->status.option & 2 || - (sd->sc_data && - (sd->sc_data[SC_TRICKDEAD].timer != -1 || - sd->sc_data[SC_AUTOCOUNTER].timer != -1 || //オートカウンター - sd->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り - sd->sc_data[SC_DANCING].timer != -1))) //ダンス中 - return; - - tick = gettick(); - - pc_stop_walking(sd, 0); - pc_stopattack(sd); - - if (USE_PACKET_DB(sd)) { - target_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - action_type = RFIFOB(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - target_id = RFIFOL(fd,3); - action_type = RFIFOB(fd,8); - break; - case 9: - target_id = RFIFOL(fd,7); - action_type = RFIFOB(fd,17); - break; - case 10: - target_id = RFIFOL(fd,9); - action_type = RFIFOB(fd,22); - break; - case 11: - target_id = RFIFOL(fd,3); - action_type = RFIFOB(fd,8); - break; - case 12: - target_id = RFIFOL(fd,3); - action_type = RFIFOB(fd,8); - break; - case 13: - case 14: - target_id = RFIFOL(fd,4); - action_type = RFIFOB(fd,14); - break; - case 15: - target_id = RFIFOL(fd,6); - action_type = RFIFOB(fd,17); - break; - case 16: - target_id = RFIFOL(fd,9); - action_type = RFIFOB(fd,19); - break; - - default: // old version by default (and packet version 6 and 7) - target_id = RFIFOL(fd,2); - action_type = RFIFOB(fd,6); - break; - } - } - - switch(action_type) { - case 0x00: // once attack - case 0x07: // continuous attack - if(sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class==22) - return; - if (sd->vender_id != 0) - return; - if (!battle_config.sdelay_attack_enable && pc_checkskill(sd, SA_FREECAST) <= 0) { - if (DIFF_TICK(tick, sd->canact_tick) < 0) { - clif_skill_fail(sd, 1, 4, 0); - return; - } - } - if (sd->invincible_timer != -1) - pc_delinvincibletimer(sd); - if (sd->attacktarget > 0) // [Valaris] - sd->attacktarget = 0; - pc_attack(sd, target_id, action_type != 0); - break; - case 0x02: // sitdown - if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 3) { - pc_stop_walking(sd, 1); - pc_setsit(sd); - skill_gangsterparadise(sd, 1); // ギャングスターパラダイス設定 fixed Valaris - clif_sitting(sd); - } else - clif_skill_fail(sd, 1, 0, 2); - break; - case 0x03: // standup - pc_setstand(sd); - skill_gangsterparadise(sd, 0); // ギャングスターパラダイス解除 fixed Valaris - WBUFW(buf, 0) = 0x8a; - WBUFL(buf, 2) = sd->bl.id; - WBUFB(buf,26) = 3; - clif_send(buf, packet_len_table[0x8a], &sd->bl, AREA); - break; - } -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_Restart(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - switch(RFIFOB(fd,2)) { - case 0x00: - if (pc_isdead(sd)) { - pc_setstand(sd); - pc_setrestartvalue(sd, 3); - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 2); - } - // in case the player's status somehow wasn't updated yet [Celest] - else if (sd->status.hp <= 0) - pc_setdead(sd); - break; - case 0x01: - if(!pc_isdead(sd) && (sd->opt1 || (sd->opt2 && !(night_flag == 1 && sd->opt2 == STATE_BLIND)))) - return; - - /* Rovert's Prevent logout option - Fixed [Valaris] */ - if ((battle_config.prevent_logout && (gettick() - sd->canlog_tick) >= 10000) || (!battle_config.prevent_logout)) { - chrif_charselectreq(sd); - } else { - WFIFOW(fd,0)=0x18b; - WFIFOW(fd,2)=1; - - WFIFOSET(fd,packet_len_table[0x018b]); - } - break; - } -} - -/*========================================== - * Transmission of a wisp (S 0096 <len>.w <nick>.24B <message>.?B) - *------------------------------------------ - */ -void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 <len>.w <nick>.24B <message>.?B // rewritten by [Yor] - char *gm_command; - struct map_session_data *dstsd; - int i; - - //printf("clif_parse_Wis: message: '%s'.\n", RFIFOP(fd,28)); - - gm_command = (char*)aCallocA(strlen((const char*)RFIFOP(fd,28)) + 28, sizeof(char)); // 24+3+(RFIFOW(fd,2)-28)+1 or 24+3+(strlen(RFIFOP(fd,28))+1 (size can be wrong with hacker) - - sprintf(gm_command, "%s : %s", sd->status.name, RFIFOP(fd,28)); - if ((is_charcommand(fd, sd, gm_command, 0) != CharCommand_None) || - (is_atcommand(fd, sd, gm_command, 0) != AtCommand_None) || - (sd && sd->sc_data && - (sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク時は会話も不可 - sd->sc_data[SC_NOCHAT].timer != -1))) //チャット禁止 - { - if(gm_command) aFree(gm_command); - return; - } - - if(gm_command) aFree(gm_command); - - // searching destination character - dstsd = map_nick2sd((char*)RFIFOP(fd,4)); - // player is not on this map-server - if (dstsd == NULL || - // At this point, don't send wisp/page if it's not exactly the same name, because (example) - // if there are 'Test' player on an other map-server and 'test' player on this map-server, - // and if we ask for 'Test', we must not contact 'test' player - // so, we send information to inter-server, which is the only one which decide (and copy correct name). - strcmp(dstsd->status.name, (const char*)RFIFOP(fd,4)) != 0) // not exactly same name - // send message to inter-server - intif_wis_message(sd, (char*)RFIFOP(fd,4), (char*)RFIFOP(fd,28), RFIFOW(fd,2)-28); - // player is on this map-server - else { - // if you send to your self, don't send anything to others - if (dstsd->fd == fd) // but, normaly, it's impossible! - clif_wis_message(fd, wisp_server_name, "You can not page yourself. Sorry.", strlen("You can not page yourself. Sorry.") + 1); - // otherwise, send message and answer immediatly - else { - if (dstsd->ignoreAll == 1) - clif_wis_end(fd, 2); // type: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - else { - // if player ignore the source character - for(i = 0; i < MAX_IGNORE_LIST; i++) - if (strcmp(dstsd->ignore[i].name, sd->status.name) == 0) { - clif_wis_end(fd, 2); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - break; - } - // if source player not found in ignore list - if (i == MAX_IGNORE_LIST) { - clif_wis_message(dstsd->fd, sd->status.name, (char*)RFIFOP(fd,28), RFIFOW(fd,2) - 28); - clif_wis_end(fd, 0); // type: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - } - } - } - } - - return; -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_GMmessage(int fd, struct map_session_data *sd) { -// /b - nullpo_retv(sd); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_Broadcast))) - intif_GMmessage((char*)RFIFOP(fd,4), RFIFOW(fd,2)-4, 0); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_TakeItem(int fd, struct map_session_data *sd) { - struct flooritem_data *fitem; - int map_object_id; - - nullpo_retv(sd); - - if (USE_PACKET_DB(sd)) { - map_object_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 7: - map_object_id = RFIFOL(fd,6); - break; - case 8: - map_object_id = RFIFOL(fd,6); - break; - case 9: - map_object_id = RFIFOL(fd,9); - break; - case 10: - map_object_id = RFIFOL(fd,7); - break; - case 11: - map_object_id = RFIFOL(fd,10); - break; - case 12: - map_object_id = RFIFOL(fd,6); - break; - case 13: - case 14: - map_object_id = RFIFOL(fd,5); - break; - case 15: - map_object_id = RFIFOL(fd,3); - break; - case 16: - map_object_id = RFIFOL(fd,5); - break; - default: // old version by default (and packet version 6) - map_object_id = RFIFOL(fd,2); - break; - } - } - fitem = (struct flooritem_data*)map_id2bl(map_object_id); - - if (pc_isdead(sd)) { - clif_clearchar_area(&sd->bl, 1); - return; - } - - if( sd->npc_id!=0 || sd->vender_id != 0 || sd->opt1 > 0 || - (sd->sc_data && (sd->sc_data[SC_TRICKDEAD].timer != -1 || //死んだふり - sd->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り - sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク - sd->sc_data[SC_NOCHAT].timer!=-1 )) ) //会話禁止 - return; - - if (fitem == NULL || fitem->bl.m != sd->bl.m) - return; - - pc_takeitem(sd, fitem); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_DropItem(int fd, struct map_session_data *sd) { - int item_index, item_amount; - - nullpo_retv(sd); - - if (pc_isdead(sd)) { - clif_clearchar_area(&sd->bl, 1); - return; - } - if (sd->npc_id != 0 || sd->vender_id != 0 || sd->opt1 > 0 || - (sd->sc_data && (sd->sc_data[SC_AUTOCOUNTER].timer != -1 || //オートカウンター - sd->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り - sd->sc_data[SC_BERSERK].timer != -1)) ) //バーサーク - return; - - if (USE_PACKET_DB(sd)) { - item_index = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-2; - item_amount = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - item_index = RFIFOW(fd,5) - 2; - item_amount = RFIFOW(fd,12); - break; - case 9: - item_index = RFIFOW(fd,8) - 2; - item_amount = RFIFOW(fd,15); - break; - case 10: - item_index = RFIFOW(fd,6) - 2; - item_amount = RFIFOW(fd,15); - break; - case 11: - item_index = RFIFOW(fd,12) - 2; - item_amount = RFIFOW(fd,17); - break; - case 12: - item_index = RFIFOW(fd,5) - 2; - item_amount = RFIFOW(fd,12); - break; - case 13: - case 14: - item_index = RFIFOW(fd,6) - 2; - item_amount = RFIFOW(fd,10); - break; - case 15: - item_index = RFIFOW(fd,4) - 2; - item_amount = RFIFOW(fd,10); - break; - case 16: - item_index = RFIFOW(fd,15) - 2; - item_amount = RFIFOW(fd,18); - break; - default: // old version by default (+ packet version 6 and 7) - item_index = RFIFOW(fd,2) - 2; - item_amount = RFIFOW(fd,4); - break; - } - } - - pc_dropitem(sd, item_index, item_amount); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_UseItem(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if (pc_isdead(sd)) { - clif_clearchar_area(&sd->bl, 1); - return; - } - if (sd->npc_id!=0 || sd->vender_id != 0 || (sd->opt1 > 0 && sd->opt1 != 6) || - (sd->sc_data && (sd->sc_data[SC_TRICKDEAD].timer != -1 || //死んだふり - sd->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り - sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク - sd->sc_data[SC_NOCHAT].timer!=-1 )) ) //会話禁止 - return; - - if (sd->invincible_timer != -1) - pc_delinvincibletimer(sd); - - if (USE_PACKET_DB(sd)) { - pc_useitem(sd,RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-2); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 6: - pc_useitem(sd,RFIFOW(fd,5)-2); - break; - case 7: - pc_useitem(sd,RFIFOW(fd,6)-2); - break; - case 8: - pc_useitem(sd,RFIFOW(fd,6)-2); - break; - case 9: - pc_useitem(sd,RFIFOW(fd,9)-2); - break; - case 10: - pc_useitem(sd,RFIFOW(fd,7)-2); - break; - case 11: - pc_useitem(sd,RFIFOW(fd,10)-2); - break; - case 12: - pc_useitem(sd,RFIFOW(fd,6)-2); - break; - case 13: - case 14: - pc_useitem(sd,RFIFOW(fd,5)-2); - break; - case 15: - pc_useitem(sd,RFIFOW(fd,3)-2); - break; - case 16: - pc_useitem(sd,RFIFOW(fd,5)-2); - break; - default: // old version by default - pc_useitem(sd,RFIFOW(fd,2)-2); - break; - } - } -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_EquipItem(int fd,struct map_session_data *sd) -{ - int index; - - nullpo_retv(sd); - - if(pc_isdead(sd)) { - clif_clearchar_area(&sd->bl,1); - return; - } - index = RFIFOW(fd,2)-2; - if(sd->npc_id!=0 || sd->vender_id != 0) return; - if(sd->sc_data && ( sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1 )) return; - - if(sd->status.inventory[index].identify != 1) { // 未鑑定 - clif_equipitemack(sd,index,0,0); // fail - return; - } - //ペット用装備であるかないか - if(sd->inventory_data[index]) { - if(sd->inventory_data[index]->type != 8){ - if(sd->inventory_data[index]->type == 10) - RFIFOW(fd,4)=0x8000; // 矢を無理やり装備できるように(−−; - pc_equipitem(sd,index,RFIFOW(fd,4)); - } else - pet_equipitem(sd,index); - } -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_UnequipItem(int fd,struct map_session_data *sd) -{ - int index; - - nullpo_retv(sd); - - if(pc_isdead(sd)) { - clif_clearchar_area(&sd->bl,1); - return; - } - if(sd->npc_id!=0 || sd->vender_id != 0 || sd->opt1 > 0) - return; - index = RFIFOW(fd,2)-2; - - /*if(sd->status.inventory[index].attribute == 1 && sd->sc_data && sd->sc_data[SC_BROKNWEAPON].timer!=-1) - status_change_end(&sd->bl,SC_BROKNWEAPON,-1); - if(sd->status.inventory[index].attribute == 1 && sd->sc_data && sd->sc_data[SC_BROKNARMOR].timer!=-1) - status_change_end(&sd->bl,SC_BROKNARMOR,-1); - if(sd->sc_count && ( sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1 )) - return;*/ - - pc_unequipitem(sd,index,1); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcClicked(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - if(pc_isdead(sd)) { - clif_clearchar_area(&sd->bl,1); - return; - } - if(sd->npc_id!=0 || sd->vender_id != 0) - return; - npc_click(sd,RFIFOL(fd,2)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcBuySellSelected(int fd,struct map_session_data *sd) -{ - npc_buysellsel(sd,RFIFOL(fd,2),RFIFOB(fd,6)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcBuyListSend(int fd,struct map_session_data *sd) -{ - int fail=0,n; - unsigned short *item_list; - - n = (RFIFOW(fd,2)-4) /4; - item_list = (unsigned short*)RFIFOP(fd,4); - - fail = npc_buylist(sd,n,item_list); - - WFIFOW(fd,0)=0xca; - WFIFOB(fd,2)=fail; - WFIFOSET(fd,packet_len_table[0xca]); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd) -{ - int fail=0,n; - unsigned short *item_list; - - n = (RFIFOW(fd,2)-4) /4; - item_list = (unsigned short*)RFIFOP(fd,4); - - fail = npc_selllist(sd,n,item_list); - - WFIFOW(fd,0)=0xcb; - WFIFOB(fd,2)=fail; - WFIFOSET(fd,packet_len_table[0xcb]); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_CreateChatRoom(int fd,struct map_session_data *sd) -{ - if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 4){ - chat_createchat(sd,RFIFOW(fd,4),RFIFOB(fd,6),(char*)RFIFOP(fd,7),(char*)RFIFOP(fd,15),RFIFOW(fd,2)-15); - } else - clif_skill_fail(sd,1,0,3); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ChatAddMember(int fd,struct map_session_data *sd) -{ - chat_joinchat(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ChatRoomStatusChange(int fd,struct map_session_data *sd) -{ - chat_changechatstatus(sd,RFIFOW(fd,4),RFIFOB(fd,6),(char*)RFIFOP(fd,7),(char*)RFIFOP(fd,15),RFIFOW(fd,2)-15); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ChangeChatOwner(int fd,struct map_session_data *sd) -{ - chat_changechatowner(sd,(char*)RFIFOP(fd,6)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_KickFromChat(int fd,struct map_session_data *sd) -{ - chat_kickchat(sd,(char*)RFIFOP(fd,2)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_ChatLeave(int fd,struct map_session_data *sd) -{ - chat_leavechat(sd); -} - -/*========================================== - * 取引要請を相手に送る - *------------------------------------------ - */ -void clif_parse_TradeRequest(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 1){ - trade_traderequest(sd,RFIFOL(sd->fd,2)); - } else - clif_skill_fail(sd,1,0,0); -} - -/*========================================== - * 取引要請 - *------------------------------------------ - */ -void clif_parse_TradeAck(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - trade_tradeack(sd,RFIFOB(sd->fd,2)); -} - -/*========================================== - * アイテム追加 - *------------------------------------------ - */ -void clif_parse_TradeAddItem(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - trade_tradeadditem(sd,RFIFOW(sd->fd,2),RFIFOL(sd->fd,4)); -} - -/*========================================== - * アイテム追加完了(ok押し) - *------------------------------------------ - */ -void clif_parse_TradeOk(int fd,struct map_session_data *sd) -{ - trade_tradeok(sd); -} - -/*========================================== - * 取引キャンセル - *------------------------------------------ - */ -void clif_parse_TradeCancel(int fd,struct map_session_data *sd) -{ - trade_tradecancel(sd); -} - -/*========================================== - * 取引許諾(trade押し) - *------------------------------------------ - */ -void clif_parse_TradeCommit(int fd,struct map_session_data *sd) -{ - trade_tradecommit(sd); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_StopAttack(int fd,struct map_session_data *sd) -{ - pc_stopattack(sd); -} - -/*========================================== - * カートへアイテムを移す - *------------------------------------------ - */ -void clif_parse_PutItemToCart(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - if(sd->npc_id!=0 || sd->vender_id != 0) - return; - pc_putitemtocart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4)); -} -/*========================================== - * カートからアイテムを出す - *------------------------------------------ - */ -void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - if(sd->npc_id!=0 || sd->vender_id != 0) return; - pc_getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4)); -} - -/*========================================== - * 付属品(鷹,ペコ,カート)をはずす - *------------------------------------------ - */ -void clif_parse_RemoveOption(int fd,struct map_session_data *sd) -{ - if(pc_isriding(sd)) { // jobchange when removing peco [Valaris] - if(sd->status.class_==13) - sd->status.class_=sd->view_class=7; - - if(sd->status.class_==21) - sd->status.class_=sd->view_class=14; - - if(sd->status.class_==4014) - sd->status.class_=sd->view_class=4008; - - if(sd->status.class_==4022) - sd->status.class_=sd->view_class=4015; - } - - pc_setoption(sd,0); -} - -/*========================================== - * チェンジカート - *------------------------------------------ - */ -void clif_parse_ChangeCart(int fd,struct map_session_data *sd) -{ - pc_setcart(sd,RFIFOW(fd,2)); -} - -/*========================================== - * ステータスアップ - *------------------------------------------ - */ -void clif_parse_StatusUp(int fd,struct map_session_data *sd) -{ - pc_statusup(sd,RFIFOW(fd,2)); -} - -/*========================================== - * スキルレベルアップ - *------------------------------------------ - */ -void clif_parse_SkillUp(int fd,struct map_session_data *sd) -{ - pc_skillup(sd,RFIFOW(fd,2)); -} - -/*========================================== - * スキル使用(ID指定) - *------------------------------------------ - */ -void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { - int skillnum, skilllv, lv, target_id; - unsigned int tick = gettick(); - - nullpo_retv(sd); - - if (sd->chatID || sd->npc_id != 0 || sd->vender_id != 0) - return; - - if (USE_PACKET_DB(sd)) { - skilllv = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - skillnum = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - target_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[2]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 6: - skilllv = RFIFOW(fd,4); - skillnum = RFIFOW(fd,9); - target_id = RFIFOL(fd,11); - break; - case 7: - skilllv = RFIFOW(fd,7); - skillnum = RFIFOW(fd,9); - target_id = RFIFOL(fd,15); - break; - case 8: - skilllv = RFIFOW(fd,7); - skillnum = RFIFOW(fd,12); - target_id = RFIFOL(fd,16); - break; - case 9: - skilllv = RFIFOW(fd,11); - skillnum = RFIFOW(fd,18); - target_id = RFIFOL(fd,22); - break; - case 10: - skilllv = RFIFOW(fd,9); - skillnum = RFIFOW(fd,15); - target_id = RFIFOL(fd,18); - break; - case 11: - skilllv = RFIFOW(fd,4); - skillnum = RFIFOW(fd,7); - target_id = RFIFOL(fd,10); - break; - case 12: - skilllv = RFIFOW(fd,7); - skillnum = RFIFOW(fd,12); - target_id = RFIFOL(fd,16); - break; - case 13: - case 14: - skilllv = RFIFOW(fd,4); - skillnum = RFIFOW(fd,10); - target_id = RFIFOL(fd,22); - break; - case 15: - skilllv = RFIFOW(fd,8); - skillnum = RFIFOW(fd,12); - target_id = RFIFOL(fd,18); - break; - case 16: - skilllv = RFIFOW(fd,8); - skillnum = RFIFOW(fd,16); - target_id = RFIFOL(fd,22); - break; - default: // old version by default - skilllv = RFIFOW(fd,2); - skillnum = RFIFOW(fd,4); - target_id = RFIFOL(fd,6); - break; - } - } - - if (skillnotok(skillnum, sd)) - return; - - if (sd->skilltimer != -1) { - if (skillnum != SA_CASTCANCEL) - return; - } else if (DIFF_TICK(tick, sd->canact_tick) < 0 && - // allow monk combos to ignore this delay [celest] - !(sd->sc_count && sd->sc_data[SC_COMBO].timer!=-1 && - (skillnum == MO_EXTREMITYFIST || - skillnum == MO_CHAINCOMBO || - skillnum == MO_COMBOFINISH || - skillnum == CH_PALMSTRIKE || - skillnum == CH_TIGERFIST || - skillnum == CH_CHAINCRUSH))) { - clif_skill_fail(sd, skillnum, 4, 0); - return; - } - - if ((sd->sc_data[SC_TRICKDEAD].timer != -1 && skillnum != NV_TRICKDEAD) || - sd->sc_data[SC_BERSERK].timer != -1 || sd->sc_data[SC_NOCHAT].timer != -1 || - sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class == 22) - return; - if (sd->invincible_timer != -1) - pc_delinvincibletimer(sd); - if (sd->skillitem >= 0 && sd->skillitem == skillnum) { - if (skilllv != sd->skillitemlv) - skilllv = sd->skillitemlv; - skill_use_id(sd, target_id, skillnum, skilllv); - } else { - sd->skillitem = sd->skillitemlv = -1; - if (skillnum == MO_EXTREMITYFIST) { - if ((sd->sc_data[SC_COMBO].timer == -1 || (sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH && sd->sc_data[SC_COMBO].val1 != CH_CHAINCRUSH))) { - if (!sd->state.skill_flag ) { - sd->state.skill_flag = 1; - clif_skillinfo(sd, MO_EXTREMITYFIST, 1, -1); - return; - } else if (sd->bl.id == target_id) { - clif_skillinfo(sd, MO_EXTREMITYFIST, 1, -1); - return; - } - } - } else if (skillnum == CH_TIGERFIST) { - if (sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) { - if (!sd->state.skill_flag ) { - sd->state.skill_flag = 1; - if (!sd->attacktarget) { - clif_skillinfo(sd, CH_TIGERFIST, 1, -2); - return; - } else - target_id = sd->attacktarget; - } else if (sd->bl.id == target_id) { - clif_skillinfo(sd, CH_TIGERFIST, 1, -2); - return; - } - } - } - if ((lv = pc_checkskill(sd, skillnum)) > 0) { - if (skilllv > lv) - skilllv = lv; - skill_use_id(sd, target_id, skillnum, skilllv); - if (sd->state.skill_flag) - sd->state.skill_flag = 0; - } - } -} - -/*========================================== - * スキル使用(場所指定) - *------------------------------------------ - */ -void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd) { - int skillnum, skilllv, lv, x, y; - unsigned int tick = gettick(); - int skillmoreinfo; - - nullpo_retv(sd); - - if (sd->npc_id != 0 || sd->vender_id != 0) return; - if(sd->chatID) return; - - skillmoreinfo = -1; - if (USE_PACKET_DB(sd)) { - skilllv = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - skillnum = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - x = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[2]); - y = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[3]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 6: - skilllv = RFIFOW(fd,4); - skillnum = RFIFOW(fd,9); - x = RFIFOW(fd,11); - y = RFIFOW(fd,13); - if (RFIFOW(fd,0) == 0x190) - skillmoreinfo = 15; - break; - case 7: - skilllv = RFIFOW(fd,7); - skillnum = RFIFOW(fd,9); - x = RFIFOW(fd,15); - y = RFIFOW(fd,17); - if (RFIFOW(fd,0) == 0x190) - skillmoreinfo = 19; - break; - case 8: - skilllv = RFIFOW(fd,3); - skillnum = RFIFOW(fd,6); - x = RFIFOW(fd,17); - y = RFIFOW(fd,21); - if (RFIFOW(fd,0) == 0x0a2) - skillmoreinfo = 23; - break; - case 9: - skilllv = RFIFOW(fd,5); - skillnum = RFIFOW(fd,15); - x = RFIFOW(fd,29); - y = RFIFOW(fd,38); - if (RFIFOW(fd,0) == 0x0a2) - skillmoreinfo = 40; - break; - case 10: - skilllv = RFIFOW(fd,10); - skillnum = RFIFOW(fd,14); - x = RFIFOW(fd,18); - y = RFIFOW(fd,23); - if (RFIFOW(fd,0) == 0x08c) - skillmoreinfo = 25; - break; - case 11: - skilllv = RFIFOW(fd,6); // 16? to check. - skillnum = RFIFOW(fd,20); - x = RFIFOW(fd,23); - y = RFIFOW(fd,27); - if (RFIFOW(fd,0) == 0x08c) - skillmoreinfo = 29; - break; - case 12: - skilllv = RFIFOW(fd,3); // 2? to check. - skillnum = RFIFOW(fd,6); - x = RFIFOW(fd,17); - y = RFIFOW(fd,21); - if (RFIFOW(fd,0) == 0x08c) - skillmoreinfo = 23; - break; - case 13: - case 14: - skilllv = RFIFOW(fd,6); - skillnum = RFIFOW(fd,9); - x = RFIFOW(fd,23); - y = RFIFOW(fd,26); - if (RFIFOW(fd,0) == 0x08c) - skillmoreinfo = 28; - break; - case 15: - skilllv = RFIFOW(fd,4); - skillnum = RFIFOW(fd,9); - x = RFIFOW(fd,22); - y = RFIFOW(fd,28); - if (RFIFOW(fd,0) == 0x113) - skillmoreinfo = 30; - break; - case 16: - skilllv = RFIFOW(fd,9); - skillnum = RFIFOW(fd,18); - x = RFIFOW(fd,22); - y = RFIFOW(fd,32); - if (RFIFOW(fd,0) == 0x07e) - skillmoreinfo = 34; - break; - default: // old version by default - skilllv = RFIFOW(fd,2); - skillnum = RFIFOW(fd,4); - x = RFIFOW(fd,6); - y = RFIFOW(fd,8); - if (RFIFOW(fd,0) == 0x190) - skillmoreinfo = 10; - break; - } - } - - if (skillnotok(skillnum, sd)) - return; - - if (skillmoreinfo != -1) { - if (pc_issit(sd)) { - clif_skill_fail(sd, skillnum, 0, 0); - return; - } - memcpy(talkie_mes, RFIFOP(fd,skillmoreinfo), 80); - } - - if (sd->skilltimer != -1) - return; - else if (DIFF_TICK(tick, sd->canact_tick) < 0 && - // allow monk combos to ignore this delay [celest] - !(sd->sc_count && sd->sc_data[SC_COMBO].timer!=-1 && - (skillnum == MO_EXTREMITYFIST || - skillnum == MO_CHAINCOMBO || - skillnum == MO_COMBOFINISH || - skillnum == CH_PALMSTRIKE || - skillnum == CH_TIGERFIST || - skillnum == CH_CHAINCRUSH))) { - clif_skill_fail(sd, skillnum, 4, 0); - return; - } - - if ((sd->sc_data[SC_TRICKDEAD].timer != -1 && skillnum != NV_TRICKDEAD) || - sd->sc_data[SC_BERSERK].timer != -1 || sd->sc_data[SC_NOCHAT].timer != -1 || - sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class == 22) - return; - if (sd->invincible_timer != -1) - pc_delinvincibletimer(sd); - if (sd->skillitem >= 0 && sd->skillitem == skillnum) { - if (skilllv != sd->skillitemlv) - skilllv = sd->skillitemlv; - skill_use_pos(sd, x, y, skillnum, skilllv); - } else { - sd->skillitem = sd->skillitemlv = -1; - if ((lv = pc_checkskill(sd, skillnum)) > 0) { - if (skilllv > lv) - skilllv = lv; - skill_use_pos(sd, x, y, skillnum,skilllv); - } - } -} - -/*========================================== - * スキル使用(map指定) - *------------------------------------------ - */ -void clif_parse_UseSkillMap(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - if(sd->chatID) return; - - if (sd->npc_id!=0 || sd->vender_id != 0 || (sd->sc_data && - (sd->sc_data[SC_TRICKDEAD].timer != -1 || - sd->sc_data[SC_BERSERK].timer!=-1 || - sd->sc_data[SC_NOCHAT].timer!=-1 || - sd->sc_data[SC_WEDDING].timer!=-1 || - sd->view_class==22))) - return; - - if(sd->invincible_timer != -1) - pc_delinvincibletimer(sd); - - skill_castend_map(sd,RFIFOW(fd,2),(char*)RFIFOP(fd,4)); -} -/*========================================== - * メモ要求 - *------------------------------------------ - */ -void clif_parse_RequestMemo(int fd,struct map_session_data *sd) -{ - pc_memo(sd,-1); -} -/*========================================== - * アイテム合成 - *------------------------------------------ - */ -void clif_parse_ProduceMix(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - sd->state.produce_flag = 0; - skill_produce_mix(sd,RFIFOW(fd,2),RFIFOW(fd,4),RFIFOW(fd,6),RFIFOW(fd,8)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - sd->npc_menu=RFIFOB(fd,6); - npc_scriptcont(sd,RFIFOL(fd,2)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcNextClicked(int fd,struct map_session_data *sd) -{ - npc_scriptcont(sd,RFIFOL(fd,2)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcAmountInput(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - -#define RFIFOL_(fd,pos) (*(int*)(session[fd]->rdata+session[fd]->rdata_pos+(pos))) - //Input Value overflow Exploit FIX - sd->npc_amount=RFIFOL_(fd,6); //fixed by Lupus. npc_amount is (int) but was RFIFOL changing it to (unsigned int) - -#undef RFIFOL_ - - npc_scriptcont(sd,RFIFOL(fd,2)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcStringInput(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - if(RFIFOW(fd,2)-7 >= sizeof(sd->npc_str)){ - printf("clif: input string too long !\n"); - memcpy(sd->npc_str,RFIFOP(fd,8),sizeof(sd->npc_str)); - sd->npc_str[sizeof(sd->npc_str)-1]=0; - } else - strcpy(sd->npc_str,(char*)RFIFOP(fd,8)); - npc_scriptcont(sd,RFIFOL(fd,4)); -} - -/*========================================== - * - *------------------------------------------ - */ -void clif_parse_NpcCloseClicked(int fd,struct map_session_data *sd) -{ - npc_scriptcont(sd,RFIFOL(fd,2)); -} - -/*========================================== - * アイテム鑑定 - *------------------------------------------ - */ -void clif_parse_ItemIdentify(int fd,struct map_session_data *sd) -{ - pc_item_identify(sd,RFIFOW(fd,2)-2); -} -/*========================================== - * 矢作成 - *------------------------------------------ - */ -void clif_parse_SelectArrow(int fd,struct map_session_data *sd) -{ - nullpo_retv(sd); - - sd->state.make_arrow_flag = 0; - skill_arrow_create(sd,RFIFOW(fd,2)); -} -/*========================================== - * オートスペル受信 - *------------------------------------------ - */ -void clif_parse_AutoSpell(int fd,struct map_session_data *sd) -{ - skill_autospell(sd,RFIFOW(fd,2)); -} -/*========================================== - * カード使用 - *------------------------------------------ - */ -void clif_parse_UseCard(int fd,struct map_session_data *sd) -{ - clif_use_card(sd,RFIFOW(fd,2)-2); -} -/*========================================== - * カード挿入装備選択 - *------------------------------------------ - */ -void clif_parse_InsertCard(int fd,struct map_session_data *sd) -{ - pc_insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2); -} - -/*========================================== - * 0193 キャラID名前引き - *------------------------------------------ - */ -void clif_parse_SolveCharName(int fd, struct map_session_data *sd) { - int char_id; - - if (USE_PACKET_DB(sd)) { - char_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - char_id = RFIFOL(fd,8); - break; - case 9: - char_id = RFIFOL(fd,7); - break; - case 10: - char_id = RFIFOL(fd,10); - break; - case 11: - char_id = RFIFOL(fd,6); - break; - case 12: - char_id = RFIFOL(fd,8); - break; - case 13: - case 14: - char_id = RFIFOL(fd,12); - break; - case 15: - char_id = RFIFOL(fd,10); - break; - case 16: - char_id = RFIFOL(fd,7); - break; - default: // old version by default (+ packet version 6 and 7) - char_id = RFIFOL(fd,2); - break; - } - } - clif_solved_charname(sd, char_id); -} - -/*========================================== - * 0197 /resetskill /resetstate - *------------------------------------------ - */ -void clif_parse_ResetChar(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - pc_isGM(sd) >= get_atcommand_level(AtCommand_ResetState)) { - switch(RFIFOW(fd,2)){ - case 0: - pc_resetstate(sd); - break; - case 1: - pc_resetskill(sd); - break; - } - } -} - -/*========================================== - * 019c /lb等 - *------------------------------------------ - */ -void clif_parse_LGMmessage(int fd, struct map_session_data *sd) { - unsigned char buf[512]; - - nullpo_retv(sd); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_LocalBroadcast))) { - WBUFW(buf,0) = 0x9a; - WBUFW(buf,2) = RFIFOW(fd,2); - memcpy(WBUFP(buf,4), RFIFOP(fd,4), RFIFOW(fd,2) - 4); - clif_send(buf, RFIFOW(fd,2), &sd->bl, ALL_SAMEMAP); - } -} - -/*========================================== - * カプラ倉庫へ入れる - *------------------------------------------ - */ -void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) { - int item_index, item_amount; - - nullpo_retv(sd); - - if (sd->npc_id != 0 || sd->vender_id != 0) - return; - - if (USE_PACKET_DB(sd)) { - item_index = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-2; - item_amount = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - item_index = RFIFOW(fd,5) - 2; - item_amount = RFIFOL(fd,12); - break; - case 9: - item_index = RFIFOW(fd,5) - 2; - item_amount = RFIFOL(fd,19); - break; - case 10: - item_index = RFIFOW(fd,3) - 2; - item_amount = RFIFOL(fd,15); - break; - case 11: - item_index = RFIFOW(fd,6) - 2; - item_amount = RFIFOL(fd,21); - break; - case 12: - item_index = RFIFOW(fd,5) - 2; - item_amount = RFIFOL(fd,12); - break; - case 13: - case 14: - item_index = RFIFOW(fd,6) - 2; - item_amount = RFIFOL(fd,9); - break; - case 15: - item_index = RFIFOW(fd,4) - 2; - item_amount = RFIFOL(fd,10); - break; - case 16: - item_index = RFIFOW(fd,10) - 2; - item_amount = RFIFOL(fd,16); - break; - default: // old version by default (+ packet version 6 and 7) - item_index = RFIFOW(fd,2) - 2; - item_amount = RFIFOL(fd,4); - break; - } - } - - if (item_index < 0 || item_index >= MAX_INVENTORY) - return; - - if(itemdb_isdropable(sd->status.inventory[item_index].nameid) == 0) - return; - - if (sd->state.storage_flag) - storage_guild_storageadd(sd, item_index, item_amount); - else - storage_storageadd(sd, item_index, item_amount); -} - -/*========================================== - * カプラ倉庫から出す - *------------------------------------------ - */ -void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) { - int item_index, item_amount; - - nullpo_retv(sd); - - if (USE_PACKET_DB(sd)) { - item_index = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-1; - item_amount = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]); - } else { - switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - case 8: - item_index = RFIFOW(fd,10) - 1; - item_amount = RFIFOL(fd,22); - break; - case 9: - item_index = RFIFOW(fd,11) - 1; - item_amount = RFIFOL(fd,22); - break; - case 10: - item_index = RFIFOW(fd,3) - 1; - item_amount = RFIFOL(fd,13); - break; - case 11: - item_index = RFIFOW(fd,4) - 1; - item_amount = RFIFOL(fd,8); - break; - case 12: - item_index = RFIFOW(fd,10) - 1; - item_amount = RFIFOL(fd,22); - break; - case 13: - case 14: - item_index = RFIFOW(fd,12) - 1; - item_amount = RFIFOL(fd,18); - break; - case 15: - item_index = RFIFOW(fd,4) - 1; - item_amount = RFIFOL(fd,17); - break; - case 16: - item_index = RFIFOW(fd,11) - 1; - item_amount = RFIFOL(fd,17); - break; - default: // old version by default (+ packet version 6 and 7) - item_index = RFIFOW(fd,2) - 1; - item_amount = RFIFOL(fd,4); - break; - } - } - - if (sd->npc_id != 0 || sd->vender_id != 0) - return; - - if (sd->state.storage_flag) - storage_guild_storageget(sd, item_index, item_amount); - else - storage_storageget(sd, item_index, item_amount); -} - -/*========================================== - * カプラ倉庫へカートから入れる - *------------------------------------------ - */ -void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if (sd->npc_id != 0 || sd->vender_id != 0 || sd->trade_partner != 0) - return; - if (sd->state.storage_flag) - storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); - else - storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); -} - -/*========================================== - * カプラ倉庫から出す - *------------------------------------------ - */ -void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if (sd->npc_id != 0 || sd->vender_id != 0) - return; - if (sd->state.storage_flag) - storage_guild_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); - else - storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); -} - -/*========================================== - * カプラ倉庫を閉じる - *------------------------------------------ - */ -void clif_parse_CloseKafra(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if (sd->state.storage_flag) - storage_guild_storageclose(sd); - else - storage_storageclose(sd); -} - -/*========================================== - * パーティを作る - *------------------------------------------ - */ -void clif_parse_CreateParty(int fd, struct map_session_data *sd) { - if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7) { - party_create(sd,(char*)RFIFOP(fd,2),0,0); - } else - clif_skill_fail(sd,1,0,4); -} - -/*========================================== - * パーティを作る - *------------------------------------------ - */ -void clif_parse_CreateParty2(int fd, struct map_session_data *sd) { - if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7){ - party_create(sd,(char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27)); - } else - clif_skill_fail(sd,1,0,4); -} - -/*========================================== - * パーティに勧誘 - *------------------------------------------ - */ -void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { - party_invite(sd, RFIFOL(fd,2)); -} - -/*========================================== - * パーティ勧誘返答 - *------------------------------------------ - */ -void clif_parse_ReplyPartyInvite(int fd,struct map_session_data *sd) { - if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 5){ - party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6)); - } else { - party_reply_invite(sd,RFIFOL(fd,2),-1); - clif_skill_fail(sd,1,0,4); - } -} - -/*========================================== - * パーティ脱退要求 - *------------------------------------------ - */ -void clif_parse_LeaveParty(int fd, struct map_session_data *sd) { - party_leave(sd); -} - -/*========================================== - * パーティ除名要求 - *------------------------------------------ - */ -void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) { - party_removemember(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6)); -} - -/*========================================== - * パーティ設定変更要求 - *------------------------------------------ - */ -void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) { - party_changeoption(sd, RFIFOW(fd,2), RFIFOW(fd,4)); -} - -/*========================================== - * パーティメッセージ送信要求 - *------------------------------------------ - */ -void clif_parse_PartyMessage(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if (is_charcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != CharCommand_None || - is_atcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != AtCommand_None || - (sd->sc_data && - (sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク時は会話も不可 - sd->sc_data[SC_NOCHAT].timer!=-1))) //チャット禁止 - return; - - party_send_message(sd, (char*)RFIFOP(fd,4), RFIFOW(fd,2)-4); -} - -/*========================================== - * 露店閉鎖 - *------------------------------------------ - */ -void clif_parse_CloseVending(int fd, struct map_session_data *sd) { - vending_closevending(sd); -} - -/*========================================== - * 露店アイテムリスト要求 - *------------------------------------------ - */ -void clif_parse_VendingListReq(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - vending_vendinglistreq(sd,RFIFOL(fd,2)); - if(sd->npc_id) - npc_event_dequeue(sd); -} - -/*========================================== - * 露店アイテム購入 - *------------------------------------------ - */ -void clif_parse_PurchaseReq(int fd, struct map_session_data *sd) { - vending_purchasereq(sd, RFIFOW(fd,2), RFIFOL(fd,4), RFIFOP(fd,8)); -} - -/*========================================== - * 露店開設 - *------------------------------------------ - */ -void clif_parse_OpenVending(int fd,struct map_session_data *sd) { - vending_openvending(sd, RFIFOW(fd,2), (char*)RFIFOP(fd,4), RFIFOB(fd,84), RFIFOP(fd,85)); -} - -/*========================================== - * ギルドを作る - *------------------------------------------ - */ -void clif_parse_CreateGuild(int fd,struct map_session_data *sd) { - guild_create(sd, (char*)RFIFOP(fd,6)); -} - -/*========================================== - * ギルドマスターかどうか確認 - *------------------------------------------ - */ -void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd) { - clif_guild_masterormember(sd); -} - -/*========================================== - * ギルド情報要求 - *------------------------------------------ - */ -void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) { - switch(RFIFOL(fd,2)){ - case 0: // ギルド基本情報、同盟敵対情報 - clif_guild_basicinfo(sd); - clif_guild_allianceinfo(sd); - break; - case 1: // メンバーリスト、役職名リスト - clif_guild_positionnamelist(sd); - clif_guild_memberlist(sd); - break; - case 2: // 役職名リスト、役職情報リスト - clif_guild_positionnamelist(sd); - clif_guild_positioninfolist(sd); - break; - case 3: // スキルリスト - clif_guild_skillinfo(sd); - break; - case 4: // 追放リスト - clif_guild_explusionlist(sd); - break; - default: - if (battle_config.error_log) - printf("clif: guild request info: unknown type %d\n", RFIFOL(fd,2)); - break; - } -} - -/*========================================== - * ギルド役職変更 - *------------------------------------------ - */ -void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) { - int i; - - for(i = 4; i < RFIFOW(fd,2); i += 40 ){ - guild_change_position(sd, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), (char*)RFIFOP(fd,i+16)); - } -} - -/*========================================== - * ギルドメンバ役職変更 - *------------------------------------------ - */ -void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd) { - int i; - - nullpo_retv(sd); - - for(i=4;i<RFIFOW(fd,2);i+=12){ - guild_change_memberposition(sd->status.guild_id, - RFIFOL(fd,i),RFIFOL(fd,i+4),RFIFOL(fd,i+8)); - } -} - -/*========================================== - * ギルドエンブレム要求 - *------------------------------------------ - */ -void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd) { - struct guild *g=guild_search(RFIFOL(fd,2)); - if(g!=NULL) - clif_guild_emblem(sd,g); -} - -/*========================================== - * ギルドエンブレム変更 - *------------------------------------------ - */ -void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd) { - guild_change_emblem(sd,RFIFOW(fd,2)-4,(char*)RFIFOP(fd,4)); -} - -/*========================================== - * ギルド告知変更 - *------------------------------------------ - */ -void clif_parse_GuildChangeNotice(int fd,struct map_session_data *sd) { - guild_change_notice(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6),(char*)RFIFOP(fd,66)); -} - -/*========================================== - * ギルド勧誘 - *------------------------------------------ - */ -void clif_parse_GuildInvite(int fd,struct map_session_data *sd) { - guild_invite(sd,RFIFOL(fd,2)); -} - -/*========================================== - * ギルド勧誘返信 - *------------------------------------------ - */ -void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd) { - guild_reply_invite(sd,RFIFOL(fd,2),RFIFOB(fd,6)); -} - -/*========================================== - * ギルド脱退 - *------------------------------------------ - */ -void clif_parse_GuildLeave(int fd,struct map_session_data *sd) { - guild_leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14)); -} - -/*========================================== - * ギルド追放 - *------------------------------------------ - */ -void clif_parse_GuildExplusion(int fd,struct map_session_data *sd) { - guild_explusion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14)); -} - -/*========================================== - * ギルド会話 - *------------------------------------------ - */ -void clif_parse_GuildMessage(int fd,struct map_session_data *sd) { - nullpo_retv(sd); - - if (is_charcommand(fd, sd, (char*)RFIFOP(fd, 4), 0) != CharCommand_None || - is_atcommand(fd, sd, (char*)RFIFOP(fd, 4), 0) != AtCommand_None || - (sd->sc_data && - (sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク時は会話も不可 - sd->sc_data[SC_NOCHAT].timer!=-1))) //チャット禁止 - return; - - guild_send_message(sd, (char*)RFIFOP(fd,4), RFIFOW(fd,2)-4); -} - -/*========================================== - * ギルド同盟要求 - *------------------------------------------ - */ -void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) { - guild_reqalliance(sd,RFIFOL(fd,2)); -} - -/*========================================== - * ギルド同盟要求返信 - *------------------------------------------ - */ -void clif_parse_GuildReplyAlliance(int fd, struct map_session_data *sd) { - guild_reply_reqalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6)); -} - -/*========================================== - * ギルド関係解消 - *------------------------------------------ - */ -void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) { - guild_delalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6)); -} - -/*========================================== - * ギルド敵対 - *------------------------------------------ - */ -void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) { - guild_opposition(sd,RFIFOL(fd,2)); -} - -/*========================================== - * ギルド解散 - *------------------------------------------ - */ -void clif_parse_GuildBreak(int fd, struct map_session_data *sd) { - guild_break(sd,(char*)RFIFOP(fd,2)); -} - -// pet -void clif_parse_PetMenu(int fd, struct map_session_data *sd) { - pet_menu(sd,RFIFOB(fd,2)); -} - -void clif_parse_CatchPet(int fd, struct map_session_data *sd) { - pet_catch_process2(sd,RFIFOL(fd,2)); -} - -void clif_parse_SelectEgg(int fd, struct map_session_data *sd) { - pet_select_egg(sd,RFIFOW(fd,2)-2); -} - -void clif_parse_SendEmotion(int fd, struct map_session_data *sd) { - nullpo_retv(sd); - - if(sd->pd) - clif_pet_emotion(sd->pd,RFIFOL(fd,2)); -} - -void clif_parse_ChangePetName(int fd, struct map_session_data *sd) { - pet_change_name(sd,(char*)RFIFOP(fd,2)); -} - -// Kick (right click menu for GM "(name) force to quit") -void clif_parse_GMKick(int fd, struct map_session_data *sd) { - struct block_list *target; - int tid = RFIFOL(fd,2); - - nullpo_retv(sd); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_Kick))) { - target = map_id2bl(tid); - if (target) { - if (target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - if (pc_isGM(sd) > pc_isGM(tsd)) - clif_GM_kick(sd, tsd, 1); - else - clif_GM_kickack(sd, 0); - } else if (target->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)target; - sd->state.attack_type = 0; - mob_damage(&sd->bl, md, md->hp, 2); - } else - clif_GM_kickack(sd, 0); - } else - clif_GM_kickack(sd, 0); - } -} - -/*========================================== - * /shift - *------------------------------------------ - */ -void clif_parse_Shift(int fd, struct map_session_data *sd) { // Rewriten by [Yor] - char player_name[25]; - - nullpo_retv(sd); - - memset(player_name, '\0', sizeof(player_name)); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_JumpTo))) { - memcpy(player_name, RFIFOP(fd,2), 24); - atcommand_jumpto(fd, sd, "@jumpto", player_name); // as @jumpto - } - - return; -} - -/*========================================== - * /recall - *------------------------------------------ - */ -void clif_parse_Recall(int fd, struct map_session_data *sd) { // Added by RoVeRT - char player_name[25]; - - nullpo_retv(sd); - - memset(player_name, '\0', sizeof(player_name)); - - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_Recall))) { - memcpy(player_name, RFIFOP(fd,2), 24); - atcommand_recall(fd, sd, "@recall", player_name); // as @recall - } - - return; -} - -/*========================================== - * /monster /item rewriten by [Yor] - *------------------------------------------ - */ -void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) { - char monster_item_name[25]; - - nullpo_retv(sd); - - memset(monster_item_name, '\0', sizeof(monster_item_name)); - - if (battle_config.atc_gmonly == 0 || pc_isGM(sd)) { - memcpy(monster_item_name, RFIFOP(fd,2), 24); - - if (mobdb_searchname(monster_item_name) != 0) { - if (pc_isGM(sd) >= get_atcommand_level(AtCommand_Monster)) - atcommand_spawn(fd, sd, "@spawn", monster_item_name); // as @spawn - } else if (itemdb_searchname(monster_item_name) != NULL) { - if (pc_isGM(sd) >= get_atcommand_level(AtCommand_Item)) - atcommand_item(fd, sd, "@item", monster_item_name); // as @item - } - - } -} - -void clif_parse_GMHide(int fd, struct map_session_data *sd) { // Modified by [Yor] - nullpo_retv(sd); - - //printf("%2x %2x %2x\n", RFIFOW(fd,0), RFIFOW(fd,2), RFIFOW(fd,4)); // R 019d <Option_value>.2B <flag>.2B - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_Hide))) { - if (sd->status.option & OPTION_HIDE) { // OPTION_HIDE = 0x40 - sd->status.option &= ~OPTION_HIDE; // OPTION_HIDE = 0x40 - clif_displaymessage(fd, "Invisible: Off."); - } else { - sd->status.option |= OPTION_HIDE; // OPTION_HIDE = 0x40 - clif_displaymessage(fd, "Invisible: On."); - } - clif_changeoption(&sd->bl); - } -} - -/*========================================== - * GMによるチャット禁止時間付与 - *------------------------------------------ - */ -void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) -{ - int tid = RFIFOL(fd,2); - int type = RFIFOB(fd,6); - int limit = RFIFOW(fd,7); - struct block_list *bl = map_id2bl(tid); - struct map_session_data *dstsd; - int dstfd; - - nullpo_retv(sd); - - if(!battle_config.muting_players) { - clif_displaymessage(fd, "Muting is disabled."); - return; - } - - if(type == 0) - limit = 0 - limit; - if(bl->type == BL_PC && (dstsd =(struct map_session_data *)bl)){ - if((tid == bl->id && type == 2 && !pc_isGM(sd)) || (pc_isGM(sd) > pc_isGM(dstsd)) ){ - dstfd = dstsd->fd; - WFIFOW(dstfd,0)=0x14b; - WFIFOB(dstfd,2)=(type==2)?1:type; - memcpy(WFIFOP(dstfd,3),sd->status.name,24); - WFIFOSET(dstfd,packet_len_table[0x14b]); - dstsd->status.manner -= limit; - if(dstsd->status.manner < 0) - status_change_start(bl,SC_NOCHAT,0,0,0,0,0,0); - else{ - dstsd->status.manner = 0; - status_change_end(bl,SC_NOCHAT,-1); - } - printf("name:%s type:%d limit:%d manner:%d\n",dstsd->status.name,type,limit,dstsd->status.manner); - } - } - - return; -} -/*========================================== - * GMによるチャット禁止時間参照(?) - *------------------------------------------ - */ -void clif_parse_GMReqNoChatCount(int fd, struct map_session_data *sd) -{ - int tid = RFIFOL(fd,2); - - WFIFOW(fd,0) = 0x1e0; - WFIFOL(fd,2) = tid; - sprintf((char*)WFIFOP(fd,6),"%d",tid); -// memcpy(WFIFOP(fd,6), "TESTNAME", 24); - WFIFOSET(fd, packet_len_table[0x1e0]); - - return; -} - -void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by [Yor] - char output[512]; - char *nick; // S 00cf <nick>.24B <type>.B: 00 (/ex nick) deny speech from nick, 01 (/in nick) allow speech from nick - int i, pos; - - memset(output, '\0', sizeof(output)); - - nick = (char*)RFIFOP(fd,2); // speed up - RFIFOB(fd,25) = '\0'; // to be sure that the player name have at maximum 23 characters - //printf("Ignore: char '%s' state: %d\n", nick, RFIFOB(fd,26)); - - WFIFOW(fd,0) = 0x0d1; // R 00d1 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail - WFIFOB(fd,2) = RFIFOB(fd,26); - // do nothing only if nick can not exist - if (strlen(nick) < 4) { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - if (RFIFOB(fd,26) == 0) // type - clif_wis_message(fd, wisp_server_name, "It's impossible to block this player.", strlen("It's impossible to block this player.") + 1); - else - clif_wis_message(fd, wisp_server_name, "It's impossible to unblock this player.", strlen("It's impossible to unblock this player.") + 1); - return; - // name can exist - } else { - // deny action (we add nick only if it's not already exist - if (RFIFOB(fd,26) == 0) { // type - pos = -1; - for(i = 0; i < MAX_IGNORE_LIST; i++) { - if (strcmp(sd->ignore[i].name, nick) == 0) { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - clif_wis_message(fd, wisp_server_name, "This player is already blocked.", strlen("This player is already blocked.") + 1); - if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. - sprintf(output, "Character '%s' (account: %d) has tried AGAIN to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); - } - return; - } else if (pos == -1 && sd->ignore[i].name[0] == '\0') - pos = i; - } - // if a position is found and name not found, we add it in the list - if (pos != -1) { - memcpy(sd->ignore[pos].name, nick, 24); - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d1]); - if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. - sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); - // send something to be inform and force bot to ignore twice... If GM receiving block + block again, it's a bot :) - clif_wis_message(fd, wisp_server_name, "Add me in your ignore list, doesn't block my wisps.", strlen("Add me in your ignore list, doesn't block my wisps.") + 1); - } - } else { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - clif_wis_message(fd, wisp_server_name, "You can not block more people.", strlen("You can not block more people.") + 1); - if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people. - sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name); - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output); - } - } - // allow action (we remove all same nicks if they exist) - } else { - pos = -1; - for(i = 0; i < MAX_IGNORE_LIST; i++) - if (strcmp(sd->ignore[i].name, nick) == 0) { - memset(sd->ignore[i].name, 0, sizeof(sd->ignore[i].name)); - if (pos == -1) { - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d1]); - pos = i; // don't break, to remove ALL same nick - } - } - if (pos == -1) { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d1]); - clif_wis_message(fd, wisp_server_name, "This player is not blocked by you.", strlen("This player is not blocked by you.") + 1); - } - } - } - -// for(i = 0; i < MAX_IGNORE_LIST; i++) // for debug only -// if (sd->ignore[i].name[0] != '\0') -// printf("Ignored player: '%s'\n", sd->ignore[i].name); - - return; -} - -void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { // Rewritten by [Yor] - //printf("Ignore all: state: %d\n", RFIFOB(fd,2)); - if (RFIFOB(fd,2) == 0) {// S 00d0 <type>len.B: 00 (/exall) deny all speech, 01 (/inall) allow all speech - WFIFOW(fd,0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail - WFIFOB(fd,2) = 0; - if (sd->ignoreAll == 0) { - sd->ignoreAll = 1; - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d2]); - } else { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d2]); - clif_wis_message(fd, wisp_server_name, "You already block everyone.", strlen("You already block everyone.") + 1); - } - } else { - WFIFOW(fd,0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail - WFIFOB(fd,2) = 1; - if (sd->ignoreAll == 1) { - sd->ignoreAll = 0; - WFIFOB(fd,3) = 0; // success - WFIFOSET(fd, packet_len_table[0x0d2]); - } else { - WFIFOB(fd,3) = 1; // fail - WFIFOSET(fd, packet_len_table[0x0d2]); - clif_wis_message(fd, wisp_server_name, "You already allow everyone.", strlen("You already allow everyone.") + 1); - } - } - - return; -} - -/*========================================== - * Wis拒否リスト - *------------------------------------------ - */ - int pstrcmp(const void *a, const void *b) -{ - return strcmp((char *)a, (char *)b); -} -void clif_parse_PMIgnoreList(int fd,struct map_session_data *sd) -{ - int i,j=0,count=0; - - qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp); - for(i = 0; i < MAX_IGNORE_LIST; i++){ //中身があるのを数える - if(sd->ignore[i].name[0] != 0) - count++; - } - WFIFOW(fd,0) = 0xd4; - WFIFOW(fd,2) = 4 + (24 * count); - for(i = 0; i < MAX_IGNORE_LIST; i++){ - if(sd->ignore[i].name[0] != 0){ - memcpy(WFIFOP(fd, 4 + j * 24),sd->ignore[i].name, 24); - j++; - } - } - WFIFOSET(fd, WFIFOW(fd,2)); - if(count >= MAX_IGNORE_LIST) //満タンなら最後の1個を消す - sd->ignore[MAX_IGNORE_LIST - 1].name[0] = 0; - - return; -} - -void clif_parse_skillMessage(int fd, struct map_session_data *sd) { // Added by RoVeRT - int skillid,skilllv, x, y; - char *mes; - - skilllv = RFIFOW(fd,2); - skillid = RFIFOW(fd,4); - - y = RFIFOB(fd,6); - x = RFIFOB(fd,8); - - mes = (char*)RFIFOP(fd,10); - - // skill 220 = graffiti -// printf("skill: %d %d location: %3d %3d message: %s\n", skillid, skilllv, x, y, (char*)mes); -} - -int monk(struct map_session_data *sd, struct block_list *target, int type) { -//R 01d1 <Monk id>L <Target monster id>L <Bool>L - int fd=sd->fd; - WFIFOW(fd,0)=0x1d1; - WFIFOL(fd,2)=sd->bl.id; - WFIFOL(fd,6)=target->id; - WFIFOL(fd,10)=type; - WFIFOSET(fd,packet_len_table[0x1d1]); - - return 0; -} - -/*========================================== - * スパノビの/doridoriによるSPR2倍 - *------------------------------------------ - */ -void clif_parse_sn_doridori(int fd, struct map_session_data *sd) { - if (sd) - sd->doridori_counter = 1; - - return; -} -/*========================================== - * スパノビの爆裂波動 - *------------------------------------------ - */ -void clif_parse_sn_explosionspirits(int fd, struct map_session_data *sd) -{ - if(sd){ - int nextbaseexp=pc_nextbaseexp(sd); - struct pc_base_job s_class = pc_calc_base_job(sd->status.class_); - if (battle_config.etc_log){ - if(nextbaseexp != 0) - printf("SuperNovice explosionspirits!! %d %d %d %d\n",sd->bl.id,s_class.job,sd->status.base_exp,(int)((double)1000*sd->status.base_exp/nextbaseexp)); - else - printf("SuperNovice explosionspirits!! %d %d %d 000\n",sd->bl.id,s_class.job,sd->status.base_exp); - } - if(s_class.job == 23 && sd->status.base_exp > 0 && nextbaseexp > 0 && (int)((double)1000*sd->status.base_exp/nextbaseexp)%100==0){ - clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,5,1); - status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],5,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,5),0 ); - } - } - return; -} - -/*========================================== - * Friends List - *------------------------------------------ - */ -void clif_friends_list_send(struct map_session_data *sd) { - int i, n; - - // Send friends list - n = 0; - WFIFOW(sd->fd, 0) = 0x201; - for(i = 0; i < 20; i++) - if (sd->status.friend_id[i]) { - WFIFOL(sd->fd,4 + 32 * n + 1) = sd->status.friend_id[i]; - //WFIFOB(sd->fd,4 + 32 * n + 5) = (online[n]) ? 0 : 1; // <- We don't know this yet. I'd reckon its 5 but... i could be wrong. - memcpy(WFIFOP(sd->fd,4 + 32 * n + 8), &sd->status.friend_name[i], 23); - n++; - } - WFIFOW(sd->fd,2) = 4 + 32 * n; - WFIFOSET(sd->fd, WFIFOW(sd->fd,2)); -} - -void clif_parse_friends_list_add(int fd, struct map_session_data *sd) { - struct map_session_data *f_sd; - int i; - - f_sd = map_nick2sd((char*)RFIFOP(fd,2)); - - // Friend doesn't exist (no player with this name) - if (f_sd == NULL) { - clif_displaymessage(fd, "This name (for a friend) doesn't exist."); - return; - } - - // Friend already exists - for (i = 0; i < 20; i++) - if (sd->status.friend_id[i] == f_sd->status.char_id) { - clif_displaymessage(fd, "Friend already exists."); - return; - } - - // Find an empty slot - for (i = 0; i < 20; i++) - if (sd->status.friend_id[i] == 0) - break; - if (i == 20) { - clif_displaymessage(fd, "Friends list is full."); - return; - } - - sd->status.friend_id[i] = f_sd->status.char_id; - memset(sd->status.friend_name[i], 0, sizeof(sd->status.friend_name[i])); - memcpy(sd->status.friend_name[i], f_sd->status.name, 23); - clif_displaymessage(fd, "Friend added."); - - clif_friends_list_send(sd); - - //printf("clif_parse_friends_list_add"); - - return; -} - -void clif_parse_friends_list_remove(int fd, struct map_session_data *sd) { - // 0x203 </o> <ID to be removed W 4B> - int id = RFIFOL(fd,3); - int i, j; - - // Search friend - for (i = 0; i < 20; i ++) - if (sd->status.friend_id[i] == id) { - // move all chars down - for(j = i + 1; j < 20; j++) { - sd->status.friend_id[j-1] = sd->status.friend_id[j]; - memcpy(sd->status.friend_name[j-1], sd->status.friend_name[j], sizeof(sd->status.friend_name[j])); - } - sd->status.friend_id[19] = 0; - memset(sd->status.friend_name[19], 0, sizeof(sd->status.friend_name[19])); - clif_displaymessage(fd, "Friend removed"); - clif_friends_list_send(sd); - break; - } - - if (i == 20) - clif_displaymessage(fd, "Name not found in list."); - - return; -} - -/*========================================== - * /killall - *------------------------------------------ - */ -void clif_parse_GMkillall(int fd,struct map_session_data *sd) -{ - char message[50]; - - nullpo_retv(sd); - - strncpy(message,sd->status.name, 24); - is_atcommand(fd, sd, strcat(message," : @kickall"),0); - - return; -} - -/*========================================== - * パケットデバッグ - *------------------------------------------ - */ -void clif_parse_debug(int fd,struct map_session_data *sd) -{ - int i, cmd; - - cmd = RFIFOW(fd,0); - - printf("packet debug 0x%4X\n",cmd); - printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F"); - for(i=0;i<packet_db[sd->packet_ver][cmd].len;i++){ - if((i&15)==0) - printf("\n%04X ",i); - printf("%02X ",RFIFOB(fd,i)); - } - printf("\n"); -} - -// functions list -static void (*clif_parse_func_table[MAX_PACKET_DB])(int, struct map_session_data *) = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - // 40 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - // 70 - NULL, NULL, clif_parse_WantToConnection, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, clif_parse_LoadEndAck, clif_parse_TickSend, NULL, - - // 80 - NULL, NULL, NULL, NULL, NULL, clif_parse_WalkToXY, NULL, NULL, - NULL, clif_parse_ActionRequest, NULL, NULL, clif_parse_GlobalMessage, NULL, NULL, NULL, - // 90 - clif_parse_NpcClicked, NULL, NULL, NULL, clif_parse_GetCharNameRequest, NULL, clif_parse_Wis, NULL, - NULL, clif_parse_GMmessage, NULL, clif_parse_ChangeDir, NULL, NULL, NULL, clif_parse_TakeItem, - // a0 - NULL, NULL, clif_parse_DropItem, NULL, NULL, NULL, NULL, clif_parse_UseItem, - NULL, clif_parse_EquipItem, NULL, clif_parse_UnequipItem, NULL, NULL, NULL, NULL, - // b0 - NULL, NULL, clif_parse_Restart, NULL, NULL, NULL, NULL, NULL, - clif_parse_NpcSelectMenu, clif_parse_NpcNextClicked, NULL, clif_parse_StatusUp, NULL, NULL, NULL, clif_parse_Emotion, - - // c0 - NULL, clif_parse_HowManyConnections, NULL, NULL, NULL, clif_parse_NpcBuySellSelected, NULL, NULL, - clif_parse_NpcBuyListSend, clif_parse_NpcSellListSend, NULL, NULL, clif_parse_GMKick, NULL, clif_parse_GMkillall, clif_parse_PMIgnore, - // d0 - clif_parse_PMIgnoreAll, NULL, NULL, clif_parse_PMIgnoreList, NULL, clif_parse_CreateChatRoom, NULL, NULL, - NULL, clif_parse_ChatAddMember, NULL, NULL, NULL, NULL, clif_parse_ChatRoomStatusChange, NULL, - // e0 - clif_parse_ChangeChatOwner, NULL, clif_parse_KickFromChat, clif_parse_ChatLeave, clif_parse_TradeRequest, NULL, clif_parse_TradeAck, NULL, - clif_parse_TradeAddItem, NULL, NULL, clif_parse_TradeOk, NULL, clif_parse_TradeCancel, NULL, clif_parse_TradeCommit, - // f0 - NULL, NULL, NULL, clif_parse_MoveToKafra, NULL, clif_parse_MoveFromKafra, NULL, clif_parse_CloseKafra, - NULL, clif_parse_CreateParty, NULL, NULL, clif_parse_PartyInvite, NULL, NULL, clif_parse_ReplyPartyInvite, - - // 100 - clif_parse_LeaveParty, NULL, clif_parse_PartyChangeOption, clif_parse_RemovePartyMember, NULL, NULL, NULL, NULL, - clif_parse_PartyMessage, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - // 110 - NULL, NULL, clif_parse_SkillUp, clif_parse_UseSkillToId, NULL, NULL, clif_parse_UseSkillToPos, NULL, - clif_parse_StopAttack, NULL, NULL, clif_parse_UseSkillMap, NULL, clif_parse_RequestMemo, NULL, NULL, - // 120 - NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_PutItemToCart, clif_parse_GetItemFromCart, - clif_parse_MoveFromKafraToCart, clif_parse_MoveToKafraFromCart, clif_parse_RemoveOption, NULL, NULL, NULL, clif_parse_CloseVending, NULL, - // 130 - clif_parse_VendingListReq, NULL, NULL, NULL, clif_parse_PurchaseReq, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_GM_Monster_Item, - - // 140 - clif_parse_MapMove, NULL, NULL, clif_parse_NpcAmountInput, NULL, NULL, clif_parse_NpcCloseClicked, NULL, - NULL, clif_parse_GMReqNoChat, NULL, NULL, NULL, clif_parse_GuildCheckMaster, NULL, clif_parse_GuildRequestInfo, - // 150 - NULL, clif_parse_GuildRequestEmblem, NULL, clif_parse_GuildChangeEmblem, NULL, clif_parse_GuildChangeMemberPosition, NULL, NULL, - NULL, clif_parse_GuildLeave, NULL, clif_parse_GuildExplusion, NULL, clif_parse_GuildBreak, NULL, NULL, - // 160 - NULL, clif_parse_GuildChangePositionInfo, NULL, NULL, NULL, clif_parse_CreateGuild, NULL, NULL, - clif_parse_GuildInvite, NULL, NULL, clif_parse_GuildReplyInvite, NULL, NULL, clif_parse_GuildChangeNotice, NULL, - // 170 - clif_parse_GuildRequestAlliance, NULL, clif_parse_GuildReplyAlliance, NULL, NULL, NULL, NULL, NULL, - clif_parse_ItemIdentify, NULL, clif_parse_UseCard, NULL, clif_parse_InsertCard, NULL, clif_parse_GuildMessage, NULL, - - // 180 - clif_parse_GuildOpposition, NULL, NULL, clif_parse_GuildDelAlliance, NULL, NULL, NULL, NULL, - NULL, NULL, clif_parse_QuitGame, NULL, NULL, NULL, clif_parse_ProduceMix, NULL, - // 190 - clif_parse_UseSkillToPos, NULL, NULL, clif_parse_SolveCharName, NULL, NULL, NULL, clif_parse_ResetChar, - NULL, NULL, NULL, NULL, clif_parse_LGMmessage, clif_parse_GMHide, NULL, clif_parse_CatchPet, - // 1a0 - NULL, clif_parse_PetMenu, NULL, NULL, NULL, clif_parse_ChangePetName, NULL, clif_parse_SelectEgg, - NULL, clif_parse_SendEmotion, NULL, NULL, NULL, NULL, clif_parse_SelectArrow, clif_parse_ChangeCart, - // 1b0 - NULL, NULL, clif_parse_OpenVending, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, clif_parse_Shift, clif_parse_Shift, clif_parse_Recall, clif_parse_Recall, NULL, NULL, - - // 1c0 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_AutoSpell, - NULL, - // 1d0 - NULL, NULL, NULL, NULL, NULL, clif_parse_NpcStringInput, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_GMReqNoChatCount, - // 1e0 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_sn_doridori, - clif_parse_CreateParty2, NULL, NULL, NULL, NULL, clif_parse_sn_explosionspirits, NULL, NULL, - // 1f0 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_ReqAdopt, - NULL, NULL, NULL, NULL, NULL, NULL, - - // 200 - NULL, NULL, clif_parse_friends_list_add, clif_parse_friends_list_remove, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - // 210 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if 0 - case 0xd3: clif_parse_IgnoreList -#endif -}; - -/*========================================== - * クライアントからのパケット解析 - * socket.cのdo_parsepacketから呼び出される - *------------------------------------------ - */ -static int clif_parse(int fd) { - int packet_len = 0, cmd, packet_ver, dump = 0; - struct map_session_data *sd; - - sd = (struct map_session_data*)session[fd]->session_data; - - // 接続が切れてるので後始末 - if (!chrif_isconnect() || session[fd]->eof) { // char鯖に繋がってない間は接続禁止 (!chrif_isconnect()) - if (sd && sd->state.auth) { - clif_quitsave(fd, sd); // the function doesn't send to inter-server/char-server if it is not connected [Yor] - if (sd->status.name != NULL) - sprintf(tmp_output,"%sCharacter '"CL_WHITE"%s"CL_RESET"' logged off.\n", (pc_isGM(sd))?"GM ":"",sd->status.name); // Player logout display [Valaris] - else - sprintf(tmp_output,"%sCharacter with Account ID '"CL_WHITE"%d"CL_RESET"' logged off.\n", (pc_isGM(sd))?"GM ":"", sd->bl.id); // Player logout display [Yor] - } else if (sd) { // not authentified! (refused by char-server or disconnect before to be authentified) - sprintf(tmp_output,"Player not authenticated with Account ID '"CL_WHITE"%d"CL_RESET"' logged off.\n", sd->bl.id); // Player logout display [Yor] -// if (chrif_isconnect()) -// clif_quitsave(fd, sd); - map_deliddb(&sd->bl); // account_id has been included in the DB before auth answer [Yor] -// sd = 0; - } else { - unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr; - sprintf(tmp_output,"Player not identified with IP '"CL_WHITE"%d.%d.%d.%d"CL_RESET"' logged off.\n", ip[0],ip[1],ip[2],ip[3]); - } - ShowInfo(tmp_output); - close(fd); -// if (sd) // 追加 -// map_deliddb(&sd->bl); // 追加 - delete_session(fd); - return 0; - } - - if (RFIFOREST(fd) < 2) - return 0; - -// printf("clif_parse: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd)); - - cmd = RFIFOW(fd,0); - - // 管理用パケット処理 - if (cmd >= 30000) { - switch(cmd) { - case 0x7530: // Athena情報所得 - WFIFOW(fd,0) = 0x7531; - WFIFOB(fd,2) = ATHENA_MAJOR_VERSION; - WFIFOB(fd,3) = ATHENA_MINOR_VERSION; - WFIFOB(fd,4) = ATHENA_REVISION; - WFIFOB(fd,5) = ATHENA_RELEASE_FLAG; - WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG; - WFIFOB(fd,7) = ATHENA_SERVER_MAP; - WFIFOW(fd,8) = ATHENA_MOD_VERSION; - WFIFOSET(fd,10); - RFIFOSKIP(fd,2); - break; - case 0x7532: // 接続の切断 - close(fd); - session[fd]->eof=1; - break; - } - return 0; - } - - // get packet version before to parse - packet_ver = 0; - if (sd) { - packet_ver = sd->packet_ver; - if (packet_ver < 0 || packet_ver > MAX_PACKET_VER) { // unusual, but just in case - close(fd); - session[fd]->eof = 1; - printf("clif_parse: session #%d, bad packet version -> disconnected.\n", fd); - return 0; - } - // check authentification packet to know packet version - } else { - // packet DB - if (IS_PACKET_DB_VER (cmd)) { - if (RFIFOREST(fd) >= packet_db[clif_config.packet_db_ver][cmd].len && - (RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[4]) == 0 || - RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[4]) == 1)) {// 00 = Female, 01 = Male - packet_ver = clif_config.packet_db_ver; - } - // 0x72 - } else if (cmd == 0x72) { - if (RFIFOREST(fd) >= 39 && (RFIFOB(fd,38) == 0 || RFIFOB(fd,38) == 1)) // 00 = Female, 01 = Male - packet_ver = 7; // 7: 13july04 - else if (RFIFOREST(fd) >= 22 && (RFIFOB(fd,21) == 0 || RFIFOB(fd,21) == 1)) // 00 = Female, 01 = Male - packet_ver = 6; // 6: 7july04 - else if (RFIFOREST(fd) >= 19 && (RFIFOB(fd,18) == 0 || RFIFOB(fd,18) == 1)) // 00 = Female, 01 = Male - packet_ver = 5; // 5: old - // else probably incomplete packet - else if (RFIFOREST(fd) < 19) - return 0; - // 0x7E - } else if (cmd == 0x7E) { - if (RFIFOREST(fd) >= 37 && (RFIFOB(fd,36) == 0 || RFIFOB(fd,36) == 1)) // 00 = Female, 01 = Male - packet_ver = 9; // 9: 9aug04/16aug04/17aug04 - else if (RFIFOREST(fd) >= 33 && (RFIFOB(fd,32) == 0 || RFIFOB(fd,32) == 1)) // 00 = Female, 01 = Male - packet_ver = 8; // 8: 26july04 - // else probably incomplete packet - else if (RFIFOREST(fd) < 33) - return 0; - // 0xF5 - } else if (cmd == 0xF5) { - if (RFIFOREST(fd) >= 34 && (RFIFOB(fd,33) == 0 || RFIFOB(fd,33) == 1)) // 00 = Female, 01 = Male - packet_ver = 10; // 10: 6sept04 - else if (RFIFOREST(fd) >= 33 && (RFIFOB(fd,32) == 0 || RFIFOB(fd,32) == 1)) // 00 = Female, 01 = Male - packet_ver = 12; // 12: 18oct04 - else if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) // 00 = Female, 01 = Male - packet_ver = 11; // 11: 21sept04 - else if (RFIFOREST(fd) >= 29 && (RFIFOB(fd,28) == 0 || RFIFOB(fd,28) == 1)) { // 00 = Female, 01 = Male - if (RFIFOL(fd,3) > 700000 && RFIFOL(fd,10) >= 150000 && RFIFOL(fd,10) < 5000000) // account id / char id (more than 5.000.000 characters?) [Yor] - packet_ver = 15; // 14: 6dec04 - else - packet_ver = 13; // 13: 25oct04 (by [Yor]) - } - // else probably incomplete packet - else if (RFIFOREST(fd) < 29) - return 0; - // 0x9B - } else if (cmd == 0x9B) { - if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) // 00 = Female, 01 = Male - packet_ver = 16; // 16: 10jan05 - else if (RFIFOREST(fd) < 32) - return 0; - } else { - // unknown client? leave packet ver as 0 so it'll disconnect anyway - } - - // check if version is accepted - if (packet_ver < 5 || // reject really old client versions - (packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) || // older than 6sept04 - (packet_ver == 10 && (battle_config.packet_ver_flag & 2) == 0) || - (packet_ver == 11 && (battle_config.packet_ver_flag & 4) == 0) || - (packet_ver == 12 && (battle_config.packet_ver_flag & 8) == 0) || - (packet_ver == 13 && (battle_config.packet_ver_flag & 16) == 0) || - (packet_ver == 14 && (battle_config.packet_ver_flag & 32) == 0) || - (packet_ver == 15 && (battle_config.packet_ver_flag & 64) == 0) || - (packet_ver == 16 && (battle_config.packet_ver_flag & 128) == 0) || - packet_ver > MAX_PACKET_VER || // no packet version support yet - // identified version, but unknown client? - (!sd && packet_db[packet_ver][cmd].func != clif_parse_WantToConnection)) { - WFIFOW(fd,0) = 0x6a; - WFIFOB(fd,2) = 5; // 05 = Game's EXE is not the latest version - WFIFOSET(fd,23); - clif_setwaitclose(fd); - return 0; - } - } - - // ゲーム用以外パケットか、認証を終える前に0072以外が来たら、切断する - if (cmd >= MAX_PACKET_DB || packet_db[packet_ver][cmd].len == 0) { // if packet is not inside these values: session is incorrect?? or auth packet is unknown - if (!fd) - return 0; - close(fd); - session[fd]->eof = 1; - printf("clif_parse: session #%d, packet 0x%x (%d bytes received) -> disconnected.\n", fd, cmd, RFIFOREST(fd)); - return 0; - } - - // パケット長を計算 - packet_len = packet_db[packet_ver][cmd].len; - if (packet_len == -1) { - if (RFIFOREST(fd) < 4) - return 0; // 可変長パケットで長さの所までデータが来てない - packet_len = RFIFOW(fd,2); - if (packet_len < 4 || packet_len > 32768) { - close(fd); - session[fd]->eof =1; - return 0; - } - } - if (RFIFOREST(fd) < packet_len) - return 0; // まだ1パケット分データが揃ってない - - #if DUMP_ALL_PACKETS - dump = 1; - #endif - - if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1) { // 切断待ちの場合パケットを処理しない - - } else if (packet_db[packet_ver][cmd].func) { // packet version 5-6-7 use same functions, but size are different - // パケット処理 - packet_db[packet_ver][cmd].func(fd, sd); - } else { - // 不明なパケット - if (battle_config.error_log) { -#if DUMP_UNKNOWN_PACKET - { - int i; - FILE *fp; - char packet_txt[256] = "save/packet.txt"; - time_t now; - dump = 1; - - if ((fp = fopen(packet_txt, "a")) == NULL) { - printf("clif.c: cant write [%s] !!! data is lost !!!\n", packet_txt); - return 1; - } else { - time(&now); - if (sd && sd->state.auth) { - if (sd->status.name != NULL) - fprintf(fp, "%sPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n", - asctime(localtime(&now)), sd->status.account_id, sd->status.char_id, sd->status.name); - else - fprintf(fp, "%sPlayer with account ID %d sent wrong packet:\n", asctime(localtime(&now)), sd->bl.id); - } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified) - fprintf(fp, "%sPlayer with account ID %d sent wrong packet:\n", asctime(localtime(&now)), sd->bl.id); - - fprintf(fp, "\t---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F"); - for(i = 0; i < packet_len; i++) { - if ((i & 15) == 0) - fprintf(fp, "\n\t%04X ", i); - fprintf(fp, "%02X ", RFIFOB(fd,i)); - } - fprintf(fp, "\n\n"); - fclose(fp); - } - } -#endif - } - } - - if (dump) { - int i; - if (fd) - printf("\nclif_parse: session #%d, packet 0x%x, lenght %d\n", fd, cmd, packet_len); - printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F"); - for(i = 0; i < packet_len; i++) { - if ((i & 15) == 0) - printf("\n%04X ",i); - printf("%02X ", RFIFOB(fd,i)); - } - if (sd && sd->state.auth) { - if (sd->status.name != NULL) - printf("\nAccount ID %d, character ID %d, player name %s.\n", - sd->status.account_id, sd->status.char_id, sd->status.name); - else - printf("\nAccount ID %d.\n", sd->bl.id); - } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified) - printf("\nAccount ID %d.\n", sd->bl.id); - } - - RFIFOSKIP(fd, packet_len); - - return 0; -} - -/*========================================== - * パケットデータベース読み込み - *------------------------------------------ - */ -static int packetdb_readdb(void) -{ - FILE *fp; - char line[1024]; - int ln=0; - int cmd,j,k,packet_ver; - char *str[64],*p,*str2[64],*p2,w1[64],w2[64]; - - struct { - void (*func)(int, struct map_session_data *); - char *name; - } clif_parse_func[]={ - {clif_parse_WantToConnection,"wanttoconnection"}, - {clif_parse_LoadEndAck,"loadendack"}, - {clif_parse_TickSend,"ticksend"}, - {clif_parse_WalkToXY,"walktoxy"}, - {clif_parse_QuitGame,"quitgame"}, - {clif_parse_GetCharNameRequest,"getcharnamerequest"}, - {clif_parse_GlobalMessage,"globalmessage"}, - {clif_parse_MapMove,"mapmove"}, - {clif_parse_ChangeDir,"changedir"}, - {clif_parse_Emotion,"emotion"}, - {clif_parse_HowManyConnections,"howmanyconnections"}, - {clif_parse_ActionRequest,"actionrequest"}, - {clif_parse_Restart,"restart"}, - {clif_parse_Wis,"wis"}, - {clif_parse_GMmessage,"gmmessage"}, - {clif_parse_TakeItem,"takeitem"}, - {clif_parse_DropItem,"dropitem"}, - {clif_parse_UseItem,"useitem"}, - {clif_parse_EquipItem,"equipitem"}, - {clif_parse_UnequipItem,"unequipitem"}, - {clif_parse_NpcClicked,"npcclicked"}, - {clif_parse_NpcBuySellSelected,"npcbuysellselected"}, - {clif_parse_NpcBuyListSend,"npcbuylistsend"}, - {clif_parse_NpcSellListSend,"npcselllistsend"}, - {clif_parse_CreateChatRoom,"createchatroom"}, - {clif_parse_ChatAddMember,"chataddmember"}, - {clif_parse_ChatRoomStatusChange,"chatroomstatuschange"}, - {clif_parse_ChangeChatOwner,"changechatowner"}, - {clif_parse_KickFromChat,"kickfromchat"}, - {clif_parse_ChatLeave,"chatleave"}, - {clif_parse_TradeRequest,"traderequest"}, - {clif_parse_TradeAck,"tradeack"}, - {clif_parse_TradeAddItem,"tradeadditem"}, - {clif_parse_TradeOk,"tradeok"}, - {clif_parse_TradeCancel,"tradecancel"}, - {clif_parse_TradeCommit,"tradecommit"}, - {clif_parse_StopAttack,"stopattack"}, - {clif_parse_PutItemToCart,"putitemtocart"}, - {clif_parse_GetItemFromCart,"getitemfromcart"}, - {clif_parse_RemoveOption,"removeoption"}, - {clif_parse_ChangeCart,"changecart"}, - {clif_parse_StatusUp,"statusup"}, - {clif_parse_SkillUp,"skillup"}, - {clif_parse_UseSkillToId,"useskilltoid"}, - {clif_parse_UseSkillToPos,"useskilltopos"}, - {clif_parse_UseSkillMap,"useskillmap"}, - {clif_parse_RequestMemo,"requestmemo"}, - {clif_parse_ProduceMix,"producemix"}, - {clif_parse_NpcSelectMenu,"npcselectmenu"}, - {clif_parse_NpcNextClicked,"npcnextclicked"}, - {clif_parse_NpcAmountInput,"npcamountinput"}, - {clif_parse_NpcStringInput,"npcstringinput"}, - {clif_parse_NpcCloseClicked,"npccloseclicked"}, - {clif_parse_ItemIdentify,"itemidentify"}, - {clif_parse_SelectArrow,"selectarrow"}, - {clif_parse_AutoSpell,"autospell"}, - {clif_parse_UseCard,"usecard"}, - {clif_parse_InsertCard,"insertcard"}, - {clif_parse_SolveCharName,"solvecharname"}, - {clif_parse_ResetChar,"resetchar"}, - {clif_parse_LGMmessage,"lgmmessage"}, - {clif_parse_MoveToKafra,"movetokafra"}, - {clif_parse_MoveFromKafra,"movefromkafra"}, - {clif_parse_MoveToKafraFromCart,"movetokafrafromcart"}, - {clif_parse_MoveFromKafraToCart,"movefromkafratocart"}, - {clif_parse_CloseKafra,"closekafra"}, - {clif_parse_CreateParty,"createparty"}, - {clif_parse_CreateParty2,"createparty2"}, - {clif_parse_PartyInvite,"partyinvite"}, - {clif_parse_ReplyPartyInvite,"replypartyinvite"}, - {clif_parse_LeaveParty,"leaveparty"}, - {clif_parse_RemovePartyMember,"removepartymember"}, - {clif_parse_PartyChangeOption,"partychangeoption"}, - {clif_parse_PartyMessage,"partymessage"}, - {clif_parse_CloseVending,"closevending"}, - {clif_parse_VendingListReq,"vendinglistreq"}, - {clif_parse_PurchaseReq,"purchasereq"}, - {clif_parse_OpenVending,"openvending"}, - {clif_parse_CreateGuild,"createguild"}, - {clif_parse_GuildCheckMaster,"guildcheckmaster"}, - {clif_parse_GuildRequestInfo,"guildrequestinfo"}, - {clif_parse_GuildChangePositionInfo,"guildchangepositioninfo"}, - {clif_parse_GuildChangeMemberPosition,"guildchangememberposition"}, - {clif_parse_GuildRequestEmblem,"guildrequestemblem"}, - {clif_parse_GuildChangeEmblem,"guildchangeemblem"}, - {clif_parse_GuildChangeNotice,"guildchangenotice"}, - {clif_parse_GuildInvite,"guildinvite"}, - {clif_parse_GuildReplyInvite,"guildreplyinvite"}, - {clif_parse_GuildLeave,"guildleave"}, - {clif_parse_GuildExplusion,"guildexplusion"}, - {clif_parse_GuildMessage,"guildmessage"}, - {clif_parse_GuildRequestAlliance,"guildrequestalliance"}, - {clif_parse_GuildReplyAlliance,"guildreplyalliance"}, - {clif_parse_GuildDelAlliance,"guilddelalliance"}, - {clif_parse_GuildOpposition,"guildopposition"}, - {clif_parse_GuildBreak,"guildbreak"}, - {clif_parse_PetMenu,"petmenu"}, - {clif_parse_CatchPet,"catchpet"}, - {clif_parse_SelectEgg,"selectegg"}, - {clif_parse_SendEmotion,"sendemotion"}, - {clif_parse_ChangePetName,"changepetname"}, - {clif_parse_GMKick,"gmkick"}, - {clif_parse_GMHide,"gmhide"}, - {clif_parse_GMReqNoChat,"gmreqnochat"}, - {clif_parse_GMReqNoChatCount,"gmreqnochatcount"}, - {clif_parse_sn_doridori,"sndoridori"}, - {clif_parse_sn_explosionspirits,"snexplosionspirits"}, - {clif_parse_PMIgnore,"wisexin"}, - {clif_parse_PMIgnoreList,"wisexlist"}, - {clif_parse_PMIgnoreAll,"wisall"}, - {clif_parse_friends_list_add,"friendslistadd"}, - {clif_parse_friends_list_remove,"friendslistremove"}, - {clif_parse_GMkillall,"killall"}, - {clif_parse_Recall,"summon"}, - {clif_parse_GM_Monster_Item,"itemmonster"}, - {clif_parse_Shift,"shift"}, - {clif_parse_debug,"debug"}, - - {NULL,NULL} - }; - - if( (fp=fopen("db/packet_db.txt","r"))==NULL ){ - printf("can't read db/packet_db.txt\n"); - return 1; - } - - clif_config.packet_db_ver = MAX_PACKET_VER; - packet_ver = MAX_PACKET_VER; // read into packet_db's version by default - - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - if (sscanf(line,"%[^:]: %[^\r\n]",w1,w2) == 2) { - if(strcmpi(w1,"packet_ver")==0) { - packet_ver = atoi(w2); - // copy from previous version into new version and continue - // - indicating all following packets should be read into the newer version - // -- on 2nd thought, rereading everything isn't the best thing to do... - // memcpy(&packet_db[packet_ver], &packet_db[packet_ver - 1], sizeof(packet_db[0])); - continue; - } else if(strcmpi(w1,"packet_db_ver")==0) { - // optional: if you do not wish to read multiple versions from the packet_db, - // remove all "packet_ver: ##" lines, and define the packet DB version with this - if(strcmpi(w2,"default")==0) - clif_config.packet_db_ver = MAX_PACKET_VER; - else { - // to manually set the packet DB version - clif_config.packet_db_ver = atoi(w2); - // check for invalid version - if (clif_config.packet_db_ver > MAX_PACKET_VER || - clif_config.packet_db_ver < 0) - clif_config.packet_db_ver = MAX_PACKET_VER; - } - continue; - } else if(strcmpi(w1,"enable_packet_db")==0) { - // whether we want to allow identifying clients via the packet DB - clif_config.enable_packet_db = battle_config_switch(w2); - // if we don't want to read the packet DB, and use hardcoded values only - if (!clif_config.enable_packet_db) - return 0; - continue; - } else if(strcmpi(w1,"prefer_packet_db")==0) { - // whether the packet DB takes higher precedence over the hardcoded one (type 1) - // and whether to overwrite predefined packet length and functions when reading - // from the DB (type 2) - clif_config.prefer_packet_db = battle_config_switch(w2); // not used for now - continue; - } - } - - memset(str,0,sizeof(str)); - for(j=0,p=line;j<4 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if(str[0]==NULL) - continue; - cmd=strtol(str[0],(char **)NULL,0); - if(cmd<=0 || cmd>=MAX_PACKET_DB) - continue; - if(str[1]==NULL){ - sprintf(tmp_output, "packet_db: packet len error\n"); - ShowError(tmp_output); - continue; - } - k = atoi(str[1]); - // if (packet_db[packet_ver][cmd].len != k && clif_config.prefer_packet_db) // not used for now - packet_db[packet_ver][cmd].len = k; - - if(str[2]==NULL){ - ln++; - continue; - } - for(j=0;j<sizeof(clif_parse_func)/sizeof(clif_parse_func[0]);j++){ - if(clif_parse_func[j].name != NULL && - strcmp(str[2],clif_parse_func[j].name)==0){ - // if (packet_db[packet_ver][cmd].func != clif_parse_func[j].func && !clif_config.prefer_packet_db) - // break; // not used for now - packet_db[packet_ver][cmd].func = clif_parse_func[j].func; - break; - } - } - // set the identifying cmd for the packet_db version - if (strcmp(str[2],"wanttoconnection")==0){ - clif_config.connect_cmd = cmd; - } - if(str[3]==NULL){ - sprintf(tmp_output, "packet_db: packet error\n"); - ShowError(tmp_output); - exit(1); - } - for(j=0,p2=str[3];p2;j++){ - str2[j]=p2; - p2=strchr(p2,':'); - if(p2) *p2++=0; - k = atoi(str2[j]); - // if (packet_db[packet_ver][cmd].pos[j] != k && clif_config.prefer_packet_db) // not used for now - packet_db[packet_ver][cmd].pos[j] = k; - } - - ln++; -// if(packet_db[clif_config.packet_db_ver][cmd].len > 2 /* && packet_db[cmd].pos[0] == 0 */) -// printf("packet_db ver %d: %d 0x%x %d %s %p\n",packet_ver,ln,cmd,packet_db[packet_ver][cmd].len,str[2],packet_db[packet_ver][cmd].func); - } - - fclose(fp); - sprintf(tmp_output,"Done reading packet version '"CL_WHITE"%d"CL_RESET"' in '"CL_WHITE"%s"CL_RESET"'.\n", clif_config.packet_db_ver, "db/packet_db.txt"); - ShowStatus(tmp_output); - return 0; - -} - -/*========================================== - * - *------------------------------------------ - */ -int do_init_clif(void) { - int i; - - clif_config.enable_packet_db = 1; // whether to use the packet DB for client connection - clif_config.packet_db_ver = -1; // the main packet version of the DB - clif_config.prefer_packet_db = 1; // whether the packet version takes precedence - clif_config.connect_cmd = 0xF5; // the default packet used for connecting to the server - - memset(packet_db,0,sizeof(packet_db)); - - // size of packet version 5 (old) - for(i=0;i<sizeof(packet_len_table)/sizeof(packet_len_table[0]);i++){ - packet_db[0][i].len = packet_len_table[i]; - } - // packet functions of version 5 (old) - for(i=0;i<sizeof(clif_parse_func_table)/sizeof(clif_parse_func_table[0]);i++){ - packet_db[0][i].func = clif_parse_func_table[i]; - } - - // using hardcoded packet values isn't necessary with packet_db now, - // but... just in case, i'll leave it to initialise for now ^^; - // init packet version 5 and lower - memcpy(&packet_db[1], &packet_db[0], sizeof(packet_db[0])); - memcpy(&packet_db[2], &packet_db[1], sizeof(packet_db[0])); - memcpy(&packet_db[3], &packet_db[2], sizeof(packet_db[0])); - memcpy(&packet_db[4], &packet_db[3], sizeof(packet_db[0])); - memcpy(&packet_db[5], &packet_db[4], sizeof(packet_db[0])); - -#ifndef PREFER_PACKET_DB - // functions of packet version 5-6-7 are same, but size are different - // size of packet version 6 (7july04) - memcpy(&packet_db[6], &packet_db[5], sizeof(packet_db[0])); - packet_db[6][0x072].len = 22; - packet_db[6][0x085].len = 8; - packet_db[6][0x0a7].len = 13; - packet_db[6][0x113].len = 15; - packet_db[6][0x116].len = 15; - packet_db[6][0x190].len = 95; - // size of packet version 7 (13july04) - memcpy(&packet_db[7], &packet_db[6], sizeof(packet_db[0])); - packet_db[7][0x072].len = 39; - packet_db[7][0x085].len = 9; - packet_db[7][0x09b].len = 13; - packet_db[7][0x09f].len = 10; - packet_db[7][0x0a7].len = 17; - packet_db[7][0x113].len = 19; - packet_db[7][0x116].len = 19; - packet_db[7][0x190].len = 99; - // init packet function calls for packet ver 8 - memcpy(packet_db[8], packet_db[7], sizeof(packet_db[0])); - packet_db[8][0x072].func = clif_parse_DropItem; - packet_db[8][0x07e].func = clif_parse_WantToConnection; - packet_db[8][0x085].func = clif_parse_UseSkillToId; - packet_db[8][0x089].func = clif_parse_GetCharNameRequest; - packet_db[8][0x08c].func = clif_parse_UseSkillToPos; - packet_db[8][0x094].func = clif_parse_TakeItem; - packet_db[8][0x09b].func = clif_parse_WalkToXY; - packet_db[8][0x09f].func = clif_parse_ChangeDir; - packet_db[8][0x0a2].func = clif_parse_UseSkillToPos; - packet_db[8][0x0a7].func = clif_parse_SolveCharName; - packet_db[8][0x0f3].func = clif_parse_GlobalMessage; - packet_db[8][0x0f5].func = clif_parse_UseItem; - packet_db[8][0x0f7].func = clif_parse_TickSend; - packet_db[8][0x113].func = clif_parse_MoveToKafra; - packet_db[8][0x116].func = clif_parse_CloseKafra; - packet_db[8][0x190].func = clif_parse_MoveFromKafra; - packet_db[8][0x193].func = clif_parse_ActionRequest; - // size of packet version 8 (26july04) - packet_db[8][0x072].len = 14; - packet_db[8][0x07e].len = 33; - packet_db[8][0x085].len = 20; - packet_db[8][0x089].len = 15; - packet_db[8][0x08c].len = 23; - packet_db[8][0x094].len = 10; - packet_db[8][0x09b].len = 6; - packet_db[8][0x09f].len = 13; - packet_db[8][0x0a2].len = 103; - packet_db[8][0x0a7].len = 12; - packet_db[8][0x0f3].len = -1; - packet_db[8][0x0f5].len = 17; - packet_db[8][0x0f7].len = 10; - packet_db[8][0x113].len = 16; - packet_db[8][0x116].len = 2; - packet_db[8][0x190].len = 26; - packet_db[8][0x193].len = 9; - // init packet function calls for packet ver 9 (same function of packet version 8, but size are different) - memcpy(packet_db[9], packet_db[8], sizeof(packet_db[0])); - // size of packet version 9 (9aug04/16aug04/17aug04) - packet_db[9][0x072].len = 17; - packet_db[9][0x07e].len = 37; - packet_db[9][0x085].len = 26; - packet_db[9][0x089].len = 12; - packet_db[9][0x08c].len = 40; - packet_db[9][0x094].len = 13; - packet_db[9][0x09b].len = 15; - packet_db[9][0x09f].len = 12; - packet_db[9][0x0a2].len = 120; - packet_db[9][0x0a7].len = 11; -// packet_db[9][0x0f3].len = -1; - packet_db[9][0x0f5].len = 24; - packet_db[9][0x0f7].len = 13; - packet_db[9][0x113].len = 23; -// packet_db[9][0x116].len = 2; - packet_db[9][0x190].len = 26; - packet_db[9][0x193].len = 18; - // new packet - packet_db[9][0x20f].len = 10; - packet_db[9][0x210].len = 22; - packet_db[9][0x212].len = 26; - packet_db[9][0x213].len = 26; - packet_db[9][0x214].len = 42; - // init packet function calls for packet ver 10 - memcpy(packet_db[10], packet_db[9], sizeof(packet_db[0])); - packet_db[10][0x072].func = clif_parse_UseItem; - packet_db[10][0x07e].func = clif_parse_MoveToKafra; - packet_db[10][0x085].func = clif_parse_ActionRequest; - packet_db[10][0x089].func = clif_parse_WalkToXY; - packet_db[10][0x08c].func = clif_parse_UseSkillToPos; - packet_db[10][0x094].func = clif_parse_DropItem; - packet_db[10][0x09b].func = clif_parse_GetCharNameRequest; - packet_db[10][0x09f].func = clif_parse_GlobalMessage; - packet_db[10][0x0a2].func = clif_parse_SolveCharName; - packet_db[10][0x0a7].func = clif_parse_UseSkillToPos; - packet_db[10][0x0f3].func = clif_parse_ChangeDir; - packet_db[10][0x0f5].func = clif_parse_WantToConnection; - packet_db[10][0x0f7].func = clif_parse_CloseKafra; - packet_db[10][0x113].func = clif_parse_TakeItem; - packet_db[10][0x116].func = clif_parse_TickSend; - packet_db[10][0x190].func = clif_parse_UseSkillToId; - packet_db[10][0x193].func = clif_parse_MoveFromKafra; - // size of packet version 10 (6sept04) - packet_db[10][0x072].len = 20; - packet_db[10][0x07e].len = 19; - packet_db[10][0x085].len = 23; - packet_db[10][0x089].len = 9; - packet_db[10][0x08c].len = 105; - packet_db[10][0x094].len = 17; - packet_db[10][0x09b].len = 14; - packet_db[10][0x09f].len = -1; - packet_db[10][0x0a2].len = 14; - packet_db[10][0x0a7].len = 25; - packet_db[10][0x0f3].len = 10; - packet_db[10][0x0f5].len = 34; - packet_db[10][0x0f7].len = 2; - packet_db[10][0x113].len = 11; - packet_db[10][0x116].len = 11; - packet_db[10][0x190].len = 22; - packet_db[10][0x193].len = 17; - // init packet function calls for packet ver 11 (same function of packet version 10, but size are different) - memcpy(packet_db[11], packet_db[10], sizeof(packet_db[0])); - // size of packet version 11 (21sept04) - packet_db[11][0x072].len = 18; - packet_db[11][0x07e].len = 25; - packet_db[11][0x085].len = 9; - packet_db[11][0x089].len = 14; - packet_db[11][0x08c].len = 109; - packet_db[11][0x094].len = 19; - packet_db[11][0x09b].len = 10; -// packet_db[11][0x09f].len = -1; - packet_db[11][0x0a2].len = 10; - packet_db[11][0x0a7].len = 29; - packet_db[11][0x0f3].len = 18; - packet_db[11][0x0f5].len = 32; -// packet_db[11][0x0f7].len = 2; - packet_db[11][0x113].len = 14; - packet_db[11][0x116].len = 14; - packet_db[11][0x190].len = 14; - packet_db[11][0x193].len = 12; - // init packet function calls for packet ver 12 (same function of packet version 11, but size are different) - memcpy(packet_db[12], packet_db[11], sizeof(packet_db[0])); - // size of packet version 12 (18oct04) - packet_db[12][0x072].len = 17; - packet_db[12][0x07e].len = 16; -// packet_db[12][0x085].len = 9; - packet_db[12][0x089].len = 6; - packet_db[12][0x08c].len = 103; - packet_db[12][0x094].len = 14; - packet_db[12][0x09b].len = 15; -// packet_db[12][0x09f].len = -1; - packet_db[12][0x0a2].len = 12; - packet_db[12][0x0a7].len = 23; - packet_db[12][0x0f3].len = 13; - packet_db[12][0x0f5].len = 33; -// packet_db[12][0x0f7].len = 2; - packet_db[12][0x113].len = 10; - packet_db[12][0x116].len = 10; - packet_db[12][0x190].len = 20; - packet_db[12][0x193].len = 26; - // init packet function calls for packet ver 13 (same function of packet version 12, but size are different) - memcpy(packet_db[13], packet_db[12], sizeof(packet_db[0])); - // size of packet version 13 (25oct04) - packet_db[13][0x072].len = 13; - packet_db[13][0x07e].len = 13; - packet_db[13][0x085].len = 15; -// packet_db[13][0x089].len = 6; - packet_db[13][0x08c].len = 108; - packet_db[13][0x094].len = 12; - packet_db[13][0x09b].len = 10; -// packet_db[13][0x09f].len = -1; - packet_db[13][0x0a2].len = 16; - packet_db[13][0x0a7].len = 28; - packet_db[13][0x0f3].len = 15; - packet_db[13][0x0f5].len = 29; -// packet_db[13][0x0f7].len = 2; - packet_db[13][0x113].len = 9; - packet_db[13][0x116].len = 9; - packet_db[13][0x190].len = 26; - packet_db[13][0x193].len = 22; - // init packet function calls for packet ver 14 (same function of packet version 13, but size are different) - memcpy(packet_db[14], packet_db[13], sizeof(packet_db[0])); - // size of packet version 14 - Added by nsstrunks (1nov04) - packet_db[14][0x072].len = 13; - packet_db[14][0x07e].len = 13; - packet_db[14][0x085].len = 15; - packet_db[14][0x089].len = 6; - packet_db[14][0x08c].len = 108; - packet_db[14][0x094].len = 12; - packet_db[14][0x09b].len = 10; - packet_db[14][0x09f].len = -1; - packet_db[14][0x0a2].len = 16; - packet_db[14][0x0a7].len = 28; - packet_db[14][0x0f3].len = 15; - packet_db[14][0x0f5].len = 29; - packet_db[14][0x113].len = 9; - packet_db[14][0x116].len = 9; - packet_db[14][0x190].len = 26; - packet_db[14][0x193].len = 22; - packet_db[14][0x215].len = 6; - packet_db[14][0x216].len = 6; - packet_db[14][0x217].len = 2; - packet_db[14][0x218].len = 2; - packet_db[14][0x219].len = 282; - packet_db[14][0x21a].len = 282; - packet_db[14][0x21b].len = 10; - packet_db[14][0x21c].len = 10; -// packet_db[14][0x143].len = 23; // is this required? uncomment if it is - // Init packet function calls for packet ver 15 - memcpy(packet_db[15], packet_db[14], sizeof(packet_db[0])); - packet_db[15][0x072].func = clif_parse_UseSkillToId; - packet_db[15][0x07e].func = clif_parse_UseSkillToPos; - packet_db[15][0x089].func = clif_parse_TickSend; - packet_db[15][0x085].func = clif_parse_GlobalMessage; - packet_db[15][0x08c].func = clif_parse_GetCharNameRequest; - packet_db[15][0x094].func = clif_parse_MoveToKafra; - packet_db[15][0x09b].func = clif_parse_CloseKafra; - packet_db[15][0x09f].func = clif_parse_ActionRequest; - packet_db[15][0x0a2].func = clif_parse_TakeItem; - packet_db[15][0x0a7].func = clif_parse_WalkToXY; - packet_db[15][0x0f3].func = clif_parse_ChangeDir; - packet_db[15][0x0f5].func = clif_parse_WantToConnection; - packet_db[15][0x0f7].func = clif_parse_SolveCharName; - packet_db[15][0x113].func = clif_parse_UseSkillToPos; - packet_db[15][0x116].func = clif_parse_DropItem; - packet_db[15][0x190].func = clif_parse_UseItem; - packet_db[15][0x193].func = clif_parse_MoveFromKafra; - // Size of packet version 15 - Added by nsstrunks (6dec04) - packet_db[15][0x072].len = 22; - packet_db[15][0x07e].len = 30; - packet_db[15][0x094].len = 14; - packet_db[15][0x09f].len = 18; - packet_db[15][0x085].len = -1; - packet_db[15][0x08c].len = 13; - packet_db[15][0x089].len = 7; - packet_db[15][0x09b].len = 2; - packet_db[15][0x0a2].len = 7; - packet_db[15][0x0a7].len = 7; - packet_db[15][0x0f3].len = 8; - packet_db[15][0x0f5].len = 29; - packet_db[15][0x0f7].len = 14; - packet_db[15][0x113].len = 110; - packet_db[15][0x116].len = 12; - packet_db[15][0x190].len = 15; - packet_db[15][0x193].len = 21; - packet_db[15][0x21d].len = 6; - packet_db[15][0x222].len = 6; - packet_db[15][0x221].len = -1; - packet_db[15][0x223].len = 8; - // Init packet function calls for packet ver 16 - memcpy(packet_db[16], packet_db[15], sizeof(packet_db[0])); - packet_db[16][0x072].func = clif_parse_UseSkillToId; - packet_db[16][0x07e].func = clif_parse_UseSkillToPos; - packet_db[16][0x089].func = clif_parse_TickSend; - packet_db[16][0x0f3].func = clif_parse_GlobalMessage; - packet_db[16][0x08c].func = clif_parse_GetCharNameRequest; - packet_db[16][0x094].func = clif_parse_MoveToKafra; - packet_db[16][0x193].func = clif_parse_CloseKafra; - packet_db[16][0x190].func = clif_parse_ActionRequest; - packet_db[16][0x0f5].func = clif_parse_TakeItem; - packet_db[16][0x0a7].func = clif_parse_WalkToXY; - packet_db[16][0x085].func = clif_parse_ChangeDir; - packet_db[16][0x09b].func = clif_parse_WantToConnection; - packet_db[16][0x0a2].func = clif_parse_SolveCharName; - packet_db[16][0x113].func = clif_parse_UseSkillToPos; - packet_db[16][0x116].func = clif_parse_DropItem; - packet_db[16][0x09f].func = clif_parse_UseItem; - packet_db[16][0x0f7].func = clif_parse_MoveFromKafra; - // Size of packet version 16 [10jan05] - packet_db[16][0x072].len = 26; - packet_db[16][0x07e].len = 114; - packet_db[16][0x089].len = 9; - packet_db[16][0x0f3].len = -1; - packet_db[16][0x08c].len = 8; - packet_db[16][0x094].len = 20; - packet_db[16][0x193].len = 2; - packet_db[16][0x190].len = 20; - packet_db[16][0x0f5].len = 9; - packet_db[16][0x0a7].len = 13; - packet_db[16][0x085].len = 23; - packet_db[16][0x09b].len = 32; - packet_db[16][0x0a2].len = 11; - packet_db[16][0x113].len = 34; - packet_db[16][0x116].len = 20; - packet_db[16][0x09f].len = 17; - packet_db[16][0x0f7].len = 21; - packet_db[16][0x143].len = 10; - // Init packet function calls for the packet_db.txt (17) - memcpy(packet_db[MAX_PACKET_VER], packet_db[MAX_PACKET_VER - 1], sizeof(packet_db[0])); -#endif - - if (clif_config.enable_packet_db) - packetdb_readdb(); - - set_defaultparse(clif_parse); -#ifdef __WIN32 - //if (!make_listen_port(map_port)) { - if (!make_listen_bind(bind_ip,map_port)) { - printf("cant bind game port\n"); - exit(1); - } -#else - for(i = 0; i < 10; i++) { - //if (make_listen_port(map_port)) - if (make_listen_bind(bind_ip,map_port)) - break; - sleep(20); - } - if (i == 10) { - printf("cant bind game port\n"); - exit(1); - } -#endif - - add_timer_func_list(clif_waitclose, "clif_waitclose"); - add_timer_func_list(clif_clearchar_delay_sub, "clif_clearchar_delay_sub"); - - return 0; -} - diff --git a/src/map/clif.h b/src/map/clif.h deleted file mode 100644 index b23eed5a6..000000000 --- a/src/map/clif.h +++ /dev/null @@ -1,313 +0,0 @@ -// $Id: clif.h 1952 2004-10-23 14:05:01Z Yor $ -#ifndef _CLIF_H_ -#define _CLIF_H_ - -#ifdef __WIN32 -typedef unsigned int in_addr_t; -#else -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif - -#include "map.h" - -#define MAX_PACKET_DB 0x224 -#define MAX_PACKET_VER 17 - -struct packet_db { - short len; - void (*func)(int, struct map_session_data *); - short pos[20]; -}; -extern struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB]; - -extern struct Clif_Config { - int enable_packet_db; - int packet_db_ver; - int prefer_packet_db; - int connect_cmd; -} clif_config; - -void clif_setip(char*); -void clif_setbindip(char*); -void clif_setport(int); - -in_addr_t clif_getip(void); -int clif_getport(void); -int clif_countusers(void); -void clif_setwaitclose(int); - -int clif_authok(struct map_session_data *); -int clif_authfail_fd(int,int); -int clif_charselectok(int); -int clif_dropflooritem(struct flooritem_data *); -int clif_clearflooritem(struct flooritem_data *,int); -int clif_clearchar(struct block_list*,int); // area or fd -int clif_clearchar_delay(unsigned int,struct block_list *,int); -#define clif_clearchar_area(bl,type) clif_clearchar(bl,type) -int clif_clearchar_id(int,int,int); -int clif_spawnpc(struct map_session_data*); //area -int clif_spawnnpc(struct npc_data*); // area -int clif_spawnmob(struct mob_data*); // area -int clif_spawnpet(struct pet_data*); // area -int clif_walkok(struct map_session_data*); // self -int clif_movechar(struct map_session_data*); // area -int clif_movemob(struct mob_data*); //area -int clif_movepet(struct pet_data *pd); //area -int clif_movenpc(struct npc_data *nd); // [Valaris] -int clif_changemap(struct map_session_data*,char*,int,int); //self -int clif_changemapserver(struct map_session_data*,char*,int,int,int,int); //self -int clif_fixpos(struct block_list *); // area -int clif_fixmobpos(struct mob_data *md); -int clif_fixpcpos(struct map_session_data *sd); -int clif_fixpetpos(struct pet_data *pd); -int clif_fixnpcpos(struct npc_data *nd); // [Valaris] -int clif_npcbuysell(struct map_session_data*,int); //self -int clif_buylist(struct map_session_data*,struct npc_data*); //self -int clif_selllist(struct map_session_data*); //self -int clif_scriptmes(struct map_session_data*,int,char*); //self -int clif_scriptnext(struct map_session_data*,int); //self -int clif_scriptclose(struct map_session_data*,int); //self -int clif_scriptmenu(struct map_session_data*,int,char*); //self -int clif_scriptinput(struct map_session_data*,int); //self -int clif_scriptinputstr(struct map_session_data *sd,int npcid); // self -int clif_cutin(struct map_session_data*,char*,int); //self -int clif_viewpoint(struct map_session_data*,int,int,int,int,int,int); //self -int clif_additem(struct map_session_data*,int,int,int); //self -int clif_delitem(struct map_session_data*,int,int); //self -int clif_updatestatus(struct map_session_data*,int); //self -int clif_changestatus(struct block_list*,int,int); //area -int clif_damage(struct block_list *,struct block_list *,unsigned int,int,int,int,int,int,int); // area -#define clif_takeitem(src,dst) clif_damage(src,dst,0,0,0,0,0,1,0) -int clif_changelook(struct block_list *,int,int); // area -int clif_arrowequip(struct map_session_data *sd,int val); //self -int clif_arrow_fail(struct map_session_data *sd,int type); //self -int clif_arrow_create_list(struct map_session_data *sd); //self -int clif_statusupack(struct map_session_data *,int,int,int); // self -int clif_equipitemack(struct map_session_data *,int,int,int); // self -int clif_unequipitemack(struct map_session_data *,int,int,int); // self -int clif_misceffect(struct block_list*,int); // area -int clif_misceffect2(struct block_list *bl,int type); -int clif_changeoption(struct block_list*); // area -int clif_useitemack(struct map_session_data*,int,int,int); // self -void clif_GlobalMessage(struct block_list *bl,char *message); -int clif_createchat(struct map_session_data*,int); // self -int clif_dispchat(struct chat_data*,int); // area or fd -int clif_joinchatfail(struct map_session_data*,int); // self -int clif_joinchatok(struct map_session_data*,struct chat_data*); // self -int clif_addchat(struct chat_data*,struct map_session_data*); // chat -int clif_changechatowner(struct chat_data*,struct map_session_data*); // chat -int clif_clearchat(struct chat_data*,int); // area or fd -int clif_leavechat(struct chat_data*,struct map_session_data*); // chat -int clif_changechatstatus(struct chat_data*); // chat -int clif_refresh(struct map_session_data*); // self - -void clif_emotion(struct block_list *bl,int type); -void clif_talkiebox(struct block_list *bl,char* talkie); -void clif_wedding_effect(struct block_list *bl); -//void clif_sitting(int fd, struct map_session_data *sd); -//void clif_callpartner(struct map_session_data *sd); -void clif_adopt_process(struct map_session_data *sd); -void clif_sitting(struct map_session_data *sd); -void clif_soundeffect(struct map_session_data *sd,struct block_list *bl,char *name,int type); -int clif_soundeffectall(struct block_list *bl, char *name, int type); - -// trade -int clif_traderequest(struct map_session_data *sd,char *name); -int clif_tradestart(struct map_session_data *sd,int type); -int clif_tradeadditem(struct map_session_data *sd,struct map_session_data *tsd,int index,int amount); -int clif_tradeitemok(struct map_session_data *sd,int index,int fail); -int clif_tradedeal_lock(struct map_session_data *sd,int fail); -int clif_tradecancelled(struct map_session_data *sd); -int clif_tradecompleted(struct map_session_data *sd,int fail); - -// storage -#include "storage.h" -int clif_storageitemlist(struct map_session_data *sd,struct storage *stor); -int clif_storageequiplist(struct map_session_data *sd,struct storage *stor); -int clif_updatestorageamount(struct map_session_data *sd,struct storage *stor); -int clif_storageitemadded(struct map_session_data *sd,struct storage *stor,int index,int amount); -int clif_storageitemremoved(struct map_session_data *sd,int index,int amount); -int clif_storageclose(struct map_session_data *sd); -int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *stor); -int clif_guildstorageequiplist(struct map_session_data *sd,struct guild_storage *stor); -int clif_updateguildstorageamount(struct map_session_data *sd,struct guild_storage *stor); -int clif_guildstorageitemadded(struct map_session_data *sd,struct guild_storage *stor,int index,int amount); - -int clif_pcinsight(struct block_list *,va_list); // map_forallinmovearea callback -int clif_pcoutsight(struct block_list *,va_list); // map_forallinmovearea callback -int clif_mobinsight(struct block_list *,va_list); // map_forallinmovearea callback -int clif_moboutsight(struct block_list *,va_list); // map_forallinmovearea callback -int clif_petoutsight(struct block_list *bl,va_list ap); -int clif_petinsight(struct block_list *bl,va_list ap); -int clif_npcoutsight(struct block_list *bl,va_list ap); -int clif_npcinsight(struct block_list *bl,va_list ap); - -int clif_class_change(struct block_list *bl,int class_,int type); -int clif_mob_class_change(struct mob_data *md,int class_); -int clif_mob_equip(struct mob_data *md,int nameid); // [Valaris] - -int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range); -int clif_skillinfoblock(struct map_session_data *sd); -int clif_skillup(struct map_session_data *sd,int skill_num); - -int clif_skillcasting(struct block_list* bl, - int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int casttime); -int clif_skillcastcancel(struct block_list* bl); -int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype); -int clif_skill_damage(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div, - int skill_id,int skill_lv,int type); -int clif_skill_damage2(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div, - int skill_id,int skill_lv,int type); -int clif_skill_nodamage(struct block_list *src,struct block_list *dst, - int skill_id,int heal,int fail); -int clif_skill_poseffect(struct block_list *src,int skill_id, - int val,int x,int y,int tick); -int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst); -int clif_skill_warppoint(struct map_session_data *sd,int skill_num, - const char *map1,const char *map2,const char *map3,const char *map4); -int clif_skill_memo(struct map_session_data *sd,int flag); -int clif_skill_teleportmessage(struct map_session_data *sd,int flag); -int clif_skill_produce_mix_list(struct map_session_data *sd,int trigger); - -int clif_produceeffect(struct map_session_data *sd,int flag,int nameid); - -int clif_skill_setunit(struct skill_unit *unit); -int clif_skill_delunit(struct skill_unit *unit); - -int clif_01ac(struct block_list *bl); - -int clif_autospell(struct map_session_data *sd,int skilllv); -int clif_devotion(struct map_session_data *sd,int target); -int clif_spiritball(struct map_session_data *sd); -int clif_combo_delay(struct block_list *src,int wait); -int clif_bladestop(struct block_list *src,struct block_list *dst,int bool_); -int clif_changemapcell(int m,int x,int y,int cell_type,int type); - -int clif_status_change(struct block_list *bl,int type,int flag); - -int clif_wis_message(int fd,char *nick,char *mes,int mes_len); -int clif_wis_end(int fd,int flag); - -int clif_solved_charname(struct map_session_data *sd,int char_id); -int clif_update_mobhp(struct mob_data *md); - -int clif_use_card(struct map_session_data *sd,int idx); -int clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int flag); - -int clif_itemlist(struct map_session_data *sd); -int clif_equiplist(struct map_session_data *sd); - -int clif_cart_additem(struct map_session_data*,int,int,int); -int clif_cart_delitem(struct map_session_data*,int,int); -int clif_cart_itemlist(struct map_session_data *sd); -int clif_cart_equiplist(struct map_session_data *sd); - -int clif_item_identify_list(struct map_session_data *sd); -int clif_item_identified(struct map_session_data *sd,int idx,int flag); -int clif_item_repair_list(struct map_session_data *sd); -int clif_item_refine_list(struct map_session_data *sd); - -int clif_item_skill(struct map_session_data *sd,int skillid,int skilllv,const char *name); - -int clif_mvp_effect(struct map_session_data *sd); -int clif_mvp_item(struct map_session_data *sd,int nameid); -int clif_mvp_exp(struct map_session_data *sd,int exp); -void clif_changed_dir(struct block_list *bl); - -// vending -int clif_openvendingreq(struct map_session_data *sd,int num); -int clif_showvendingboard(struct block_list* bl,char *message,int fd); -int clif_closevendingboard(struct block_list* bl,int fd); -int clif_vendinglist(struct map_session_data *sd,int id,struct vending *vending); -int clif_buyvending(struct map_session_data *sd,int index,int amount,int fail); -int clif_openvending(struct map_session_data *sd,int id,struct vending *vending); -int clif_vendingreport(struct map_session_data *sd,int index,int amount); - -int clif_movetoattack(struct map_session_data *sd,struct block_list *bl); - -// party -int clif_party_created(struct map_session_data *sd,int flag); -int clif_party_info(struct party *p,int fd); -int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd); -int clif_party_inviteack(struct map_session_data *sd,char *nick,int flag); -int clif_party_option(struct party *p,struct map_session_data *sd,int flag); -int clif_party_leaved(struct party *p,struct map_session_data *sd,int account_id,char *name,int flag); -int clif_party_message(struct party *p,int account_id,char *mes,int len); -int clif_party_move(struct party *p,struct map_session_data *sd,int online); -int clif_party_xy(struct party *p,struct map_session_data *sd); -int clif_party_hp(struct party *p,struct map_session_data *sd); -int clif_hpmeter(struct map_session_data *sd); - -// guild -int clif_guild_created(struct map_session_data *sd,int flag); -int clif_guild_belonginfo(struct map_session_data *sd,struct guild *g); -int clif_guild_basicinfo(struct map_session_data *sd); -int clif_guild_allianceinfo(struct map_session_data *sd); -int clif_guild_memberlist(struct map_session_data *sd); -int clif_guild_skillinfo(struct map_session_data *sd); -int clif_guild_memberlogin_notice(struct guild *g,int idx,int flag); -int clif_guild_invite(struct map_session_data *sd,struct guild *g); -int clif_guild_inviteack(struct map_session_data *sd,int flag); -int clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes); -int clif_guild_explusion(struct map_session_data *sd,const char *name,const char *mes, - int account_id); -int clif_guild_positionchanged(struct guild *g,int idx); -int clif_guild_memberpositionchanged(struct guild *g,int idx); -int clif_guild_emblem(struct map_session_data *sd,struct guild *g); -int clif_guild_notice(struct map_session_data *sd,struct guild *g); -int clif_guild_message(struct guild *g,int account_id,const char *mes,int len); -int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv); -int clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name); -int clif_guild_allianceack(struct map_session_data *sd,int flag); -int clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag); -int clif_guild_oppositionack(struct map_session_data *sd,int flag); -int clif_guild_broken(struct map_session_data *sd,int flag); - - -// atcommand -int clif_displaymessage(const int fd,char* mes); -int clif_disp_onlyself(struct map_session_data *sd,char *mes,int len); -int clif_GMmessage(struct block_list *bl,char* mes,int len,int flag); -int clif_heal(int fd,int type,int val); -int clif_resurrection(struct block_list *bl,int type); -int clif_set0199(int fd,int type); -int clif_pvpset(struct map_session_data *sd, int pvprank, int pvpnum,int type); -int clif_send0199(int map,int type); -int clif_refine(int fd,struct map_session_data *sd,int fail,int index,int val); - -//petsystem -int clif_catch_process(struct map_session_data *sd); -int clif_pet_rulet(struct map_session_data *sd,int data); -int clif_sendegg(struct map_session_data *sd); -int clif_send_petdata(struct map_session_data *sd,int type,int param); -int clif_send_petstatus(struct map_session_data *sd); -int clif_pet_emotion(struct pet_data *pd,int param); -int clif_pet_performance(struct block_list *bl,int param); -int clif_pet_equip(struct pet_data *pd,int nameid); -int clif_pet_food(struct map_session_data *sd,int foodid,int fail); - -//friends list -void clif_friends_list_send(struct map_session_data *sd); -void clif_parse_friends_list_add(int fd,struct map_session_data *sd); -void clif_parse_friends_list_remove(int fd,struct map_session_data *sd); - -int clif_specialeffect(struct block_list *bl,int type, int flag); // special effects [Valaris] -int clif_message(struct block_list *bl, char* msg); // messages (from mobs/npcs) [Valaris] - -int clif_GM_kickack(struct map_session_data *sd,int id); -int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type); -int clif_timedout(struct map_session_data *sd); - -int clif_foreachclient(int (*)(struct map_session_data*,va_list),...); - -int do_final_clif(void); -int do_init_clif(void); - -#endif - - diff --git a/src/map/guild.c b/src/map/guild.c deleted file mode 100644 index 935377e19..000000000 --- a/src/map/guild.c +++ /dev/null @@ -1,1717 +0,0 @@ -// $Id: guild.c,v 1.5 2004/09/25 05:32:18 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "guild.h" -#include "storage.h" -#include "db.h" -#include "timer.h" -#include "socket.h" -#include "nullpo.h" -#include "malloc.h" -#include "battle.h" -#include "npc.h" -#include "pc.h" -#include "status.h" -#include "map.h" -#include "mob.h" -#include "intif.h" -#include "clif.h" -#include "skill.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -static struct dbt *guild_db; -static struct dbt *castle_db; -static struct dbt *guild_expcache_db; -static struct dbt *guild_infoevent_db; -static struct dbt *guild_castleinfoevent_db; - -struct eventlist { - char name[50]; - struct eventlist *next; -}; - -// ギルドのEXPキャッシュのフラッシュに関連する定数 -#define GUILD_PAYEXP_INVERVAL 10000 // 間隔(キャッシュの最大生存時間、ミリ秒) -#define GUILD_PAYEXP_LIST 8192 // キャッシュの最大数 - -// ギルドのEXPキャッシュ -struct guild_expcache { - int guild_id, account_id, char_id, exp; -}; - -// timer for auto saving guild data during WoE -#define GUILD_SAVE_INTERVAL 300000 -int guild_save_timer = -1; - -int guild_payexp_timer(int tid,unsigned int tick,int id,int data); -int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data); -int guild_save_sub(int tid,unsigned int tick,int id,int data); - -// ギルドスキルdbのアクセサ(今は直打ちで代用) -int guild_skill_get_inf(int id) { // Modified for new skills [Sara] - if (id==GD_BATTLEORDER) return 4; - else if (id==GD_REGENERATION) return 4; - else if (id==GD_RESTORE) return 4; - else if (id==GD_EMERGENCYCALL) return 4; - else return 0; -} -int guild_skill_get_sp(int id,int lv){ return 0; } -int guild_skill_get_range(int id){ return 0; } -int guild_skill_get_max(int id) { // Modified for new skills [Sara] - switch (id) { - case GD_GUARDUP: - return 3; - case GD_EXTENSION: - return 10; - case GD_LEADERSHIP: - case GD_GLORYWOUNDS: - case GD_SOULCOLD: - case GD_HAWKEYES: - return 5; - case GD_REGENERATION: - return 3; - default: - return 1; - } -} - -// ギルドスキルがあるか確認 -int guild_checkskill(struct guild *g,int id) -{ - int idx = id-GD_SKILLBASE; - if (idx < 0 || idx >= MAX_GUILDSKILL) - return 0; - return g->skill[idx].lv; -} - -static int guild_read_castledb(void) -{ - FILE *fp; - char line[1024]; - int j,ln=0; - char *str[32],*p; - struct guild_castle *gc; - - if( (fp=fopen("db/castle_db.txt","r"))==NULL){ - printf("can't read db/castle_db.txt\n"); - return -1; - } - - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle)); - for(j=0,p=line;j<6 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - - gc->guild_id=0; // <Agit> Clear Data for Initialize - gc->economy=0; gc->defense=0; gc->triggerE=0; gc->triggerD=0; gc->nextTime=0; gc->payTime=0; - gc->createTime=0; gc->visibleC=0; gc->visibleG0=0; gc->visibleG1=0; gc->visibleG2=0; - gc->visibleG3=0; gc->visibleG4=0; gc->visibleG5=0; gc->visibleG6=0; gc->visibleG7=0; - gc->Ghp0=0; gc->Ghp1=0; gc->Ghp2=0; gc->Ghp3=0; gc->Ghp4=0; gc->Ghp5=0; gc->Ghp6=0; gc->Ghp7=0; // guardian HP [Valaris] - - gc->castle_id=atoi(str[0]); - memcpy(gc->map_name,str[1],24); - memcpy(gc->castle_name,str[2],24); - memcpy(gc->castle_event,str[3],24); - - numdb_insert(castle_db,gc->castle_id,gc); - - //intif_guild_castle_info(gc->castle_id); - - ln++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/castle_db.txt"); - ShowStatus(tmp_output); - return 0; -} - -// 初期化 -void do_init_guild(void) -{ - guild_db=numdb_init(); - castle_db=numdb_init(); - guild_expcache_db=numdb_init(); - guild_infoevent_db=numdb_init(); - guild_castleinfoevent_db=numdb_init(); - - guild_read_castledb(); - - add_timer_func_list(guild_gvg_eliminate_timer,"guild_gvg_eliminate_timer"); - add_timer_func_list(guild_payexp_timer,"guild_payexp_timer"); - add_timer_func_list(guild_save_sub, "guild_save_sub"); - add_timer_interval(gettick()+GUILD_PAYEXP_INVERVAL,guild_payexp_timer,0,0,GUILD_PAYEXP_INVERVAL); -} - - -// 検索 -struct guild *guild_search(int guild_id) -{ - return (struct guild *) numdb_search(guild_db,guild_id); -} -int guild_searchname_sub(void *key,void *data,va_list ap) -{ - struct guild *g=(struct guild *)data,**dst; - char *str; - str=va_arg(ap,char *); - dst=va_arg(ap,struct guild **); - if(strcmpi(g->name,str)==0) - *dst=g; - return 0; -} -// ギルド名検索 -struct guild* guild_searchname(char *str) -{ - struct guild *g=NULL; - numdb_foreach(guild_db,guild_searchname_sub,str,&g); - return g; -} -struct guild_castle *guild_castle_search(int gcid) -{ - return (struct guild_castle *) numdb_search(castle_db,gcid); -} - -// mapnameに対応したアジトのgcを返す -struct guild_castle *guild_mapname2gc(char *mapname) -{ - int i; - struct guild_castle *gc=NULL; - for(i=0;i<MAX_GUILDCASTLE;i++){ - gc=guild_castle_search(i); - if(!gc) continue; - if(strcmp(gc->map_name,mapname)==0) return gc; - } - return NULL; -} - -// ログイン中のギルドメンバーの1人のsdを返す -struct map_session_data *guild_getavailablesd(struct guild *g) -{ - int i; - - nullpo_retr(NULL, g); - - for(i=0;i<g->max_member;i++) - if(g->member[i].sd!=NULL) - return g->member[i].sd; - return NULL; -} - -// ギルドメンバーのインデックスを返す -int guild_getindex(struct guild *g,int account_id,int char_id) -{ - int i; - if(g==NULL) - return -1; - for(i=0;i<g->max_member;i++) - if( g->member[i].account_id==account_id && - g->member[i].char_id==char_id ) - return i; - return -1; -} -// ギルドメンバーの役職を返す -int guild_getposition(struct map_session_data *sd,struct guild *g) -{ - int i; - - nullpo_retr(-1, sd); - - if(g==NULL && (g=guild_search(sd->status.guild_id))==NULL) - return -1; - for(i=0;i<g->max_member;i++) - if( g->member[i].account_id==sd->status.account_id && - g->member[i].char_id==sd->status.char_id ) - return g->member[i].position; - return -1; -} - -// メンバー情報の作成 -void guild_makemember(struct guild_member *m,struct map_session_data *sd) -{ - nullpo_retv(sd); - - memset(m,0,sizeof(struct guild_member)); - m->account_id =sd->status.account_id; - m->char_id =sd->status.char_id; - m->hair =sd->status.hair; - m->hair_color =sd->status.hair_color; - m->gender =sd->sex; - m->class_ =sd->status.class_; - m->lv =sd->status.base_level; - m->exp =0; - m->exp_payper =0; - m->online =1; - m->position =MAX_GUILDPOSITION-1; - memcpy(m->name,sd->status.name,24); - return; -} -// ギルド競合確認 -int guild_check_conflict(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - intif_guild_checkconflict(sd->status.guild_id, - sd->status.account_id,sd->status.char_id); - return 0; -} - -// ギルドのEXPキャッシュをinter鯖にフラッシュする -int guild_payexp_timer_sub(void *key,void *data,va_list ap) -{ - int i, *dellist,*delp, dataid=(int)key; - struct guild_expcache *c; - struct guild *g; - - nullpo_retr(0, ap); - nullpo_retr(0, c=(struct guild_expcache *)data); - nullpo_retr(0, dellist=va_arg(ap,int *)); - nullpo_retr(0, delp=va_arg(ap,int *)); - - if( *delp>=GUILD_PAYEXP_LIST || (g=guild_search(c->guild_id))==NULL ) - return 0; - if( ( i=guild_getindex(g,c->account_id,c->char_id) )<0 ) - return 0; - - g->member[i].exp+=c->exp; - intif_guild_change_memberinfo(g->guild_id,c->account_id,c->char_id, - GMI_EXP,&g->member[i].exp,sizeof(g->member[i].exp)); - c->exp=0; - - dellist[(*delp)++]=dataid; - aFree(c); - return 0; -} -int guild_payexp_timer(int tid,unsigned int tick,int id,int data) -{ - int dellist[GUILD_PAYEXP_LIST],delp=0,i; - numdb_foreach(guild_expcache_db,guild_payexp_timer_sub, - dellist,&delp); - for(i=0;i<delp;i++) - numdb_erase(guild_expcache_db,dellist[i]); -// if(battle_config.etc_log) -// printf("guild exp %d charactor's exp flushed !\n",delp); - return 0; -} - -//------------------------------------------------------------------------ - -// 作成要求 -int guild_create(struct map_session_data *sd,char *name) -{ - nullpo_retr(0, sd); - - if(sd->status.guild_id==0){ - if(!battle_config.guild_emperium_check || pc_search_inventory(sd,714) >= 0) { - struct guild_member m; - guild_makemember(&m,sd); - m.position=0; - intif_guild_create(name,&m); - } else - clif_guild_created(sd,3); // エンペリウムがいない - }else - clif_guild_created(sd,1); // すでに所属している - - return 0; -} - -// 作成可否 -int guild_created(int account_id,int guild_id) -{ - struct map_session_data *sd=map_id2sd(account_id); - - if(sd==NULL) - return 0; - if(guild_id>0) { - struct guild *g; - sd->status.guild_id=guild_id; - sd->guild_sended=0; - if((g=(struct guild *) numdb_search(guild_db,guild_id))!=NULL){ - printf("guild: id already exists!\n"); - exit(1); - } - clif_guild_created(sd,0); - if(battle_config.guild_emperium_check) - pc_delitem(sd,pc_search_inventory(sd,714),1,0); // エンペリウム消耗 - } else { - clif_guild_created(sd,2); // 作成失敗(同名ギルド存在) - } - return 0; -} - -// 情報要求 -int guild_request_info(int guild_id) -{ -// if(battle_config.etc_log) -// printf("guild_request_info\n"); - return intif_guild_request_info(guild_id); -} -// イベント付き情報要求 -int guild_npc_request_info(int guild_id,const char *event) -{ - struct eventlist *ev; - - if( guild_search(guild_id) ){ - if(event && *event) - npc_event_do(event); - return 0; - } - - if(event==NULL || *event==0) - return guild_request_info(guild_id); - - ev=(struct eventlist *)aCalloc(1,sizeof(struct eventlist)); - memcpy(ev->name,event,strlen(event)); - ev->next=(struct eventlist *)numdb_search(guild_infoevent_db,guild_id); - numdb_insert(guild_infoevent_db,guild_id,ev); - return guild_request_info(guild_id); -} - -// 所属キャラの確認 -int guild_check_member(const struct guild *g) -{ - int i; - struct map_session_data *sd; - - nullpo_retr(0, g); - - for(i=0;i<fd_max;i++){ - if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth && !sd->state.waitingdisconnect){ - if(sd->status.guild_id==g->guild_id){ - int j,f=1; - for(j=0;j<MAX_GUILD;j++){ // データがあるか - if( g->member[j].account_id==sd->status.account_id && - g->member[j].char_id==sd->status.char_id) - f=0; - } - if(f){ - sd->status.guild_id=0; - sd->guild_sended=0; - sd->guild_emblem_id=0; - if(battle_config.error_log) - printf("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name); - } - } - } - } - return 0; -} -// 情報所得失敗(そのIDのキャラを全部未所属にする) -int guild_recv_noinfo(int guild_id) -{ - int i; - struct map_session_data *sd; - for(i=0;i<fd_max;i++){ - if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth && !sd->state.waitingdisconnect){ - if(sd->status.guild_id==guild_id) - sd->status.guild_id=0; - } - } - return 0; -} -// 情報所得 -int guild_recv_info(struct guild *sg) -{ - struct guild *g,before; - int i,bm,m; - struct eventlist *ev,*ev2; - - nullpo_retr(0, sg); - - if((g=(struct guild *) numdb_search(guild_db,sg->guild_id))==NULL){ - g=(struct guild *)aCalloc(1,sizeof(struct guild)); - numdb_insert(guild_db,sg->guild_id,g); - before=*sg; - - // 最初のロードなのでユーザーのチェックを行う - guild_check_member(sg); - }else - before=*g; - memcpy(g,sg,sizeof(struct guild)); - - for(i=bm=m=0;i<g->max_member;i++){ // sdの設定と人数の確認 - if(g->member[i].account_id>0){ - struct map_session_data *sd = map_id2sd(g->member[i].account_id); - if (sd && sd->status.char_id == g->member[i].char_id && - sd->status.guild_id == g->guild_id && - !sd->state.waitingdisconnect) - g->member[i].sd = sd; - else sd = NULL; - m++; - }else - g->member[i].sd=NULL; - if(before.member[i].account_id>0) - bm++; - } - - for(i=0;i<g->max_member;i++){ // 情報の送信 - struct map_session_data *sd = g->member[i].sd; - if( sd==NULL ) - continue; - - if( before.guild_lv!=g->guild_lv || bm!=m || - before.max_member!=g->max_member ){ - clif_guild_basicinfo(sd); // 基本情報送信 - clif_guild_emblem(sd,g); // エンブレム送信 - } - - if(bm!=m){ // メンバー情報送信 - clif_guild_memberlist(g->member[i].sd); - } - - if( before.skill_point!=g->skill_point) - clif_guild_skillinfo(sd); // スキル情報送信 - - if( sd->guild_sended==0){ // 未送信なら所属情報も送る - clif_guild_belonginfo(sd,g); - clif_guild_notice(sd,g); - sd->guild_emblem_id=g->emblem_id; - sd->guild_sended=1; - } - } - - // イベントの発生 - if( (ev=(struct eventlist *)numdb_search(guild_infoevent_db,sg->guild_id))!=NULL ){ - numdb_erase(guild_infoevent_db,sg->guild_id); - while(ev){ - npc_event_do(ev->name); - ev2=ev->next; - aFree(ev); - ev=ev2; - } - } - - return 0; -} - - -// ギルドへの勧誘 -int guild_invite(struct map_session_data *sd,int account_id) -{ - struct map_session_data *tsd; - struct guild *g; - int i; - - nullpo_retr(0, sd); - - tsd= map_id2sd(account_id); - g=guild_search(sd->status.guild_id); - - if(tsd==NULL || g==NULL) - return 0; - if(!battle_config.invite_request_check) { - if (tsd->party_invite>0 || tsd->trade_partner) { // 相手が取引中かどうか - clif_guild_inviteack(sd,0); - return 0; - } - } - if( tsd->status.guild_id>0 || tsd->guild_invite>0 ){ // 相手の所属確認 - clif_guild_inviteack(sd,0); - return 0; - } - - // 定員確認 - for(i=0;i<g->max_member;i++) - if(g->member[i].account_id==0) - break; - if(i==g->max_member){ - clif_guild_inviteack(sd,3); - return 0; - } - - tsd->guild_invite=sd->status.guild_id; - tsd->guild_invite_account=sd->status.account_id; - - clif_guild_invite(tsd,g); - return 0; -} -// ギルド勧誘への返答 -int guild_reply_invite(struct map_session_data *sd,int guild_id,int flag) -{ - struct map_session_data *tsd; - - nullpo_retr(0, sd); - nullpo_retr(0, tsd= map_id2sd( sd->guild_invite_account )); - - if(sd->guild_invite!=guild_id) // 勧誘とギルドIDが違う - return 0; - - if(flag==1){ // 承諾 - struct guild_member m; - struct guild *g; - int i; - - // 定員確認 - if( (g=guild_search(tsd->status.guild_id))==NULL ){ - sd->guild_invite=0; - sd->guild_invite_account=0; - return 0; - } - for(i=0;i<g->max_member;i++) - if(g->member[i].account_id==0) - break; - if(i==g->max_member){ - sd->guild_invite=0; - sd->guild_invite_account=0; - clif_guild_inviteack(tsd,3); - return 0; - } - - - //inter鯖へ追加要求 - guild_makemember(&m,sd); - intif_guild_addmember( sd->guild_invite, &m ); - return 0; - }else{ // 拒否 - sd->guild_invite=0; - sd->guild_invite_account=0; - if(tsd==NULL) - return 0; - clif_guild_inviteack(tsd,1); - } - return 0; -} -// ギルドメンバが追加された -int guild_member_added(int guild_id,int account_id,int char_id,int flag) -{ - struct map_session_data *sd= map_id2sd(account_id),*sd2; - struct guild *g; - - if( (g=guild_search(guild_id))==NULL ) - return 0; - - if(sd==NULL || sd->guild_invite==0){ - // キャラ側に登録できなかったため脱退要求を出す - if (flag == 0) { - if(battle_config.error_log) - printf("guild: member added error %d is not online\n",account_id); - intif_guild_leave(guild_id,account_id,char_id,0,"**登録失敗**"); - } - return 0; - } - sd2 = map_id2sd(sd->guild_invite_account); - sd->guild_invite = 0; - sd->guild_invite_account = 0; - - if(flag==1){ // 失敗 - if( sd2!=NULL ) - clif_guild_inviteack(sd2,3); - return 0; - } - - // 成功 - sd->guild_sended=0; - sd->status.guild_id=guild_id; - - if( sd2!=NULL ) - clif_guild_inviteack(sd2,2); - - // いちおう競合確認 - guild_check_conflict(sd); - - return 0; -} - -// ギルド脱退要求 -int guild_leave(struct map_session_data *sd,int guild_id, - int account_id,int char_id,const char *mes) -{ - struct guild *g; - int i; - - nullpo_retr(0, sd); - - g = guild_search(sd->status.guild_id); - - if(g==NULL) - return 0; - - if( sd->status.account_id!=account_id || - sd->status.char_id!=char_id || sd->status.guild_id!=guild_id) - return 0; - - for(i=0;i<g->max_member;i++){ // 所属しているか - if( g->member[i].account_id==sd->status.account_id && - g->member[i].char_id==sd->status.char_id ){ - intif_guild_leave(g->guild_id,sd->status.account_id,sd->status.char_id,0,mes); - return 0; - } - } - return 0; -} -// ギルド追放要求 -int guild_explusion(struct map_session_data *sd,int guild_id, - int account_id,int char_id,const char *mes) -{ - struct guild *g; - int i,ps; - - nullpo_retr(0, sd); - - g = guild_search(sd->status.guild_id); - - if(g==NULL) - return 0; - - if( sd->status.guild_id!=guild_id) - return 0; - - if( (ps=guild_getposition(sd,g))<0 || !(g->position[ps].mode&0x0010) ) - return 0; // 処罰権限無し - - for(i=0;i<g->max_member;i++){ // 所属しているか - if( g->member[i].account_id==account_id && - g->member[i].char_id==char_id ){ - intif_guild_leave(g->guild_id,account_id,char_id,1,mes); - return 0; - } - } - return 0; -} -// ギルドメンバが脱退した -int guild_member_leaved(int guild_id,int account_id,int char_id,int flag, - const char *name,const char *mes) -{ - struct map_session_data *sd=map_id2sd(account_id); - struct guild *g=guild_search(guild_id); - - if(g!=NULL){ - int i; - for(i=0;i<g->max_member;i++) { - if( g->member[i].account_id==account_id && - g->member[i].char_id==char_id ){ - struct map_session_data *sd2=sd; - if(sd2==NULL) - sd2=guild_getavailablesd(g); - else - { - if(flag==0) - clif_guild_leave(sd2,name,mes); - else - clif_guild_explusion(sd2,name,mes,account_id); - } - g->member[i].account_id=0; - g->member[i].sd=NULL; - } - // メンバーリストを全員に再通知 - for(i=0;i<g->max_member;i++){ - if( g->member[i].sd!=NULL ) - clif_guild_memberlist(g->member[i].sd); - } - } - } - if(sd!=NULL) { - if (sd->status.guild_id==guild_id){ - sd->status.guild_id=0; - sd->guild_emblem_id=0; - sd->guild_sended=0; - } - } - - return 0; -} -// ギルドメンバのオンライン状態/Lv更新送信 -int guild_send_memberinfoshort(struct map_session_data *sd,int online) -{ - struct guild *g; - - nullpo_retr(0, sd); - - if(sd->status.guild_id<=0) - return 0; - g=guild_search(sd->status.guild_id); - if(g==NULL) - return 0; - - intif_guild_memberinfoshort(g->guild_id, - sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class_); - - if( !online ){ // ログアウトするならsdをクリアして終了 - int i=guild_getindex(g,sd->status.account_id,sd->status.char_id); - if(i>=0) - g->member[i].sd=NULL; - return 0; - } - - if( sd->guild_sended!=0 ) // ギルド初期送信データは送信済み - return 0; - - // 競合確認 - guild_check_conflict(sd); - - // あるならギルド初期送信データ送信 - if( (g=guild_search(sd->status.guild_id))!=NULL ){ - guild_check_member(g); // 所属を確認する - if(sd->status.guild_id==g->guild_id){ - clif_guild_belonginfo(sd,g); - clif_guild_notice(sd,g); - sd->guild_sended=1; - sd->guild_emblem_id=g->emblem_id; - } - } - return 0; -} -// ギルドメンバのオンライン状態/Lv更新通知 -int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_) -{ - int i,alv,c,idx=0,om=0,oldonline=-1; - struct guild *g=guild_search(guild_id); - if(g==NULL) - return 0; - for(i=0,alv=0,c=0,om=0;i<g->max_member;i++){ - struct guild_member *m=&g->member[i]; - if(m->account_id==account_id && m->char_id==char_id ){ - oldonline=m->online; - m->online=online; - m->lv=lv; - m->class_=class_; - idx=i; - } - if(m->account_id>0){ - alv+=m->lv; - c++; - } - if(m->online) - om++; - } - if(idx==g->max_member){ - if(battle_config.error_log) - printf("guild: not found member %d,%d on %d[%s]\n", account_id,char_id,guild_id,g->name); - return 0; - } - g->average_lv=alv/c; - g->connect_member=om; - - if(oldonline!=online) // オンライン状態が変わったので通知 - clif_guild_memberlogin_notice(g,idx,online); - - for(i=0;i<g->max_member;i++){ // sd再設定 - struct map_session_data *sd= map_id2sd(g->member[i].account_id); - if (sd && sd->status.char_id == g->member[i].char_id && - sd->status.guild_id == g->guild_id && - !sd->state.waitingdisconnect) - g->member[i].sd = sd; - else sd = NULL; - } - - // ここにクライアントに送信処理が必要 - - return 0; -} -// ギルド会話送信 -int guild_send_message(struct map_session_data *sd,char *mes,int len) -{ - nullpo_retr(0, sd); - - if(sd->status.guild_id==0) - return 0; - intif_guild_message(sd->status.guild_id,sd->status.account_id,mes,len); - guild_recv_message(sd->status.guild_id,sd->status.account_id,mes,len); - - return 0; -} -// ギルド会話受信 -int guild_recv_message(int guild_id,int account_id,char *mes,int len) -{ - struct guild *g; - if( (g=guild_search(guild_id))==NULL) - return 0; - clif_guild_message(g,account_id,mes,len); - return 0; -} -// ギルドメンバの役職変更 -int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx) -{ - return intif_guild_change_memberinfo( - guild_id,account_id,char_id,GMI_POSITION,&idx,sizeof(idx)); -} -// ギルドメンバの役職変更通知 -int guild_memberposition_changed(struct guild *g,int idx,int pos) -{ - nullpo_retr(0, g); - - g->member[idx].position=pos; - clif_guild_memberpositionchanged(g,idx); - return 0; -} -// ギルド役職変更 -int guild_change_position(struct map_session_data *sd,int idx, - int mode,int exp_mode,const char *name) -{ - struct guild_position p; - - nullpo_retr(0, sd); - - if(exp_mode>battle_config.guild_exp_limit) - exp_mode=battle_config.guild_exp_limit; - if(exp_mode<0)exp_mode=0; - p.mode=mode; - p.exp_mode=exp_mode; - memcpy(p.name,name,24); - return intif_guild_position(sd->status.guild_id,idx,&p); -} -// ギルド役職変更通知 -int guild_position_changed(int guild_id,int idx,struct guild_position *p) -{ - struct guild *g=guild_search(guild_id); - if(g==NULL) - return 0; - memcpy(&g->position[idx],p,sizeof(struct guild_position)); - clif_guild_positionchanged(g,idx); - return 0; -} -// ギルド告知変更 -int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2) -{ - nullpo_retr(0, sd); - - if(guild_id!=sd->status.guild_id) - return 0; - return intif_guild_notice(guild_id,mes1,mes2); -} -// ギルド告知変更通知 -int guild_notice_changed(int guild_id,const char *mes1,const char *mes2) -{ - int i; - struct map_session_data *sd; - struct guild *g=guild_search(guild_id); - if(g==NULL) - return 0; - - memcpy(g->mes1,mes1,60); - memcpy(g->mes2,mes2,120); - - for(i=0;i<g->max_member;i++){ - if((sd=g->member[i].sd)!=NULL) - clif_guild_notice(sd,g); - } - return 0; -} -// ギルドエンブレム変更 -int guild_change_emblem(struct map_session_data *sd,int len,const char *data) -{ - struct guild *g; - nullpo_retr(0, sd); - - if (battle_config.require_glory_guild && - !((g = guild_search(sd->status.guild_id)) && guild_checkskill(g, GD_GLORYGUILD)>0)) { - clif_skill_fail(sd,GD_GLORYGUILD,0,0); - return 0; - } - - return intif_guild_emblem(sd->status.guild_id,len,data); -} -// ギルドエンブレム変更通知 -int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data) -{ - int i; - struct map_session_data *sd; - struct guild *g=guild_search(guild_id); - if(g==NULL) - return 0; - - memcpy(g->emblem_data,data,len); - g->emblem_len=len; - g->emblem_id=emblem_id; - - for(i=0;i<g->max_member;i++){ - if((sd=g->member[i].sd)!=NULL){ - sd->guild_emblem_id=emblem_id; - clif_guild_belonginfo(sd,g); - clif_guild_emblem(sd,g); - } - } - return 0; -} - -// ギルドのEXP上納 -int guild_payexp(struct map_session_data *sd,int exp) -{ - struct guild *g; - struct guild_expcache *c; - int per,exp2; - - nullpo_retr(0, sd); - - if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL ) - return 0; - if( (per=g->position[guild_getposition(sd,g)].exp_mode)<=0 ) - return 0; - if( per>100 )per=100; - - if( (exp2=exp*per/100)<=0 ) - return 0; - - if( (c=(struct guild_expcache *) numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){ - c=(struct guild_expcache *)aCallocA(1,sizeof(struct guild_expcache)); - c->guild_id=sd->status.guild_id; - c->account_id=sd->status.account_id; - c->char_id=sd->status.char_id; - c->exp=exp2; - numdb_insert(guild_expcache_db,c->char_id,c); - }else{ - c->exp+=exp2; - } - return exp2; -} - -// Celest -int guild_getexp(struct map_session_data *sd,int exp) -{ - struct guild *g; - struct guild_expcache *c; - - nullpo_retr(0, sd); - - if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL ) - return 0; - - if( (c=(struct guild_expcache *) numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){ - c=(struct guild_expcache *)aCallocA(1,sizeof(struct guild_expcache)); - c->guild_id=sd->status.guild_id; - c->account_id=sd->status.account_id; - c->char_id=sd->status.char_id; - c->exp=exp; - numdb_insert(guild_expcache_db,c->char_id,c); - }else{ - c->exp+=exp; - } - return exp; -} - -// スキルポイント割り振り -int guild_skillup(struct map_session_data *sd,int skill_num,int flag) -{ - struct guild *g; - int idx = skill_num - GD_SKILLBASE; - - nullpo_retr(0, sd); - - if(idx < 0 || idx >= MAX_GUILDSKILL) - - return 0; - if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL) - return 0; - if(strcmp(sd->status.name,g->master)) - return 0; - - if( (g->skill_point>0 || flag&1) && - g->skill[idx].id!=0 && - g->skill[idx].lv < guild_skill_get_max(skill_num) ){ - intif_guild_skillup(g->guild_id,skill_num,sd->status.account_id,flag); - } - status_calc_pc (sd, 0); // Celest - - return 0; -} -// スキルポイント割り振り通知 -int guild_skillupack(int guild_id,int skill_num,int account_id) -{ - struct map_session_data *sd=map_id2sd(account_id); - struct guild *g=guild_search(guild_id); - int i; - if(g==NULL) - return 0; - if(sd!=NULL) - clif_guild_skillup(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv); - // 全員に通知 - for(i=0;i<g->max_member;i++) - if((sd=g->member[i].sd)!=NULL) - clif_guild_skillinfo(sd); - return 0; -} - -// ギルド同盟数所得 -int guild_get_alliance_count(struct guild *g,int flag) -{ - int i,c; - - nullpo_retr(0, g); - - for(i=c=0;i<MAX_GUILDALLIANCE;i++){ - if( g->alliance[i].guild_id>0 && - g->alliance[i].opposition==flag ) - c++; - } - return c; -} -// 同盟関係かどうかチェック -// 同盟なら1、それ以外は0 -int guild_check_alliance(int guild_id1, int guild_id2, int flag) -{ - struct guild *g; - int i; - - g = guild_search(guild_id1); - if (g == NULL) - return 0; - - for (i=0; i<MAX_GUILDALLIANCE; i++) - if ((g->alliance[i].guild_id == guild_id2) && (g->alliance[i].opposition == flag)) - return 1; - - return 0; -} -// ギルド同盟要求 -int guild_reqalliance(struct map_session_data *sd,int account_id) -{ - struct map_session_data *tsd= map_id2sd(account_id); - struct guild *g[2]; - int i; - - if(agit_flag) { // Disable alliance creation during woe [Valaris] - clif_displaymessage(sd->fd,"Alliances cannot be made during Guild Wars!"); - return 0; - } // end addition [Valaris] - - - nullpo_retr(0, sd); - - if(tsd==NULL || tsd->status.guild_id<=0) - return 0; - - g[0]=guild_search(sd->status.guild_id); - g[1]=guild_search(tsd->status.guild_id); - - if(g[0]==NULL || g[1]==NULL) - return 0; - - if( guild_get_alliance_count(g[0],0)>3 ) // 同盟数確認 - clif_guild_allianceack(sd,4); - if( guild_get_alliance_count(g[1],0)>3 ) - clif_guild_allianceack(sd,3); - - if( tsd->guild_alliance>0 ){ // 相手が同盟要請状態かどうか確認 - clif_guild_allianceack(sd,1); - return 0; - } - - for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに同盟状態か確認 - if( g[0]->alliance[i].guild_id==tsd->status.guild_id && - g[0]->alliance[i].opposition==0){ - clif_guild_allianceack(sd,0); - return 0; - } - } - - tsd->guild_alliance=sd->status.guild_id; - tsd->guild_alliance_account=sd->status.account_id; - - clif_guild_reqalliance(tsd,sd->status.account_id,g[0]->name); - return 0; -} -// ギルド勧誘への返答 -int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag) -{ - struct map_session_data *tsd; - - nullpo_retr(0, sd); - nullpo_retr(0, tsd= map_id2sd( account_id )); - - if(sd->guild_alliance!=tsd->status.guild_id) // 勧誘とギルドIDが違う - return 0; - - if(flag==1){ // 承諾 - int i; - - struct guild *g; // 同盟数再確認 - if( (g=guild_search(sd->status.guild_id))==NULL || - guild_get_alliance_count(g,0)>3 ){ - clif_guild_allianceack(sd,4); - clif_guild_allianceack(tsd,3); - return 0; - } - if( (g=guild_search(tsd->status.guild_id))==NULL || - guild_get_alliance_count(g,0)>3 ){ - clif_guild_allianceack(sd,3); - clif_guild_allianceack(tsd,4); - return 0; - } - - // 敵対関係なら敵対を止める - if((g=guild_search(sd->status.guild_id)) == NULL) - return 0; - for(i=0;i<MAX_GUILDALLIANCE;i++){ - if( g->alliance[i].guild_id==tsd->status.guild_id && - g->alliance[i].opposition==1) - intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, - sd->status.account_id,tsd->status.account_id,9 ); - } - if((g=guild_search(tsd->status.guild_id)) == NULL) - return 0; - for(i=0;i<MAX_GUILDALLIANCE;i++){ - if( g->alliance[i].guild_id==sd->status.guild_id && - g->alliance[i].opposition==1) - intif_guild_alliance( tsd->status.guild_id,sd->status.guild_id, - tsd->status.account_id,sd->status.account_id,9 ); - } - - // inter鯖へ同盟要請 - intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, - sd->status.account_id,tsd->status.account_id,0 ); - return 0; - }else{ // 拒否 - sd->guild_alliance=0; - sd->guild_alliance_account=0; - if(tsd!=NULL) - clif_guild_allianceack(tsd,3); - } - return 0; -} -// ギルド関係解消 -int guild_delalliance(struct map_session_data *sd,int guild_id,int flag) -{ - if(agit_flag) { // Disable alliance breaking during woe [Valaris] - clif_displaymessage(sd->fd,"Alliances cannot be broken during Guild Wars!"); - return 0; - } // end addition [Valaris] - - nullpo_retr(0, sd); - - intif_guild_alliance( sd->status.guild_id,guild_id, - sd->status.account_id,0,flag|8 ); - return 0; -} -// ギルド敵対 -int guild_opposition(struct map_session_data *sd,int char_id) -{ - struct map_session_data *tsd=map_id2sd(char_id); - struct guild *g; - int i; - - nullpo_retr(0, sd); - - g=guild_search(sd->status.guild_id); - if(g==NULL || tsd==NULL) - return 0; - - if( guild_get_alliance_count(g,1)>3 ) // 敵対数確認 - clif_guild_oppositionack(sd,1); - - for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに関係を持っているか確認 - if(g->alliance[i].guild_id==tsd->status.guild_id){ - if(g->alliance[i].opposition==1){ // すでに敵対 - clif_guild_oppositionack(sd,2); - return 0; - }else // 同盟破棄 - intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, - sd->status.account_id,tsd->status.account_id,8 ); - } - } - - // inter鯖に敵対要請 - intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, - sd->status.account_id,tsd->status.account_id,1 ); - return 0; -} -// ギルド同盟/敵対通知 -int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2, - int flag,const char *name1,const char *name2) -{ - struct guild *g[2]; - int guild_id[2]; - const char *guild_name[2]; - struct map_session_data *sd[2]; - int j,i; - - guild_id[0] = guild_id1; - guild_id[1] = guild_id2; - guild_name[0] = name1; - guild_name[1] = name2; - sd[0] = map_id2sd(account_id1); - sd[1] = map_id2sd(account_id2); - - g[0]=guild_search(guild_id1); - g[1]=guild_search(guild_id2); - - if(sd[0]!=NULL && (flag&0x0f)==0){ - sd[0]->guild_alliance=0; - sd[0]->guild_alliance_account=0; - } - - if(flag&0x70){ // 失敗 - for(i=0;i<2-(flag&1);i++) - if( sd[i]!=NULL ) - clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4); - return 0; - } -// if(battle_config.etc_log) -// printf("guild alliance_ack %d %d %d %d %d %s %s\n",guild_id1,guild_id2,account_id1,account_id2,flag,name1,name2); - - if(!(flag&0x08)){ // 関係追加 - for(i=0;i<2-(flag&1);i++) - if(g[i]!=NULL) - for(j=0;j<MAX_GUILDALLIANCE;j++) - if(g[i]->alliance[j].guild_id==0){ - g[i]->alliance[j].guild_id=guild_id[1-i]; - memcpy(g[i]->alliance[j].name,guild_name[1-i],24); - g[i]->alliance[j].opposition=flag&1; - break; - } - }else{ // 関係解消 - for(i=0;i<2-(flag&1);i++){ - if(g[i]!=NULL) - for(j=0;j<MAX_GUILDALLIANCE;j++) - if( g[i]->alliance[j].guild_id==guild_id[1-i] && - g[i]->alliance[j].opposition==(flag&1)){ - g[i]->alliance[j].guild_id=0; - break; - } - if( sd[i]!=NULL ) // 解消通知 - clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1)); - } - } - - if((flag&0x0f)==0){ // 同盟通知 - if( sd[1]!=NULL ) - clif_guild_allianceack(sd[1],2); - }else if((flag&0x0f)==1){ // 敵対通知 - if( sd[0]!=NULL ) - clif_guild_oppositionack(sd[0],0); - } - - - for(i=0;i<2-(flag&1);i++){ // 同盟/敵対リストの再送信 - struct map_session_data *sd; - if(g[i]!=NULL) - for(j=0;j<g[i]->max_member;j++) - if((sd=g[i]->member[j].sd)!=NULL) - clif_guild_allianceinfo(sd); - } - return 0; -} -// ギルド解散通知用 -int guild_broken_sub(void *key,void *data,va_list ap) -{ - struct guild *g=(struct guild *)data; - int guild_id=va_arg(ap,int); - int i,j; - struct map_session_data *sd=NULL; - - nullpo_retr(0, g); - - for(i=0;i<MAX_GUILDALLIANCE;i++){ // 関係を破棄 - if(g->alliance[i].guild_id==guild_id){ - for(j=0;j<g->max_member;j++) - if( (sd=g->member[j].sd)!=NULL ) - clif_guild_delalliance(sd,guild_id,g->alliance[i].opposition); - g->alliance[i].guild_id=0; - } - } - return 0; -} -// ギルド解散通知 -int guild_broken(int guild_id,int flag) -{ - struct guild *g=guild_search(guild_id); - struct map_session_data *sd; - int i; - if(flag!=0 || g==NULL) - return 0; - - for(i=0;i<g->max_member;i++){ // ギルド解散を通知 - if((sd=g->member[i].sd)!=NULL){ - if(sd->state.storage_flag) - storage_guild_storage_quit(sd,1); - sd->status.guild_id=0; - sd->guild_sended=0; - clif_guild_broken(g->member[i].sd,0); - } - } - - numdb_foreach(guild_db,guild_broken_sub,guild_id); - numdb_erase(guild_db,guild_id); - guild_storage_delete(guild_id); - aFree(g); - return 0; -} - -// ギルド解散 -int guild_break(struct map_session_data *sd,char *name) -{ - struct guild *g; - int i; - - nullpo_retr(0, sd); - - if( (g=guild_search(sd->status.guild_id))==NULL ) - return 0; - if(strcmp(g->name,name)!=0) - return 0; - if(strcmp(sd->status.name,g->master)!=0) - return 0; - for(i=0;i<g->max_member;i++){ - if( g->member[i].account_id>0 && ( - g->member[i].account_id!=sd->status.account_id || - g->member[i].char_id!=sd->status.char_id )) - break; - } - if(i<g->max_member){ - clif_guild_broken(sd,2); - return 0; - } - - intif_guild_break(g->guild_id); - return 0; -} - -// ギルド城データ要求 -int guild_castledataload(int castle_id,int index) -{ - return intif_guild_castle_dataload(castle_id,index); -} -// ギルド城情報所得時イベント追加 -int guild_addcastleinfoevent(int castle_id,int index,const char *name) -{ - struct eventlist *ev; - int code=castle_id|(index<<16); - - if( name==NULL || *name==0 ) - return 0; - - ev=(struct eventlist *)aCalloc(1,sizeof(struct eventlist)); - memcpy(ev->name,name,sizeof(ev->name)); - ev->next=(struct eventlist *) numdb_search(guild_castleinfoevent_db,code); - numdb_insert(guild_castleinfoevent_db,code,ev); - return 0; -} - -// ギルド城データ要求返信 -int guild_castledataloadack(int castle_id,int index,int value) -{ - struct guild_castle *gc=guild_castle_search(castle_id); - int code=castle_id|(index<<16); - struct eventlist *ev,*ev2; - - if(gc==NULL){ - return 0; - } - switch(index){ - case 1: gc->guild_id = value; break; - case 2: gc->economy = value; break; - case 3: gc->defense = value; break; - case 4: gc->triggerE = value; break; - case 5: gc->triggerD = value; break; - case 6: gc->nextTime = value; break; - case 7: gc->payTime = value; break; - case 8: gc->createTime = value; break; - case 9: gc->visibleC = value; break; - case 10: gc->visibleG0 = value; break; - case 11: gc->visibleG1 = value; break; - case 12: gc->visibleG2 = value; break; - case 13: gc->visibleG3 = value; break; - case 14: gc->visibleG4 = value; break; - case 15: gc->visibleG5 = value; break; - case 16: gc->visibleG6 = value; break; - case 17: gc->visibleG7 = value; break; - case 18: gc->Ghp0 = value; break; // guardian HP [Valaris] - case 19: gc->Ghp1 = value; break; - case 20: gc->Ghp2 = value; break; - case 21: gc->Ghp3 = value; break; - case 22: gc->Ghp4 = value; break; - case 23: gc->Ghp5 = value; break; - case 24: gc->Ghp6 = value; break; - case 25: gc->Ghp7 = value; break; // end additions [Valaris] - default: - printf("guild_castledataloadack ERROR!! (Not found index=%d)\n", index); - return 0; - } - if( (ev=(struct eventlist *) numdb_search(guild_castleinfoevent_db,code))!=NULL ){ - numdb_erase(guild_castleinfoevent_db,code); - while(ev){ - npc_event_do(ev->name); - ev2=ev->next; - aFree(ev); - ev=ev2; - } - } - return 1; -} -// ギルド城データ変更要求 -int guild_castledatasave(int castle_id,int index,int value) -{ - return intif_guild_castle_datasave(castle_id,index,value); -} - -// ギルド城データ変更通知 -int guild_castledatasaveack(int castle_id,int index,int value) -{ - struct guild_castle *gc=guild_castle_search(castle_id); - if(gc==NULL){ - return 0; - } - switch(index){ - case 1: gc->guild_id = value; break; - case 2: gc->economy = value; break; - case 3: gc->defense = value; break; - case 4: gc->triggerE = value; break; - case 5: gc->triggerD = value; break; - case 6: gc->nextTime = value; break; - case 7: gc->payTime = value; break; - case 8: gc->createTime = value; break; - case 9: gc->visibleC = value; break; - case 10: gc->visibleG0 = value; break; - case 11: gc->visibleG1 = value; break; - case 12: gc->visibleG2 = value; break; - case 13: gc->visibleG3 = value; break; - case 14: gc->visibleG4 = value; break; - case 15: gc->visibleG5 = value; break; - case 16: gc->visibleG6 = value; break; - case 17: gc->visibleG7 = value; break; - case 18: gc->Ghp0 = value; break; // guardian HP [Valaris] - case 19: gc->Ghp1 = value; break; - case 20: gc->Ghp2 = value; break; - case 21: gc->Ghp3 = value; break; - case 22: gc->Ghp4 = value; break; - case 23: gc->Ghp5 = value; break; - case 24: gc->Ghp6 = value; break; - case 25: gc->Ghp7 = value; break; // end additions [Valaris] - default: - printf("guild_castledatasaveack ERROR!! (Not found index=%d)\n", index); - return 0; - } - return 1; -} - -// ギルドデータ一括受信(初期化時) -int guild_castlealldataload(int len,struct guild_castle *gc) -{ - int i; - int n = (len-4) / sizeof(struct guild_castle), ev = -1; - - nullpo_retr(0, gc); - - // イベント付きで要求するデータ位置を探す(最後の占拠データ) - for(i = 0; i < n; i++) { - if ((gc + i)->guild_id) - ev = i; - } - - // 城データ格納とギルド情報要求 - for(i = 0; i < n; i++, gc++) { - struct guild_castle *c = guild_castle_search(gc->castle_id); - if (!c) { - printf("guild_castlealldataload ??\n"); - continue; - } - memcpy(&c->guild_id,&gc->guild_id, - sizeof(struct guild_castle) - ((int)&c->guild_id - (int)c) ); - if( c->guild_id ){ - if(i!=ev) - guild_request_info(c->guild_id); - else - guild_npc_request_info(c->guild_id, "::OnAgitInit"); - } - } - if (ev == -1) - npc_event_doall("OnAgitInit"); - return 0; -} - -int guild_agit_start(void) -{ // Run All NPC_Event[OnAgitStart] - int c = npc_event_doall("OnAgitStart"); - printf("NPC_Event:[OnAgitStart] Run (%d) Events by @AgitStart.\n",c); - // Start auto saving - guild_save_timer = add_timer_interval (gettick() + GUILD_SAVE_INTERVAL, guild_save_sub, 0, 0, GUILD_SAVE_INTERVAL); - return 0; -} - -int guild_agit_end(void) -{ // Run All NPC_Event[OnAgitEnd] - int c = npc_event_doall("OnAgitEnd"); - printf("NPC_Event:[OnAgitEnd] Run (%d) Events by @AgitEnd.\n",c); - // Stop auto saving - delete_timer (guild_save_timer, guild_save_sub); - return 0; -} - -int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data) -{ // Run One NPC_Event[OnAgitEliminate] - char *name = (char*)data; - size_t len = (name) ? strlen(name) : 0; - // the rest is dangerous, but let it crash, - // if this happens, it's ruined anyway - char *evname=(char*)aMalloc( (len + 4) * sizeof(char)); - int c=0; - - if(agit_flag) // Agit not already End - { - memcpy(evname,name,len - 5); - strcpy(evname + len - 5,"Eliminate"); - c = npc_event_do(evname); - printf("NPC_Event:[%s] Run (%d) Events.\n",evname,c); - } - if(name) aFree(name); - return 0; -} - -static int Ghp[MAX_GUILDCASTLE][8]; // so save only if HP are changed // experimental code [Yor] -static int Gid[MAX_GUILDCASTLE]; -int guild_save_sub(int tid,unsigned int tick,int id,int data) -{ - struct guild_castle *gc; - int i; - - for(i = 0; i < MAX_GUILDCASTLE; i++) { // [Yor] - gc = guild_castle_search(i); - if (!gc) continue; - if (gc->guild_id != Gid[i]) { - // Re-save guild id if its owner guild has changed - // This should already be done in gldfunc_ev_agit.txt, - // but since people have complained... Well x3 - guild_castledatasave(gc->castle_id, 1, gc->guild_id); - Gid[i] = gc->guild_id; - } - if (gc->visibleG0 == 1 && Ghp[i][0] != gc->Ghp0) { - guild_castledatasave(gc->castle_id, 18, gc->Ghp0); - Ghp[i][0] = gc->Ghp0; - } - if (gc->visibleG1 == 1 && Ghp[i][1] != gc->Ghp1) { - guild_castledatasave(gc->castle_id, 19, gc->Ghp1); - Ghp[i][1] = gc->Ghp1; - } - if (gc->visibleG2 == 1 && Ghp[i][2] != gc->Ghp2) { - guild_castledatasave(gc->castle_id, 20, gc->Ghp2); - Ghp[i][2] = gc->Ghp2; - } - if (gc->visibleG3 == 1 && Ghp[i][3] != gc->Ghp3) { - guild_castledatasave(gc->castle_id, 21, gc->Ghp3); - Ghp[i][3] = gc->Ghp3; - } - if (gc->visibleG4 == 1 && Ghp[i][4] != gc->Ghp4) { - guild_castledatasave(gc->castle_id, 22, gc->Ghp4); - Ghp[i][4] = gc->Ghp4; - } - if (gc->visibleG5 == 1 && Ghp[i][5] != gc->Ghp5) { - guild_castledatasave(gc->castle_id, 23, gc->Ghp5); - Ghp[i][5] = gc->Ghp5; - } - if (gc->visibleG6 == 1 && Ghp[i][6] != gc->Ghp6) { - guild_castledatasave(gc->castle_id, 24, gc->Ghp6); - Ghp[i][6] = gc->Ghp6; - } - if (gc->visibleG7 == 1 && Ghp[i][7] != gc->Ghp7) { - guild_castledatasave(gc->castle_id, 25, gc->Ghp7); - Ghp[i][7] = gc->Ghp7; - } - } - - return 0; -} - -int guild_agit_break(struct mob_data *md) -{ // Run One NPC_Event[OnAgitBreak] - char *evname; - - nullpo_retr(0, md); - - evname=(char *)aCallocA(strlen(md->npc_event) + 1, sizeof(char)); - - strcpy(evname,md->npc_event); -// Now By User to Run [OnAgitBreak] NPC Event... -// It's a little impossible to null point with player disconnect in this! -// But Script will be stop, so nothing... -// Maybe will be changed in the futher.. -// int c = npc_event_do(evname); - if(!agit_flag) return 0; // Agit already End - add_timer(gettick()+battle_config.gvg_eliminate_time,guild_gvg_eliminate_timer,md->bl.m,(int)evname); - return 0; -} - -// [MouseJstr] -// How many castles does this guild have? -int guild_checkcastles(struct guild *g) { - int i,nb_cas=0, id,cas_id=0; - struct guild_castle *gc; - id=g->guild_id; - for(i=0;i<MAX_GUILDCASTLE;i++){ - gc=guild_castle_search(i); - cas_id=gc->guild_id; - if(g->guild_id==cas_id) - nb_cas=nb_cas+1; - } //end for - return nb_cas; -} - -// [MouseJstr] -// is this guild allied with this castle? -int guild_isallied(struct guild *g, struct guild_castle *gc) -{ - int i; - - nullpo_retr(0, g); - - if(g->guild_id == gc->guild_id) - return 1; - - if (gc->guild_id == 0) - return 0; - - - for(i=0;i<MAX_GUILDALLIANCE;i++) - if(g->alliance[i].guild_id == gc->guild_id) { - if(g->alliance[i].opposition == 0) - return 1; - else - return 0; - } - - return 0; -} - -static int guild_db_final(void *key,void *data,va_list ap) -{ - struct guild *g=(struct guild *) data; - - aFree(g); - - return 0; -} -static int castle_db_final(void *key,void *data,va_list ap) -{ - struct guild_castle *gc=(struct guild_castle *) data; - - aFree(gc); - - return 0; -} -static int guild_expcache_db_final(void *key,void *data,va_list ap) -{ - struct guild_expcache *c=(struct guild_expcache *) data; - - aFree(c); - - return 0; -} -static int guild_infoevent_db_final(void *key,void *data,va_list ap) -{ - struct eventlist *ev=(struct eventlist *) data; - - aFree(ev); - - return 0; -} -void do_final_guild(void) -{ - if(guild_db) - numdb_final(guild_db,guild_db_final); - if(castle_db) - numdb_final(castle_db,castle_db_final); - if(guild_expcache_db) - numdb_final(guild_expcache_db,guild_expcache_db_final); - if(guild_infoevent_db) - numdb_final(guild_infoevent_db,guild_infoevent_db_final); - if(guild_castleinfoevent_db) - numdb_final(guild_castleinfoevent_db,guild_infoevent_db_final); -} diff --git a/src/map/guild.h b/src/map/guild.h deleted file mode 100644 index 1dee350a1..000000000 --- a/src/map/guild.h +++ /dev/null @@ -1,89 +0,0 @@ -// $Id: guild.h,v 1.4 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _GUILD_H_ -#define _GUILD_H_ - -struct map_session_data; -struct mob_data; -struct guild; -struct guild_member; -struct guild_position; -struct guild_castle; - -int guild_skill_get_inf(int id); -int guild_skill_get_sp(int id,int lv); -int guild_skill_get_range(int id); -int guild_skill_get_max(int id); - -int guild_checkskill(struct guild *g,int id); -int guild_checkcastles(struct guild *g); // [MouseJstr] -int guild_isallied(struct guild *g, struct guild_castle *gc); - -void do_init_guild(void); -struct guild *guild_search(int guild_id); -struct guild *guild_searchname(char *str); -struct guild_castle *guild_castle_search(int gcid); - -struct guild_castle *guild_mapname2gc(char *mapname); - -struct map_session_data *guild_getavailablesd(struct guild *g); -int guild_getindex(struct guild *g,int account_id,int char_id); -int guild_getposition(struct map_session_data *sd,struct guild *g); -int guild_payexp(struct map_session_data *sd,int exp); -int guild_getexp(struct map_session_data *sd,int exp); // [Celest] - -int guild_create(struct map_session_data *sd,char *name); -int guild_created(int account_id,int guild_id); -int guild_request_info(int guild_id); -int guild_recv_noinfo(int guild_id); -int guild_recv_info(struct guild *sg); -int guild_npc_request_info(int guild_id,const char *ev); -int guild_invite(struct map_session_data *sd,int account_id); -int guild_reply_invite(struct map_session_data *sd,int guild_id,int flag); -int guild_member_added(int guild_id,int account_id,int char_id,int flag); -int guild_leave(struct map_session_data *sd,int guild_id, - int account_id,int char_id,const char *mes); -int guild_member_leaved(int guild_id,int account_id,int char_id,int flag, - const char *name,const char *mes); -int guild_explusion(struct map_session_data *sd,int guild_id, - int account_id,int char_id,const char *mes); -int guild_skillup(struct map_session_data *sd,int skill_num,int flag); -int guild_reqalliance(struct map_session_data *sd,int account_id); -int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag); -int guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2); -int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2, - int flag,const char *name1,const char *name2); -int guild_delalliance(struct map_session_data *sd,int guild_id,int flag); -int guild_opposition(struct map_session_data *sd,int char_id); -int guild_check_alliance(int guild_id1, int guild_id2, int flag); - -int guild_send_memberinfoshort(struct map_session_data *sd,int online); -int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_); -int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx); -int guild_memberposition_changed(struct guild *g,int idx,int pos); -int guild_change_position(struct map_session_data *sd,int idx, - int mode,int exp_mode,const char *name); -int guild_position_changed(int guild_id,int idx,struct guild_position *p); -int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2); -int guild_notice_changed(int guild_id,const char *mes1,const char *mes2); -int guild_change_emblem(struct map_session_data *sd,int len,const char *data); -int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data); -int guild_send_message(struct map_session_data *sd,char *mes,int len); -int guild_recv_message(int guild_id,int account_id,char *mes,int len); -int guild_skillupack(int guild_id,int skill_num,int account_id); -int guild_break(struct map_session_data *sd,char *name); -int guild_broken(int guild_id,int flag); - -int guild_addcastleinfoevent(int castle_id,int index,const char *name); -int guild_castledataload(int castle_id,int index); -int guild_castledataloadack(int castle_id,int index,int value); -int guild_castledatasave(int castle_id,int index,int value); -int guild_castledatasaveack(int castle_id,int index,int value); -int guild_castlealldataload(int len,struct guild_castle *gc); - -int guild_agit_start(void); -int guild_agit_end(void); -int guild_agit_break(struct mob_data *md); - -void do_final_guild(void); - -#endif diff --git a/src/map/intif.c b/src/map/intif.c deleted file mode 100644 index 3aa472ad8..000000000 --- a/src/map/intif.c +++ /dev/null @@ -1,1167 +0,0 @@ -// $Id: intif.c,v 1.2 2004/09/25 05:32:18 MouseJstr Exp $ -#include <sys/types.h> -#ifdef _WIN32 -#include <winsock.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#ifndef _WIN32 -#include <sys/time.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <arpa/inet.h> -#endif -#include <signal.h> -#include <fcntl.h> -#include <string.h> - -#include "socket.h" -#include "timer.h" -#include "map.h" -#include "battle.h" -#include "chrif.h" -#include "clif.h" -#include "pc.h" -#include "intif.h" -#include "storage.h" -#include "party.h" -#include "guild.h" -#include "pet.h" -#include "nullpo.h" -#include "malloc.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -static const int packet_len_table[]={ - -1,-1,27,-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, - 35,-1,11,15, 34,29, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, - 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, - 9, 9,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -extern int char_fd; // inter serverのfdはchar_fdを使う -#define inter_fd (char_fd) // エイリアス - -//----------------------------------------------------------------- -// inter serverへの送信 - -int CheckForCharServer() { - return ((char_fd == -1) || session[char_fd] == NULL || session[char_fd]->wdata == NULL); -} - -// pet -int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id, - short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3080; - WFIFOL(inter_fd,2) = account_id; - WFIFOL(inter_fd,6) = char_id; - WFIFOW(inter_fd,10) = pet_class; - WFIFOW(inter_fd,12) = pet_lv; - WFIFOW(inter_fd,14) = pet_egg_id; - WFIFOW(inter_fd,16) = pet_equip; - WFIFOW(inter_fd,18) = intimate; - WFIFOW(inter_fd,20) = hungry; - WFIFOB(inter_fd,22) = rename_flag; - WFIFOB(inter_fd,23) = incuvate; - memcpy(WFIFOP(inter_fd,24),pet_name,24); - WFIFOSET(inter_fd,48); - - return 0; -} - -int intif_request_petdata(int account_id,int char_id,int pet_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3081; - WFIFOL(inter_fd,2) = account_id; - WFIFOL(inter_fd,6) = char_id; - WFIFOL(inter_fd,10) = pet_id; - WFIFOSET(inter_fd,14); - - return 0; -} - -int intif_save_petdata(int account_id,struct s_pet *p) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3082; - WFIFOW(inter_fd,2) = sizeof(struct s_pet) + 8; - WFIFOL(inter_fd,4) = account_id; - memcpy(WFIFOP(inter_fd,8),p,sizeof(struct s_pet)); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - - return 0; -} - -int intif_delete_petdata(int pet_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3083; - WFIFOL(inter_fd,2) = pet_id; - WFIFOSET(inter_fd,6); - - return 0; -} - -// GMメッセージを送信 -int intif_GMmessage(char* mes,int len,int flag) -{ - int lp = (flag&0x10) ? 8 : 4; - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3000; - WFIFOW(inter_fd,2) = lp + len; - WFIFOL(inter_fd,4) = 0x65756c62; - memcpy(WFIFOP(inter_fd,lp), mes, len); - WFIFOSET(inter_fd, WFIFOW(inter_fd,2)); - - // Send to the local players - clif_GMmessage(NULL, mes, len, 0); - - return 0; -} - -// The transmission of Wisp/Page to inter-server (player not found on this server) -int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int mes_len) { - nullpo_retr(0, sd); - if (CheckForCharServer()) - return 0; - - WFIFOW(inter_fd,0) = 0x3001; - WFIFOW(inter_fd,2) = mes_len + 52; - memcpy(WFIFOP(inter_fd,4), sd->status.name, 24); - memcpy(WFIFOP(inter_fd,28), nick, 24); - memcpy(WFIFOP(inter_fd,52), mes, mes_len); - WFIFOSET(inter_fd, WFIFOW(inter_fd,2)); - - if (battle_config.etc_log) - printf("intif_wis_message from %s to %s (message: '%s')\n", sd->status.name, nick, mes); - - return 0; -} - -// The reply of Wisp/page -int intif_wis_replay(int id, int flag) { - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3002; - WFIFOL(inter_fd,2) = id; - WFIFOB(inter_fd,6) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - WFIFOSET(inter_fd,7); - - if (battle_config.etc_log) - printf("intif_wis_replay: id: %d, flag:%d\n", id, flag); - - return 0; -} - -// The transmission of GM only Wisp/Page from server to inter-server -int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes) { - int mes_len; - if (CheckForCharServer()) - return 0; - mes_len = strlen(mes) + 1; // + null - WFIFOW(inter_fd,0) = 0x3003; - WFIFOW(inter_fd,2) = mes_len + 30; - memcpy(WFIFOP(inter_fd,4), Wisp_name, 24); - WFIFOW(inter_fd,28) = (short)min_gm_level; - memcpy(WFIFOP(inter_fd,30), mes, mes_len); - WFIFOSET(inter_fd, WFIFOW(inter_fd,2)); - - if (battle_config.etc_log) - printf("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n", Wisp_name, min_gm_level, mes); - - return 0; -} - -// アカウント変数送信 -int intif_saveaccountreg(struct map_session_data *sd) { - int j,p; - if (CheckForCharServer()) - return 0; - - nullpo_retr(0, sd); - - if (sd->status.account_reg_num == -1) - return 0; - - WFIFOW(inter_fd,0) = 0x3004; - WFIFOL(inter_fd,4) = sd->bl.id; - for(j=0,p=8;j<sd->status.account_reg_num;j++,p+=36){ - memcpy(WFIFOP(inter_fd,p),sd->status.account_reg[j].str,32); - WFIFOL(inter_fd,p+32)=sd->status.account_reg[j].value; - } - WFIFOW(inter_fd,2)=p; - WFIFOSET(inter_fd,p); - return 0; -} -// アカウント変数要求 -int intif_request_accountreg(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - if (CheckForCharServer()) - return 0; - - WFIFOW(inter_fd,0) = 0x3005; - WFIFOL(inter_fd,2) = sd->bl.id; - WFIFOSET(inter_fd,6); - - sd->status.account_reg_num = -1; - - return 0; -} - -// 倉庫データ要求 -int intif_request_storage(int account_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3010; - WFIFOL(inter_fd,2) = account_id; - WFIFOSET(inter_fd,6); - return 0; -} -// 倉庫データ送信 -int intif_send_storage(struct storage *stor) -{ - if (CheckForCharServer()) - return 0; - nullpo_retr(0, stor); - WFIFOW(inter_fd,0) = 0x3011; - WFIFOW(inter_fd,2) = sizeof(struct storage)+8; - WFIFOL(inter_fd,4) = stor->account_id; - memcpy( WFIFOP(inter_fd,8),stor, sizeof(struct storage) ); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 0; -} - -int intif_request_guild_storage(int account_id,int guild_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3018; - WFIFOL(inter_fd,2) = account_id; - WFIFOL(inter_fd,6) = guild_id; - WFIFOSET(inter_fd,10); - return 0; -} -int intif_send_guild_storage(int account_id,struct guild_storage *gstor) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3019; - WFIFOW(inter_fd,2) = sizeof(struct guild_storage)+12; - WFIFOL(inter_fd,4) = account_id; - WFIFOL(inter_fd,8) = gstor->guild_id; - memcpy( WFIFOP(inter_fd,12),gstor, sizeof(struct guild_storage) ); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 0; -} - -// パーティ作成要求 -int intif_create_party(struct map_session_data *sd,char *name,int item,int item2) -{ - if (CheckForCharServer()) - return 0; - nullpo_retr(0, sd); - - WFIFOW(inter_fd,0) = 0x3020; - WFIFOL(inter_fd,2) = sd->status.account_id; - memcpy(WFIFOP(inter_fd, 6),name,24); - memcpy(WFIFOP(inter_fd,30),sd->status.name,24); - memcpy(WFIFOP(inter_fd,54),map[sd->bl.m].name,16); - WFIFOW(inter_fd,70)= sd->status.base_level; - WFIFOB(inter_fd,72)= item; - WFIFOB(inter_fd,73)= item2; - WFIFOSET(inter_fd,74); -// if(battle_config.etc_log) -// printf("intif: create party\n"); - return 0; -} -// パーティ情報要求 -int intif_request_partyinfo(int party_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3021; - WFIFOL(inter_fd,2) = party_id; - WFIFOSET(inter_fd,6); -// if(battle_config.etc_log) -// printf("intif: request party info\n"); - return 0; -} -// パーティ追加要求 -int intif_party_addmember(int party_id,int account_id) -{ - struct map_session_data *sd; - if (CheckForCharServer()) - return 0; - sd=map_id2sd(account_id); -// if(battle_config.etc_log) -// printf("intif: party add member %d %d\n",party_id,account_id); - if(sd!=NULL){ - WFIFOW(inter_fd,0)=0x3022; - WFIFOL(inter_fd,2)=party_id; - WFIFOL(inter_fd,6)=account_id; - memcpy(WFIFOP(inter_fd,10),sd->status.name,24); - memcpy(WFIFOP(inter_fd,34),map[sd->bl.m].name,16); - WFIFOW(inter_fd,50)=sd->status.base_level; - WFIFOSET(inter_fd,52); - } - return 0; -} -// パーティ設定変更 -int intif_party_changeoption(int party_id,int account_id,int exp,int item) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3023; - WFIFOL(inter_fd,2)=party_id; - WFIFOL(inter_fd,6)=account_id; - WFIFOW(inter_fd,10)=exp; - WFIFOW(inter_fd,12)=item; - WFIFOSET(inter_fd,14); - return 0; -} -// パーティ脱退要求 -int intif_party_leave(int party_id,int account_id) -{ - if (CheckForCharServer()) - return 0; -// if(battle_config.etc_log) -// printf("intif: party leave %d %d\n",party_id,account_id); - WFIFOW(inter_fd,0)=0x3024; - WFIFOL(inter_fd,2)=party_id; - WFIFOL(inter_fd,6)=account_id; - WFIFOSET(inter_fd,10); - return 0; -} -// パーティ移動要求 -int intif_party_changemap(struct map_session_data *sd,int online) -{ - if (CheckForCharServer()) - return 0; - if(sd!=NULL){ - WFIFOW(inter_fd,0)=0x3025; - WFIFOL(inter_fd,2)=sd->status.party_id; - WFIFOL(inter_fd,6)=sd->status.account_id; - memcpy(WFIFOP(inter_fd,10),map[sd->bl.m].name,16); - WFIFOB(inter_fd,26)=online; - WFIFOW(inter_fd,27)=sd->status.base_level; - WFIFOSET(inter_fd,29); - } -// if(battle_config.etc_log) -// printf("party: change map\n"); - return 0; -} -// パーティー解散要求 -int intif_break_party(int party_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3026; - WFIFOL(inter_fd,2)=party_id; - WFIFOSET(inter_fd,6); - return 0; -} -// パーティ会話送信 -int intif_party_message(int party_id,int account_id,char *mes,int len) -{ - if (CheckForCharServer()) - return 0; -// if(battle_config.etc_log) -// printf("intif_party_message: %s\n",mes); - WFIFOW(inter_fd,0)=0x3027; - WFIFOW(inter_fd,2)=len+12; - WFIFOL(inter_fd,4)=party_id; - WFIFOL(inter_fd,8)=account_id; - memcpy(WFIFOP(inter_fd,12),mes,len); - WFIFOSET(inter_fd,len+12); - return 0; -} -// パーティ競合チェック要求 -int intif_party_checkconflict(int party_id,int account_id,char *nick) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3028; - WFIFOL(inter_fd,2)=party_id; - WFIFOL(inter_fd,6)=account_id; - memcpy(WFIFOP(inter_fd,10),nick,24); - WFIFOSET(inter_fd,34); - return 0; -} - -// ギルド作成要求 -int intif_guild_create(const char *name,const struct guild_member *master) -{ - if (CheckForCharServer()) - return 0; - nullpo_retr(0, master); - - WFIFOW(inter_fd,0)=0x3030; - WFIFOW(inter_fd,2)=sizeof(struct guild_member)+32; - WFIFOL(inter_fd,4)=master->account_id; - memcpy(WFIFOP(inter_fd,8),name,24); - memcpy(WFIFOP(inter_fd,32),master,sizeof(struct guild_member)); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 0; -} -// ギルド情報要求 -int intif_guild_request_info(int guild_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3031; - WFIFOL(inter_fd,2) = guild_id; - WFIFOSET(inter_fd,6); - return 0; -} -// ギルドメンバ追加要求 -int intif_guild_addmember(int guild_id,struct guild_member *m) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0) = 0x3032; - WFIFOW(inter_fd,2) = sizeof(struct guild_member)+8; - WFIFOL(inter_fd,4) = guild_id; - memcpy(WFIFOP(inter_fd,8),m,sizeof(struct guild_member)); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 0; -} -// ギルドメンバ脱退/追放要求 -int intif_guild_leave(int guild_id,int account_id,int char_id,int flag,const char *mes) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0) = 0x3034; - WFIFOL(inter_fd, 2) = guild_id; - WFIFOL(inter_fd, 6) = account_id; - WFIFOL(inter_fd,10) = char_id; - WFIFOB(inter_fd,14) = flag; - memcpy(WFIFOP(inter_fd,15),mes,40); - WFIFOSET(inter_fd,55); - return 0; -} -// ギルドメンバのオンライン状況/Lv更新要求 -int intif_guild_memberinfoshort(int guild_id, - int account_id,int char_id,int online,int lv,int class_) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0) = 0x3035; - WFIFOL(inter_fd, 2) = guild_id; - WFIFOL(inter_fd, 6) = account_id; - WFIFOL(inter_fd,10) = char_id; - WFIFOB(inter_fd,14) = online; - WFIFOW(inter_fd,15) = lv; - WFIFOW(inter_fd,17) = class_; - WFIFOSET(inter_fd,19); - return 0; -} -// ギルド解散通知 -int intif_guild_break(int guild_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0) = 0x3036; - WFIFOL(inter_fd, 2) = guild_id; - WFIFOSET(inter_fd,6); - return 0; -} -// ギルド会話送信 -int intif_guild_message(int guild_id,int account_id,char *mes,int len) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3037; - WFIFOW(inter_fd,2)=len+12; - WFIFOL(inter_fd,4)=guild_id; - WFIFOL(inter_fd,8)=account_id; - memcpy(WFIFOP(inter_fd,12),mes,len); - WFIFOSET(inter_fd,len+12); - - return 0; -} -// ギルド競合チェック要求 -int intif_guild_checkconflict(int guild_id,int account_id,int char_id) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0)=0x3038; - WFIFOL(inter_fd, 2)=guild_id; - WFIFOL(inter_fd, 6)=account_id; - WFIFOL(inter_fd,10)=char_id; - WFIFOSET(inter_fd,14); - return 0; -} -// ギルド基本情報変更要求 -int intif_guild_change_basicinfo(int guild_id,int type,const void *data,int len) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3039; - WFIFOW(inter_fd,2)=len+10; - WFIFOL(inter_fd,4)=guild_id; - WFIFOW(inter_fd,8)=type; - memcpy(WFIFOP(inter_fd,10),data,len); - WFIFOSET(inter_fd,len+10); - return 0; -} -// ギルドメンバ情報変更要求 -int intif_guild_change_memberinfo(int guild_id,int account_id,int char_id, - int type,const void *data,int len) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0)=0x303a; - WFIFOW(inter_fd, 2)=len+18; - WFIFOL(inter_fd, 4)=guild_id; - WFIFOL(inter_fd, 8)=account_id; - WFIFOL(inter_fd,12)=char_id; - WFIFOW(inter_fd,16)=type; - memcpy(WFIFOP(inter_fd,18),data,len); - WFIFOSET(inter_fd,len+18); - return 0; -} -// ギルド役職変更要求 -int intif_guild_position(int guild_id,int idx,struct guild_position *p) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x303b; - WFIFOW(inter_fd,2)=sizeof(struct guild_position)+12; - WFIFOL(inter_fd,4)=guild_id; - WFIFOL(inter_fd,8)=idx; - memcpy(WFIFOP(inter_fd,12),p,sizeof(struct guild_position)); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 0; -} -// ギルドスキルアップ要求 -int intif_guild_skillup(int guild_id,int skill_num,int account_id,int flag) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0)=0x303c; - WFIFOL(inter_fd, 2)=guild_id; - WFIFOL(inter_fd, 6)=skill_num; - WFIFOL(inter_fd,10)=account_id; - //WFIFOL(inter_fd,14)=flag; - WFIFOSET(inter_fd,14); - return 0; -} -// ギルド同盟/敵対要求 -int intif_guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd, 0)=0x303d; - WFIFOL(inter_fd, 2)=guild_id1; - WFIFOL(inter_fd, 6)=guild_id2; - WFIFOL(inter_fd,10)=account_id1; - WFIFOL(inter_fd,14)=account_id2; - WFIFOB(inter_fd,18)=flag; - WFIFOSET(inter_fd,19); - return 0; -} -// ギルド告知変更要求 -int intif_guild_notice(int guild_id,const char *mes1,const char *mes2) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x303e; - WFIFOL(inter_fd,2)=guild_id; - memcpy(WFIFOP(inter_fd,6),mes1,60); - memcpy(WFIFOP(inter_fd,66),mes2,120); - WFIFOSET(inter_fd,186); - return 0; -} -// ギルドエンブレム変更要求 -int intif_guild_emblem(int guild_id,int len,const char *data) -{ - if (CheckForCharServer()) - return 0; - if(guild_id<=0 || len<0 || len>2000) - return 0; - WFIFOW(inter_fd,0)=0x303f; - WFIFOW(inter_fd,2)=len+12; - WFIFOL(inter_fd,4)=guild_id; - WFIFOL(inter_fd,8)=0; - memcpy(WFIFOP(inter_fd,12),data,len); - WFIFOSET(inter_fd,len+12); - return 0; -} -//現在のギルド城占領ギルドを調べる -int intif_guild_castle_dataload(int castle_id,int index) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3040; - WFIFOW(inter_fd,2)=castle_id; - WFIFOB(inter_fd,4)=index; - WFIFOSET(inter_fd,5); - return 0; -} - -//ギルド城占領ギルド変更要求 -int intif_guild_castle_datasave(int castle_id,int index, int value) -{ - if (CheckForCharServer()) - return 0; - WFIFOW(inter_fd,0)=0x3041; - WFIFOW(inter_fd,2)=castle_id; - WFIFOB(inter_fd,4)=index; - WFIFOL(inter_fd,5)=value; - WFIFOSET(inter_fd,9); - return 0; -} - -//----------------------------------------------------------------- -// Packets receive from inter server - -// Wisp/Page reception -int intif_parse_WisMessage(int fd) { // rewritten by [Yor] - struct map_session_data* sd; - char *wisp_source; - int id=RFIFOL(fd,4); - int i=0; //,j=0; - -// if(battle_config.etc_log) -// printf("intif_parse_wismessage: %d %s %s %s\n",id,RFIFOP(fd,6),RFIFOP(fd,30),RFIFOP(fd,54) ); - - sd=(struct map_session_data *) map_nick2sd((char *) RFIFOP(fd,32)); // 送信先を探す - if(sd!=NULL && strcmp((char *) sd->status.name, (char *) RFIFOP(fd,32)) == 0){ -/* - for(i=0;i<MAX_WIS_REFUSAL;i++){ //拒否リストに名前があるかどうか判定してあれば拒否 - if(strcmp(sd->wis_refusal[i],RFIFOP(fd,8))==0){ - j++; - break; - } - } -*/ - if(sd->ignoreAll == 1) - intif_wis_replay(RFIFOL(fd,4), 2); // 受信拒否 -/* - else if(j>0) - intif_wis_replay(id,2); // 受信拒否 - - else{ -*/ - else { - wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor] - for(i=0;i<MAX_IGNORE_LIST;i++){ //拒否リストに名前があるかどうか判定してあれば拒否 - if(strcmp(sd->ignore[i].name, wisp_source)==0){ - break; - } - } - if(i==MAX_IGNORE_LIST) // run out of list, so we are not ignored - { - clif_wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56); - intif_wis_replay(id,0); // 送信成功 - } - else - intif_wis_replay(id, 2); // 受信拒否 - } - }else - intif_wis_replay(id,1); // そんな人いません - return 0; -} - -// Wisp/page transmission result reception -int intif_parse_WisEnd(int fd) { - struct map_session_data* sd; - - if (battle_config.etc_log) - printf("intif_parse_wisend: player: %s, flag: %d\n", RFIFOP(fd,2), RFIFOB(fd,26)); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - sd = (struct map_session_data *)map_nick2sd((char *) RFIFOP(fd,2)); - if (sd != NULL) - clif_wis_end(sd->fd, RFIFOB(fd,26)); - - return 0; -} - -// Received wisp message from map-server via char-server for ALL gm -int mapif_parse_WisToGM(int fd) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B - int i, min_gm_level; - struct map_session_data *pl_sd; - char Wisp_name[24]; - char mbuf[255]; - char *message = (char *) (((RFIFOW(fd,2) - 30) >= sizeof(mbuf)) ? (char *) aMallocA((RFIFOW(fd,2) - 30)) : mbuf); - - min_gm_level = (int)RFIFOW(fd,28); - memcpy(Wisp_name, RFIFOP(fd,4), 24); - Wisp_name[23] = '\0'; - memcpy(message, RFIFOP(fd,30), RFIFOW(fd,2) - 30); - message[sizeof(message) - 1] = '\0'; - // information is sended to all online GM - for (i = 0; i < fd_max; i++) - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) - if (pc_isGM(pl_sd) >= min_gm_level) - clif_wis_message(i, Wisp_name, message, strlen(message) + 1); - - if (message != mbuf) - aFree(message); - - return 0; -} - -// アカウント変数通知 -int intif_parse_AccountReg(int fd) { - int j,p; - struct map_session_data *sd; - - if( (sd=map_id2sd(RFIFOL(fd,4)))==NULL ) - return 1; - for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG_NUM;p+=36,j++){ - memcpy(sd->status.account_reg[j].str,RFIFOP(fd,p),32); - sd->status.account_reg[j].value=RFIFOL(fd,p+32); - } - sd->status.account_reg_num = j; -// printf("intif: accountreg\n"); - - return 0; -} - -// 倉庫データ受信 -int intif_parse_LoadStorage(int fd) { - struct storage *stor; - struct map_session_data *sd; - - stor = account2storage( RFIFOL(fd,4)); - - if (stor->storage_status == 1) { // Already open.. lets ignore this update - if (battle_config.error_log) - printf("intif_parse_LoadStorage: storage received for a client already open\n"); - return 0; - } - - if (RFIFOW(fd,2)-8 != sizeof(struct storage)) { - if (battle_config.error_log) - printf("intif_parse_LoadStorage: data size error %d %d\n", RFIFOW(fd,2)-8, sizeof(struct storage)); - return 1; - } - sd=map_id2sd( RFIFOL(fd,4) ); - if(sd==NULL){ - if(battle_config.error_log) - printf("intif_parse_LoadStorage: user not found %d\n",RFIFOL(fd,4)); - return 1; - } - if(battle_config.save_log) - printf("intif_openstorage: %d\n",RFIFOL(fd,4) ); - memcpy(stor,RFIFOP(fd,8),sizeof(struct storage)); - stor->dirty=0; - stor->storage_status=1; - sd->state.storage_flag = 0; - clif_storageitemlist(sd,stor); - clif_storageequiplist(sd,stor); - clif_updatestorageamount(sd,stor); - - return 0; -} - -// 倉庫データ送信成功 -int intif_parse_SaveStorage(int fd) -{ - if(battle_config.save_log) - printf("intif_savestorage: done %d %d\n",RFIFOL(fd,2),RFIFOB(fd,6) ); - return 0; -} - -int intif_parse_LoadGuildStorage(int fd) -{ - struct guild_storage *gstor; - struct map_session_data *sd; - int guild_id = RFIFOL(fd,8); - if(guild_id > 0) { - gstor=guild2storage(guild_id); - if(!gstor) { - if(battle_config.error_log) - printf("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id); - return 1; - } - if( RFIFOW(fd,2)-12 != sizeof(struct guild_storage) ){ - gstor->storage_status = 0; - if(battle_config.error_log) - printf("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-12 , sizeof(struct guild_storage)); - return 1; - } - sd=map_id2sd( RFIFOL(fd,4) ); - if(sd==NULL){ - if(battle_config.error_log) - printf("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4)); - return 1; - } - if(battle_config.save_log) - printf("intif_open_guild_storage: %d\n",RFIFOL(fd,4) ); - memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage)); - gstor->storage_status = 1; - sd->state.storage_flag = 1; - clif_guildstorageitemlist(sd,gstor); - clif_guildstorageequiplist(sd,gstor); - clif_updateguildstorageamount(sd,gstor); - } - return 0; -} -int intif_parse_SaveGuildStorage(int fd) -{ - if(battle_config.save_log) { - printf("intif_save_guild_storage: done %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOB(fd,10) ); - } - return 0; -} - -// パーティ作成可否 -int intif_parse_PartyCreated(int fd) -{ - if(battle_config.etc_log) - printf("intif: party created\n"); - party_created(RFIFOL(fd,2), RFIFOB(fd,6),RFIFOL(fd,7),(char *) RFIFOP(fd,11)); - return 0; -} -// パーティ情報 -int intif_parse_PartyInfo(int fd) -{ - if( RFIFOW(fd,2)==8){ - if(battle_config.error_log) - printf("intif: party noinfo %d\n",RFIFOL(fd,4)); - party_recv_noinfo(RFIFOL(fd,4)); - return 0; - } - -// printf("intif: party info %d\n",RFIFOL(fd,4)); - if( RFIFOW(fd,2)!=sizeof(struct party)+4 ){ - if(battle_config.error_log) - printf("intif: party info : data size error %d %d %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct party)+4); - } - party_recv_info((struct party *)RFIFOP(fd,4)); - return 0; -} -// パーティ追加通知 -int intif_parse_PartyMemberAdded(int fd) -{ - if(battle_config.etc_log) - printf("intif: party member added %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOB(fd,10)); - party_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOB(fd,10)); - return 0; -} -// パーティ設定変更通知 -int intif_parse_PartyOptionChanged(int fd) -{ - party_optionchanged(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12),RFIFOB(fd,14)); - return 0; -} -// パーティ脱退通知 -int intif_parse_PartyMemberLeaved(int fd) -{ - if(battle_config.etc_log) - printf("intif: party member leaved %d %d %s\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10)); - party_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),(char *) RFIFOP(fd,10)); - return 0; -} -// パーティ解散通知 -int intif_parse_PartyBroken(int fd) -{ - party_broken(RFIFOL(fd,2)); - return 0; -} -// パーティ移動通知 -int intif_parse_PartyMove(int fd) -{ -// if(battle_config.etc_log) -// printf("intif: party move %d %d %s %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27)); - party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),(char *) RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27)); - return 0; -} -// パーティメッセージ -int intif_parse_PartyMessage(int fd) -{ -// if(battle_config.etc_log) -// printf("intif_parse_PartyMessage: %s\n",RFIFOP(fd,12)); - party_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12); - return 0; -} - -// ギルド作成可否 -int intif_parse_GuildCreated(int fd) -{ - guild_created(RFIFOL(fd,2),RFIFOL(fd,6)); - return 0; -} -// ギルド情報 -int intif_parse_GuildInfo(int fd) -{ - if( RFIFOW(fd,2)==8){ - if(battle_config.error_log) - printf("intif: guild noinfo %d\n",RFIFOL(fd,4)); - guild_recv_noinfo(RFIFOL(fd,4)); - return 0; - } - -// if(battle_config.etc_log) -// printf("intif: guild info %d\n",RFIFOL(fd,4)); - if( RFIFOW(fd,2)!=sizeof(struct guild)+4 ){ - if(battle_config.error_log) - printf("intif: guild info : data size error\n %d %d %d",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild)+4); - } - guild_recv_info((struct guild *)RFIFOP(fd,4)); - return 0; -} -// ギルドメンバ追加通知 -int intif_parse_GuildMemberAdded(int fd) -{ - if(battle_config.etc_log) - printf("intif: guild member added %d %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14)); - guild_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14)); - return 0; -} -// ギルドメンバ脱退/追放通知 -int intif_parse_GuildMemberLeaved(int fd) -{ - guild_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14), - (char *) RFIFOP(fd,55), (char *) RFIFOP(fd,15)); - return 0; -} - -// ギルドメンバオンライン状態/Lv変更通知 -int intif_parse_GuildMemberInfoShort(int fd) -{ - guild_recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17)); - return 0; -} -// ギルド解散通知 -int intif_parse_GuildBroken(int fd) -{ - guild_broken(RFIFOL(fd,2),RFIFOB(fd,6)); - return 0; -} - -// ギルド基本情報変更通知 -int intif_parse_GuildBasicInfoChanged(int fd) -{ - int type=RFIFOW(fd,8),guild_id=RFIFOL(fd,4); - void *data=RFIFOP(fd,10); - struct guild *g=guild_search(guild_id); - short dw=*((short *)data); - int dd=*((int *)data); - if( g==NULL ) - return 0; - switch(type){ - case GBI_EXP: g->exp=dd; break; - case GBI_GUILDLV: g->guild_lv=dw; break; - case GBI_SKILLPOINT: g->skill_point=dd; break; - } - return 0; -} -// ギルドメンバ情報変更通知 -int intif_parse_GuildMemberInfoChanged(int fd) -{ - int type=RFIFOW(fd,16),guild_id=RFIFOL(fd,4); - int account_id=RFIFOL(fd,8),char_id=RFIFOL(fd,12); - void *data=RFIFOP(fd,18); - struct guild *g=guild_search(guild_id); - int idx,dd=*((int *)data); - if( g==NULL ) - return 0; - idx=guild_getindex(g,account_id,char_id); - switch(type){ - case GMI_POSITION: - g->member[idx].position=dd; - guild_memberposition_changed(g,idx,dd); - break; - case GMI_EXP: - g->member[idx].exp=dd; - break; - } - return 0; -} - -// ギルド役職変更通知 -int intif_parse_GuildPosition(int fd) -{ - if( RFIFOW(fd,2)!=sizeof(struct guild_position)+12 ){ - if(battle_config.error_log) - printf("intif: guild info : data size error\n %d %d %d",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild_position)+12); - } - guild_position_changed(RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12)); - return 0; -} -// ギルドスキル割り振り通知 -int intif_parse_GuildSkillUp(int fd) -{ - guild_skillupack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10)); - return 0; -} -// ギルド同盟/敵対通知 -int intif_parse_GuildAlliance(int fd) -{ - guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14), - RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43)); - return 0; -} -// ギルド告知変更通知 -int intif_parse_GuildNotice(int fd) -{ - guild_notice_changed(RFIFOL(fd,2),(char *) RFIFOP(fd,6),(char *) RFIFOP(fd,66)); - return 0; -} -// ギルドエンブレム変更通知 -int intif_parse_GuildEmblem(int fd) -{ - guild_emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8), (char *)RFIFOP(fd,12)); - return 0; -} -// ギルド会話受信 -int intif_parse_GuildMessage(int fd) -{ - guild_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12); - return 0; -} -// ギルド城データ要求返信 -int intif_parse_GuildCastleDataLoad(int fd) -{ - return guild_castledataloadack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); -} -// ギルド城データ変更通知 -int intif_parse_GuildCastleDataSave(int fd) -{ - return guild_castledatasaveack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); -} - -// ギルド城データ一括受信(初期化時) -int intif_parse_GuildCastleAllDataLoad(int fd) -{ - return guild_castlealldataload(RFIFOW(fd,2),(struct guild_castle *)RFIFOP(fd,4)); -} - -// pet -int intif_parse_CreatePet(int fd) -{ - pet_get_egg(RFIFOL(fd,2),RFIFOL(fd,7),RFIFOB(fd,6)); - - return 0; -} - -int intif_parse_RecvPetData(int fd) -{ - struct s_pet p; - int len=RFIFOW(fd,2); - if(sizeof(struct s_pet)!=len-9) { - if(battle_config.etc_log) - printf("intif: pet data: data size error %d %d\n",sizeof(struct s_pet),len-9); - } - else{ - memcpy(&p,RFIFOP(fd,9),sizeof(struct s_pet)); - pet_recv_petdata(RFIFOL(fd,4),&p,RFIFOB(fd,8)); - } - - return 0; -} -int intif_parse_SavePetOk(int fd) -{ - if(RFIFOB(fd,6) == 1) { - if(battle_config.error_log) - printf("pet data save failure\n"); - } - - return 0; -} - -int intif_parse_DeletePetOk(int fd) -{ - if(RFIFOB(fd,2) == 1) { - if(battle_config.error_log) - printf("pet data delete failure\n"); - } - - return 0; -} -//----------------------------------------------------------------- -// inter serverからの通信 -// エラーがあれば0(false)を返すこと -// パケットが処理できれば1,パケット長が足りなければ2を返すこと -int intif_parse(int fd) -{ - int packet_len; - int cmd = RFIFOW(fd,0); - // パケットのID確認 - if(cmd<0x3800 || cmd>=0x3800+(sizeof(packet_len_table)/sizeof(packet_len_table[0])) || - packet_len_table[cmd-0x3800]==0){ - return 0; - } - // パケットの長さ確認 - packet_len = packet_len_table[cmd-0x3800]; - if(packet_len==-1){ - if(RFIFOREST(fd)<4) - return 2; - packet_len = RFIFOW(fd,2); - } -// if(battle_config.etc_log) -// printf("intif_parse %d %x %d %d\n",fd,cmd,packet_len,RFIFOREST(fd)); - if(RFIFOREST(fd)<packet_len){ - return 2; - } - // 処理分岐 - switch(cmd){ - case 0x3800: clif_GMmessage(NULL,(char *) RFIFOP(fd,4),packet_len-4,0); break; - case 0x3801: intif_parse_WisMessage(fd); break; - case 0x3802: intif_parse_WisEnd(fd); break; - case 0x3803: mapif_parse_WisToGM(fd); break; - case 0x3804: intif_parse_AccountReg(fd); break; - case 0x3810: intif_parse_LoadStorage(fd); break; - case 0x3811: intif_parse_SaveStorage(fd); break; - case 0x3818: intif_parse_LoadGuildStorage(fd); break; - case 0x3819: intif_parse_SaveGuildStorage(fd); break; - case 0x3820: intif_parse_PartyCreated(fd); break; - case 0x3821: intif_parse_PartyInfo(fd); break; - case 0x3822: intif_parse_PartyMemberAdded(fd); break; - case 0x3823: intif_parse_PartyOptionChanged(fd); break; - case 0x3824: intif_parse_PartyMemberLeaved(fd); break; - case 0x3825: intif_parse_PartyMove(fd); break; - case 0x3826: intif_parse_PartyBroken(fd); break; - case 0x3827: intif_parse_PartyMessage(fd); break; - case 0x3830: intif_parse_GuildCreated(fd); break; - case 0x3831: intif_parse_GuildInfo(fd); break; - case 0x3832: intif_parse_GuildMemberAdded(fd); break; - case 0x3834: intif_parse_GuildMemberLeaved(fd); break; - case 0x3835: intif_parse_GuildMemberInfoShort(fd); break; - case 0x3836: intif_parse_GuildBroken(fd); break; - case 0x3837: intif_parse_GuildMessage(fd); break; - case 0x3839: intif_parse_GuildBasicInfoChanged(fd); break; - case 0x383a: intif_parse_GuildMemberInfoChanged(fd); break; - case 0x383b: intif_parse_GuildPosition(fd); break; - case 0x383c: intif_parse_GuildSkillUp(fd); break; - case 0x383d: intif_parse_GuildAlliance(fd); break; - case 0x383e: intif_parse_GuildNotice(fd); break; - case 0x383f: intif_parse_GuildEmblem(fd); break; - case 0x3840: intif_parse_GuildCastleDataLoad(fd); break; - case 0x3841: intif_parse_GuildCastleDataSave(fd); break; - case 0x3842: intif_parse_GuildCastleAllDataLoad(fd); break; - case 0x3880: intif_parse_CreatePet(fd); break; - case 0x3881: intif_parse_RecvPetData(fd); break; - case 0x3882: intif_parse_SavePetOk(fd); break; - case 0x3883: intif_parse_DeletePetOk(fd); break; - default: - if(battle_config.error_log) - printf("intif_parse : unknown packet %d %x\n",fd,RFIFOW(fd,0)); - return 0; - } - // パケット読み飛ばし - RFIFOSKIP(fd,packet_len); - return 1; -} diff --git a/src/map/intif.h b/src/map/intif.h deleted file mode 100644 index 17d6045ac..000000000 --- a/src/map/intif.h +++ /dev/null @@ -1,56 +0,0 @@ -// $Id: intif.h,v 1.2 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _INTIF_H_ -#define _INFIF_H_ - -int intif_parse(int fd); - -int intif_GMmessage(char* mes,int len,int flag); - -int intif_wis_message(struct map_session_data *sd,char *nick,char *mes,int mes_len); -int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes); - -int intif_saveaccountreg(struct map_session_data *sd); -int intif_request_accountreg(struct map_session_data *sd); - -int intif_request_storage(int account_id); -int intif_send_storage(struct storage *stor); -int intif_request_guild_storage(int account_id, int guild_id); -int intif_send_guild_storage(int account_id, struct guild_storage *gstor); - - -int intif_create_party(struct map_session_data *sd,char *name,int item,int item2); -int intif_request_partyinfo(int party_id); -int intif_party_addmember(int party_id, int account_id); -int intif_party_changeoption(int party_id, int account_id, int exp, int item); -int intif_party_leave(int party_id, int accound_id); -int intif_party_changemap(struct map_session_data *sd, int online); -int intif_break_party(int party_id); -int intif_party_message(int party_id, int account_id, char *mes,int len); -int intif_party_checkconflict(int party_id, int account_id, char *nick); - - -int intif_guild_create(const char *name, const struct guild_member *master); -int intif_guild_request_info(int guild_id); -int intif_guild_addmember(int guild_id, struct guild_member *m); -int intif_guild_leave(int guild_id, int account_id, int char_id, int flag, const char *mes); -int intif_guild_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int class_); -int intif_guild_break(int guild_id); -int intif_guild_message(int guild_id, int account_id, char *mes, int len); -int intif_guild_checkconflict(int guild_id, int account_id, int char_id); -int intif_guild_change_basicinfo(int guild_id, int type, const void *data, int len); -int intif_guild_change_memberinfo(int guild_id, int account_id, int char_id, int type, const void *data, int len); -int intif_guild_position(int guild_id, int idx, struct guild_position *p); -int intif_guild_skillup(int guild_id, int skill_num, int account_id, int flag); -int intif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag); -int intif_guild_notice(int guild_id, const char *mes1, const char *mes2); -int intif_guild_emblem(int guild_id, int len, const char *data); -int intif_guild_castle_dataload(int castle_id, int index); -int intif_guild_castle_datasave(int castle_id, int index, int value); - -int intif_create_pet(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id, - short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name); -int intif_request_petdata(int account_id, int char_id, int pet_id); -int intif_save_petdata(int account_id, struct s_pet *p); -int intif_delete_petdata(int pet_id); - -#endif diff --git a/src/map/itemdb.c b/src/map/itemdb.c deleted file mode 100644 index 91ec58c81..000000000 --- a/src/map/itemdb.c +++ /dev/null @@ -1,975 +0,0 @@ -// $Id: itemdb.c,v 1.3 2004/09/25 05:32:18 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "db.h" -#include "grfio.h" -#include "nullpo.h" -#include "malloc.h" -#include "map.h" -#include "battle.h" -#include "itemdb.h" -#include "script.h" -#include "pc.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define MAX_RANDITEM 2000 - -// ** ITEMDB_OVERRIDE_NAME_VERBOSE ** -// 定義すると、itemdb.txtとgrfで名前が異なる場合、表示します. -//#define ITEMDB_OVERRIDE_NAME_VERBOSE 1 - -static struct dbt* item_db; - -static struct random_item_data blue_box[MAX_RANDITEM], violet_box[MAX_RANDITEM], card_album[MAX_RANDITEM], gift_box[MAX_RANDITEM], scroll[MAX_RANDITEM], finding_ore[MAX_RANDITEM]; -static int blue_box_count=0, violet_box_count=0, card_album_count=0, gift_box_count=0, scroll_count=0, finding_ore_count = 0; -static int blue_box_default=0, violet_box_default=0, card_album_default=0, gift_box_default=0, scroll_default=0, finding_ore_default = 0; - -// Function declarations - -static void itemdb_read(void); -static int itemdb_readdb(void); -#ifndef TXT_ONLY -static int itemdb_read_sqldb(void); -#endif /* not TXT_ONLY */ -static int itemdb_read_randomitem(); -static int itemdb_read_itemavail(void); -static int itemdb_read_itemnametable(void); -static int itemdb_read_itemslottable(void); -static int itemdb_read_itemslotcounttable(void); -static int itemdb_read_cardillustnametable(void); -static int itemdb_read_noequip(void); -static int itemdb_read_norefine(void); -void itemdb_reload(void); - -/*========================================== - * 名前で検索用 - *------------------------------------------ - */ -// name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) -int itemdb_searchname_sub(void *key,void *data,va_list ap) -{ - struct item_data *item=(struct item_data *)data,**dst; - char *str; - str=va_arg(ap,char *); - dst=va_arg(ap,struct item_data **); -// if( strcmpi(item->name,str)==0 || strcmp(item->jname,str)==0 || -// memcmp(item->name,str,24)==0 || memcmp(item->jname,str,24)==0 ) - if( strcmpi(item->name,str)==0 ) //by lupus - *dst=item; - return 0; -} - -/*========================================== - * 名前で検索用 - *------------------------------------------ - */ -int itemdb_searchjname_sub(void *key,void *data,va_list ap) -{ - struct item_data *item=(struct item_data *)data,**dst; - char *str; - str=va_arg(ap,char *); - dst=va_arg(ap,struct item_data **); - if( strcmpi(item->jname,str)==0 ) - *dst=item; - return 0; -} -/*========================================== - * 名前で検索 - *------------------------------------------ - */ -struct item_data* itemdb_searchname(const char *str) -{ - struct item_data *item=NULL; - numdb_foreach(item_db,itemdb_searchname_sub,str,&item); - return item; -} - -/*========================================== - * 箱系アイテム検索 - *------------------------------------------ - */ -int itemdb_searchrandomid(int flags) -{ - int nameid=0,i,index,count; - struct random_item_data *list=NULL; - - struct { - int nameid,count; - struct random_item_data *list; - } data[7]; - - // for BCC32 compile error - data[0].nameid = 0; data[0].count = 0; data[0].list = NULL; - data[1].nameid = blue_box_default; data[1].count = blue_box_count; data[1].list = blue_box; - data[2].nameid = violet_box_default; data[2].count = violet_box_count; data[2].list = violet_box; - data[3].nameid = card_album_default; data[3].count = card_album_count; data[3].list = card_album; - data[4].nameid = gift_box_default; data[4].count = gift_box_count; data[4].list = gift_box; - data[5].nameid = scroll_default; data[5].count = scroll_count; data[5].list = scroll; - data[6].nameid = finding_ore_default; data[6].count = finding_ore_count; data[6].list = finding_ore; - - if(flags>=1 && flags<=6){ - nameid=data[flags].nameid; - count=data[flags].count; - list=data[flags].list; - - if(count > 0) { - for(i=0;i<1000;i++) { - index = rand()%count; - if( rand()%1000000 < list[index].per) { - nameid = list[index].nameid; - break; - } - } - } - } - return nameid; -} - -/*========================================== - * DBの存在確認 - *------------------------------------------ - */ -struct item_data* itemdb_exists(int nameid) -{ - return (struct item_data *) numdb_search(item_db,nameid); -} -/*========================================== - * DBの検索 - *------------------------------------------ - */ -struct item_data* itemdb_search(int nameid) -{ - struct item_data *id; - - id=(struct item_data *) numdb_search(item_db,nameid); - if(id) return id; - - id=(struct item_data *)aCalloc(1,sizeof(struct item_data)); - numdb_insert(item_db,nameid,id); - - id->nameid=nameid; - id->value_buy=10; - id->value_sell=id->value_buy/2; - id->weight=10; - id->sex=2; - id->elv=0; - id->class_=0xffffffff; - id->flag.available=0; - id->flag.value_notdc=0; //一応・・・ - id->flag.value_notoc=0; - id->flag.no_equip=0; - id->view_id=0; - - if(nameid>500 && nameid<600) - id->type=0; //heal item - else if(nameid>600 && nameid<700) - id->type=2; //use item - else if((nameid>700 && nameid<1100) || - (nameid>7000 && nameid<8000)) - id->type=3; //correction - else if(nameid>=1750 && nameid<1771) - id->type=10; //arrow - else if(nameid>1100 && nameid<2000) - id->type=4; //weapon - else if((nameid>2100 && nameid<3000) || - (nameid>5000 && nameid<6000)) - id->type=5; //armor - else if(nameid>4000 && nameid<5000) - id->type=6; //card - else if(nameid>9000 && nameid<10000) - id->type=7; //egg - else if(nameid>10000) - id->type=8; //petequip - - return id; -} - -/*========================================== - * - *------------------------------------------ - */ -int itemdb_isequip(int nameid) -{ - int type=itemdb_type(nameid); - if(type==0 || type==2 || type==3 || type==6 || type==10) - return 0; - return 1; -} -/*========================================== - * - *------------------------------------------ - */ -int itemdb_isequip2(struct item_data *data) -{ - if(data) { - int type=data->type; - if(type==0 || type==2 || type==3 || type==6 || type==10) - return 0; - else - return 1; - } - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int itemdb_isequip3(int nameid) -{ - int type=itemdb_type(nameid); - if(type==4 || type==5 || type == 8) - return 1; - return 0; -} - -/*========================================== - * 捨てられるアイテムは1、そうでないアイテムは0 - *------------------------------------------ - */ -int itemdb_isdropable(int nameid) -{ - //結婚指輪は捨てられない - switch(nameid){ - case 2634: //結婚指輪 - case 2635: //結婚指輪 - return 0; - } - - return 1; -} - -/*==================================== - * Removed item_value_db, don't re-add - *------------------------------------ - */ -static void itemdb_read(void) -{ - #ifndef TXT_ONLY - if (db_use_sqldbs) - { - itemdb_read_sqldb(); - } - else - { - itemdb_readdb(); - } - /* not TXT_ONLY */ - #else - itemdb_readdb(); - #endif /* TXT_ONLY */ - - itemdb_read_randomitem(); - itemdb_read_itemavail(); - itemdb_read_noequip(); - itemdb_read_norefine(); - if (battle_config.cardillust_read_grffile) - itemdb_read_cardillustnametable(); - if (battle_config.item_equip_override_grffile) - itemdb_read_itemslottable(); - if (battle_config.item_slots_override_grffile) - itemdb_read_itemslotcounttable(); - if (battle_config.item_name_override_grffile) - itemdb_read_itemnametable(); -} - -/*========================================== - * アイテムデータベースの読み込み - *------------------------------------------ - */ -static int itemdb_readdb(void) -{ - FILE *fp; - char line[1024]; - int ln=0,lines=0; - int nameid,j; - char *str[32],*p,*np; - struct item_data *id; - int i=0; - char *filename[]={ "db/item_db.txt","db/item_db2.txt" }; - - for(i=0;i<2;i++){ - - fp=fopen(filename[i],"r"); - if(fp==NULL){ - if(i>0) - continue; - printf("can't read %s\n",filename[i]); - exit(1); - } - - lines=0; - while(fgets(line,1020,fp)){ - lines++; - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - for(j=0,np=p=line;j<17 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p){ *p++=0; np=p; } - } - if(str[0]==NULL) - continue; - - nameid=atoi(str[0]); - if(nameid<=0 || nameid>=20000) - continue; - ln++; - - //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Gender,Loc,wLV,eLV,View - id=itemdb_search(nameid); - memcpy(id->name,str[1],24); - memcpy(id->jname,str[2],24); - id->type=atoi(str[3]); - - { - int buy = atoi(str[4]), sell = atoi(str[5]); - // if buying price > selling price * 2 consider it valid and don't change it [celest] - if (buy && sell && buy > sell*2){ - id->value_buy = buy; - id->value_sell = sell; - } else { - // buy≠sell*2 は item_value_db.txt で指定してください。 - if (sell) { // sell値を優先とする - id->value_buy = sell*2; - id->value_sell = sell; - } else { - id->value_buy = buy; - id->value_sell = buy/2; - } - } - // check for bad prices that can possibly cause exploits - if (id->value_buy*75/100 < id->value_sell*124/100) { - sprintf (tmp_output, "Item %s [%d] buying:%d < selling:%d\n", - id->name, id->nameid, id->value_buy*75/100, id->value_sell*124/100); - ShowWarning (tmp_output); - } - } - id->weight=atoi(str[6]); - id->atk=atoi(str[7]); - id->def=atoi(str[8]); - id->range=atoi(str[9]); - id->slot=atoi(str[10]); - id->class_=atoi(str[11]); - id->sex=atoi(str[12]); - if(id->equip != atoi(str[13])){ - id->equip=atoi(str[13]); - } - id->wlv=atoi(str[14]); - id->elv=atoi(str[15]); - id->look=atoi(str[16]); - id->flag.available=1; - id->flag.value_notdc=0; - id->flag.value_notoc=0; - id->view_id=0; - - id->use_script=NULL; - id->equip_script=NULL; - - if((p=strchr(np,'{'))==NULL) - continue; - id->use_script = parse_script((unsigned char *) p,lines); - if((p=strchr(p+1,'{'))==NULL) - continue; - id->equip_script = parse_script((unsigned char *) p,lines); - } - fclose(fp); - if (ln > 0) { - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]); - ShowStatus(tmp_output); - } - ln=0; // reset to 0 - } - return 0; -} - -// Removed item_value_db, don't re-add! - -/*========================================== - * ランダムアイテム出現データの読み込み - *------------------------------------------ - */ -static int itemdb_read_randomitem() -{ - FILE *fp; - char line[1024]; - int ln=0; - int nameid,i,j; - char *str[10],*p; - - const struct { - char filename[64]; - struct random_item_data *pdata; - int *pcount,*pdefault; - } data[] = { - {"db/item_bluebox.txt", blue_box, &blue_box_count, &blue_box_default }, - {"db/item_violetbox.txt", violet_box, &violet_box_count, &violet_box_default }, - {"db/item_cardalbum.txt", card_album, &card_album_count, &card_album_default }, - {"db/item_giftbox.txt", gift_box, &gift_box_count, &gift_box_default }, - {"db/item_scroll.txt", scroll, &scroll_count, &scroll_default }, - {"db/item_findingore.txt", finding_ore,&finding_ore_count, &finding_ore_default }, - }; - - for(i=0;i<sizeof(data)/sizeof(data[0]);i++){ - struct random_item_data *pd=data[i].pdata; - int *pc=data[i].pcount; - int *pdefault=data[i].pdefault; - char *fn=(char *) data[i].filename; - - *pdefault = 0; - if( (fp=fopen(fn,"r"))==NULL ){ - printf("can't read %s\n",fn); - continue; - } - - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - for(j=0,p=line;j<3 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - - if(str[0]==NULL) - continue; - - nameid=atoi(str[0]); - if(nameid<0 || nameid>=20000) - continue; - if(nameid == 0) { - if(str[2]) - *pdefault = atoi(str[2]); - continue; - } - - if(str[2]){ - pd[ *pc ].nameid = nameid; - pd[(*pc)++].per = atoi(str[2]); - } - - if(ln >= MAX_RANDITEM) - break; - ln++; - } - fclose(fp); - if (*pc > 0) { - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",*pc,fn); - ShowStatus(tmp_output); - } - } - - return 0; -} -/*========================================== - * アイテム使用可能フラグのオーバーライド - *------------------------------------------ - */ -static int itemdb_read_itemavail(void) -{ - FILE *fp; - char line[1024]; - int ln=0; - int nameid,j,k; - char *str[10],*p; - - if( (fp=fopen("db/item_avail.txt","r"))==NULL ){ - printf("can't read db/item_avail.txt\n"); - return -1; - } - - while(fgets(line,1020,fp)){ - struct item_data *id; - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - for(j=0,p=line;j<2 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - - if(str[0]==NULL) - continue; - - nameid=atoi(str[0]); - if(nameid<0 || nameid>=20000 || !(id=itemdb_exists(nameid)) ) - continue; - k=atoi(str[1]); - if(k > 0) { - id->flag.available = 1; - id->view_id = k; - } - else - id->flag.available = 0; - ln++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/item_avail.txt"); - ShowStatus(tmp_output); - return 0; -} - -/*========================================== - * アイテムの名前テーブルを読み込む - *------------------------------------------ - */ -static int itemdb_read_itemnametable(void) -{ - char *buf,*p; - int s; - - buf=(char *) grfio_reads("data\\idnum2itemdisplaynametable.txt",&s); - - if(buf==NULL) - return -1; - - buf[s]=0; - for(p=buf;p-buf<s;){ - int nameid; - char buf2[64]; - - if( sscanf(p,"%d#%[^#]#",&nameid,buf2)==2 ){ - -#ifdef ITEMDB_OVERRIDE_NAME_VERBOSE - if( itemdb_exists(nameid) && - strncmp(itemdb_search(nameid)->jname,buf2,24)!=0 ){ - printf("[override] %d %s => %s\n",nameid - ,itemdb_search(nameid)->jname,buf2); - } -#endif - - memcpy(itemdb_search(nameid)->jname,buf2,24); - } - - p=strchr(p,10); - if(!p) break; - p++; - } - aFree(buf); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\idnum2itemdisplaynametable.txt"); - ShowStatus(tmp_output); - - return 0; -} - -/*========================================== - * カードイラストのリソース名前テーブルを読み込む - *------------------------------------------ - */ -static int itemdb_read_cardillustnametable(void) -{ - char *buf,*p; - int s; - - buf=(char *) grfio_reads("data\\num2cardillustnametable.txt",&s); - - if(buf==NULL) - return -1; - - buf[s]=0; - for(p=buf;p-buf<s;){ - int nameid; - char buf2[64]; - - if( sscanf(p,"%d#%[^#]#",&nameid,buf2)==2 ){ - strcat(buf2,".bmp"); - memcpy(itemdb_search(nameid)->cardillustname,buf2,64); -// printf("%d %s\n",nameid,itemdb_search(nameid)->cardillustname); - } - - p=strchr(p,10); - if(!p) break; - p++; - } - aFree(buf); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\num2cardillustnametable.txt"); - ShowStatus(tmp_output); - - return 0; -} - -// -// 初期化 -// -/*========================================== - * - *------------------------------------------ - */ -static int itemdb_read_itemslottable(void) -{ - char *buf,*p; - int s; - - buf=(char *) grfio_read("data\\itemslottable.txt"); - if(buf==NULL) - return -1; - s=grfio_size("data\\itemslottable.txt"); - buf[s]=0; - for(p=buf;p-buf<s;){ - int nameid,equip; - struct item_data* item; - sscanf(p,"%d#%d#",&nameid,&equip); - item = itemdb_search(nameid); - if (item && itemdb_isequip2(item)) - item->equip=equip; - p=strchr(p,10); - if(!p) break; - p++; - p=strchr(p,10); - if(!p) break; - p++; - } - aFree(buf); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslottable.txt"); - ShowStatus(tmp_output); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static int itemdb_read_itemslotcounttable(void) -{ - char *buf,*p; - int s; - - buf=(char *) grfio_read("data\\itemslotcounttable.txt"); - if(buf==NULL) - return -1; - s=grfio_size("data\\itemslotcounttable.txt"); - buf[s]=0; - for(p=buf;p-buf<s;){ - int nameid,slot; - sscanf(p,"%d#%d#",&nameid,&slot); - itemdb_search(nameid)->slot=slot; - p=strchr(p,10); - if(!p) break; - p++; - p=strchr(p,10); - if(!p) break; - p++; - } - aFree(buf); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslotcounttable.txt"); - ShowStatus(tmp_output); - - return 0; -} - -/*========================================== - * 装備制限ファイル読み出し - *------------------------------------------ - */ -static int itemdb_read_noequip(void) -{ - FILE *fp; - char line[1024]; - int ln=0; - int nameid,j; - char *str[32],*p; - struct item_data *id; - - if( (fp=fopen("db/item_noequip.txt","r"))==NULL ){ - printf("can't read db/item_noequip.txt\n"); - return -1; - } - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - for(j=0,p=line;j<2 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if(str[0]==NULL) - continue; - - nameid=atoi(str[0]); - if(nameid<=0 || nameid>=20000 || !(id=itemdb_exists(nameid))) - continue; - - id->flag.no_equip=atoi(str[1]); - - ln++; - - } - fclose(fp); - if (ln > 0) { - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/item_noequip.txt"); - ShowStatus(tmp_output); - } - return 0; -} - -/*================================================ - * Whether the item can be refined or not [Celest] - *------------------------------------------------ - */ -static int itemdb_read_norefine(void) -{ - int i, nameid; - struct item_data *id; - // To-do: let it read from a text file later - int cant_refine[] = { - 1243, 1530, 2110, 2112, 2201, 2202, 2203, 2204, 2205, 2210, - 2212, 2218, 2219, 2237, 2238, 2239, 2240, 2241, 2242, 2243, - 2250, 2253, 2260, 2262, 2263, 2264, 2265, 2266, 2267, 2268, - 2269, 2270, 2271, 2276, 2278, 2279, 2281, 2282, 2286, 2288, - 2289, 2290, 2291, 2292, 2293, 2295, 2296, 2297, 2298, 2352, - 2410, 2413, 2414, 2509, 2510, 2601, 2602, 2603, 2604, 2605, - 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, - 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, - 2627, 2628, 2629, 2630, 2631, 2634, 2635, 2636, 2637, 2638, - 2639, 2640, 5004, 5005, 5006, 5008, 5014, 5015, 5037, 5039, - 5040, 5043, 5046, 5049, 5050, 5051, 5053, 5054, 5055, 5058, - 5068, 5074, 5085, 5086, 5087, 5088, 5089, 5090, 5096, 5098, 0 - }; - - for (i=0; i < (int)(sizeof(cant_refine) / sizeof(cant_refine[0])); i++) { - nameid = cant_refine[i]; - if(nameid<=0 || nameid>=20000 || !(id=itemdb_exists(nameid))) - continue; - id->flag.no_refine = 1; - } - - return 1; -} - -#ifndef TXT_ONLY - -/*====================================== -* SQL -*=================================== -*/ -static int itemdb_read_sqldb(void) -{ - unsigned short nameid; - struct item_data *id; - char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator - - // ---------- - - sprintf(tmp_sql, "SELECT * FROM `%s`", item_db_db); - - // Execute the query; if the query execution succeeded... - if (mysql_query(&mmysql_handle, tmp_sql) == 0) - { - sql_res = mysql_store_result(&mmysql_handle); - - // If the storage of the query result succeeded... - if (sql_res) - { - // Parse each row in the query result into sql_row - while ((sql_row = mysql_fetch_row(sql_res))) - { - /* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | - +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ - | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_genders | equip_locations | weapon_level | equip_level | view | script_use | script_equip | - +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ */ - - nameid = atoi(sql_row[0]); - - // If the identifier is not within the valid range, process the next row - if (nameid == 0 || nameid >= 20000) - { - continue; - } - - // Insert a new row into the item database - - /*id = aCalloc(sizeof(struct item_data), 1); - - if (id == NULL) - { - printf("out of memory : itemdb_read_sqldb\n"); - exit(1); - } - - memset(id, 0, sizeof(struct item_data)); - numdb_insert(item_db, (int) nameid, id);*/ - - // ---------- - id=itemdb_search(nameid); - - memcpy(id->name, sql_row[1], 25); - memcpy(id->jname, sql_row[2], 25); - - id->type = atoi(sql_row[3]); - - // If price_buy is not NULL and price_sell is not NULL... - if ((sql_row[4] != NULL) && (sql_row[5] != NULL)) - { - id->value_buy = atoi(sql_row[4]); - id->value_sell = atoi(sql_row[5]); - } - // If price_buy is not NULL and price_sell is NULL... - else if ((sql_row[4] != NULL) && (sql_row[5] == NULL)) - { - id->value_buy = atoi(sql_row[4]); - id->value_sell = atoi(sql_row[4]) / 2; - } - // If price_buy is NULL and price_sell is not NULL... - else if ((sql_row[4] == NULL) && (sql_row[5] != NULL)) - { - id->value_buy = atoi(sql_row[5]) * 2; - id->value_sell = atoi(sql_row[5]); - } - // If price_buy is NULL and price_sell is NULL... - if ((sql_row[4] == NULL) && (sql_row[5] == NULL)) - { - id->value_buy = 0; - id->value_sell = 0; - } - - id->weight = atoi(sql_row[6]); - - id->atk = (sql_row[7] != NULL) ? atoi(sql_row[7]) : 0; - id->def = (sql_row[8] != NULL) ? atoi(sql_row[8]) : 0; - id->range = (sql_row[9] != NULL) ? atoi(sql_row[9]) : 0; - id->slot = (sql_row[10] != NULL) ? atoi(sql_row[10]) : 0; - id->class_ = (sql_row[11] != NULL) ? atoi(sql_row[11]) : 0; - id->sex = (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0; - id->equip = (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0; - id->wlv = (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0; - id->elv = (sql_row[15] != NULL) ? atoi(sql_row[15]) : 0; - id->look = (sql_row[16] != NULL) ? atoi(sql_row[16]) : 0; - - id->view_id = 0; - - // ---------- - - if (sql_row[17] != NULL) - { - if (sql_row[17][0] == '{') - id->use_script = parse_script((unsigned char *) sql_row[17], 0); - else { - sprintf(script, "{%s}", sql_row[17]); - id->use_script = parse_script((unsigned char *) script, 0); - } - } - else - { - id->use_script = NULL; - } - - if (sql_row[18] != NULL) - { - if (sql_row[18][0] == '{') - id->equip_script = parse_script((unsigned char *) sql_row[18], 0); - else { - sprintf(script, "{%s}", sql_row[18]); - id->equip_script = parse_script((unsigned char *) script, 0); - } - } - else - { - id->equip_script = NULL; - } - - // ---------- - - id->flag.available = 1; - id->flag.value_notdc = 0; - id->flag.value_notoc = 0; - } - - // If the retrieval failed, output an error - if (mysql_errno(&mmysql_handle)) - { - printf("Database server error (retrieving rows from %s): %s\n", item_db_db, mysql_error(&mmysql_handle)); - } - sprintf(tmp_output,"Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",(unsigned long) mysql_num_rows(sql_res),item_db_db); - ShowStatus(tmp_output); - } - else - { - printf("MySQL error (storing query result for %s): %s\n", item_db_db, mysql_error(&mmysql_handle)); - } - - // Free the query result - mysql_free_result(sql_res); - } - else - { - printf("Database server error (executing query for %s): %s\n", item_db_db, mysql_error(&mmysql_handle)); - } - - return 0; -} - -#endif /* not TXT_ONLY */ -/*========================================== - * - *------------------------------------------ - */ -static int itemdb_final(void *key,void *data,va_list ap) -{ - struct item_data *id; - - nullpo_retr(0, id= (struct item_data *) data); - - if(id->use_script) - aFree(id->use_script); - if(id->equip_script) - aFree(id->equip_script); - aFree(id); - - return 0; -} - -void itemdb_reload(void) -{ - numdb_final(item_db,itemdb_final); - do_init_itemdb(); -} - -/*========================================== - * - *------------------------------------------ - */ -void do_final_itemdb(void) -{ - if(item_db){ - numdb_final(item_db,itemdb_final); - item_db=NULL; - } -} - -/* -static FILE *dfp; -static int itemdebug(void *key,void *data,va_list ap){ -// struct item_data *id=(struct item_data *)data; - fprintf(dfp,"%6d",(int)key); - return 0; -} -void itemdebugtxt() -{ - dfp=fopen("itemdebug.txt","wt"); - numdb_foreach(item_db,itemdebug); - fclose(dfp); -} -*/ -/*========================================== - * - *------------------------------------------ - */ -int do_init_itemdb(void) -{ - item_db = numdb_init(); - - itemdb_read(); - - return 0; -} diff --git a/src/map/itemdb.h b/src/map/itemdb.h deleted file mode 100644 index 2ba6ae7f6..000000000 --- a/src/map/itemdb.h +++ /dev/null @@ -1,85 +0,0 @@ -// $Id: itemdb.h,v 1.3 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _ITEMDB_H_ -#define _ITEMDB_H_ - -#include "map.h" - -struct item_data { - int nameid; - char name[24],jname[24]; - char prefix[24],suffix[24]; - char cardillustname[64]; - int value_buy; - int value_sell; - int type; - int class_; - int sex; - int equip; - int weight; - int atk; - int def; - int range; - int slot; - int look; - int elv; - int wlv; - int refine; - char *use_script; // 回復とかも全部この中でやろうかなと - char *equip_script; // 攻撃,防御の属性設定もこの中で可能かな? - struct { - unsigned available : 1; - unsigned value_notdc : 1; - unsigned value_notoc : 1; - unsigned no_equip : 3; - unsigned no_drop : 1; - unsigned no_use : 1; - unsigned no_refine : 1; // [celest] - } flag; - int view_id; -}; - -struct random_item_data { - int nameid; - int per; -}; - -struct item_data* itemdb_searchname(const char *name); -struct item_data* itemdb_search(int nameid); -struct item_data* itemdb_exists(int nameid); -#define itemdb_type(n) itemdb_search(n)->type -#define itemdb_atk(n) itemdb_search(n)->atk -#define itemdb_def(n) itemdb_search(n)->def -#define itemdb_look(n) itemdb_search(n)->look -#define itemdb_weight(n) itemdb_search(n)->weight -#define itemdb_equip(n) itemdb_search(n)->equip -#define itemdb_usescript(n) itemdb_search(n)->use_script -#define itemdb_equipscript(n) itemdb_search(n)->equip_script -#define itemdb_wlv(n) itemdb_search(n)->wlv -#define itemdb_range(n) itemdb_search(n)->range -#define itemdb_slot(n) itemdb_search(n)->slot -#define itemdb_available(n) (itemdb_exists(n) && itemdb_search(n)->flag.available) -#define itemdb_viewid(n) (itemdb_search(n)->view_id) - -int itemdb_searchrandomid(int flags); - -#define itemdb_value_buy(n) itemdb_search(n)->value_buy -#define itemdb_value_sell(n) itemdb_search(n)->value_sell -#define itemdb_value_notdc(n) itemdb_search(n)->flag.value_notdc -#define itemdb_value_notoc(n) itemdb_search(n)->flag.value_notoc - -int itemdb_isequip(int); -int itemdb_isequip2(struct item_data *); -int itemdb_isequip3(int); -int itemdb_isdropable(int nameid); - -// itemdb_equipマクロとitemdb_equippointとの違いは -// 前者が鯖側dbで定義された値そのものを返すのに対し -// 後者はsessiondataを考慮した鞍側での装備可能場所 -// すべての組み合わせを返す - -void itemdb_reload(void); - -void do_final_itemdb(void); -int do_init_itemdb(void); - -#endif diff --git a/src/map/log.c b/src/map/log.c deleted file mode 100644 index 7cf4dfcf4..000000000 --- a/src/map/log.c +++ /dev/null @@ -1,687 +0,0 @@ -// Logging functions by Azndragon & Codemaster -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "../common/strlib.h" -#include "../common/nullpo.h" -#include "itemdb.h" -#include "map.h" -#include "log.h" - -struct Log_Config log_config; - -char timestring[255]; -time_t curtime; - -//FILTER OPTIONS -//0 = Don't log -//1 = Log any item -//Bits: || -//2 - Healing items (0) -//3 - Etc Items(3) + Arrows (10) -//4 - Usable Items(2) -//5 - Weapon(4) -//6 - Shields,Armor,Headgears,Accessories,etc(5) -//7 - Cards(6) -//8 - Pet Accessories(8) + Eggs(7) (well, monsters don't drop 'em but we'll use the same system for ALL logs) -//9 - Log expensive items ( >= price_log) -//10 - Log big amount of items ( >= amount_log) -//11 - Log refined items (if their refine >= refine_log ) -//12 - Log rare items (if their drop chance <= rare_log ) - -//check if this item should be logger according the settings -int should_log_item(int filter, int nameid) { - struct item_data *item_data; - if (nameid<512 || (item_data= itemdb_search(nameid)) == NULL) return 0; - if ( (filter&1) || // Filter = 1, we log any item - (filter&2 && item_data->type == 0 ) || //healing items - (filter&4 && (item_data->type == 3 || item_data->type == 10) ) || //etc+arrows - (filter&8 && item_data->type == 2 ) || //usable - (filter&16 && item_data->type == 4 ) || //weapon - (filter&32 && item_data->type == 5 ) || //armor - (filter&64 && item_data->type == 6 ) || //cards - (filter&128 && (item_data->type == 7 || item_data->type == 8) ) || //eggs+pet access - (filter&256 && item_data->value_buy >= log_config.price_items_log ) || - (filter&512 && item_data->refine >= log_config.refine_items_log ) - ) return item_data->nameid; - - return 0; -} - -int log_branch(struct map_session_data *sd) -{ -#ifndef TXT_ONLY - char t_name[100]; -#endif - FILE *logfp; - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')", - log_config.log_branch_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->mapname); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_branch,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%s%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, sd->mapname, RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_drop(struct map_session_data *sd, int monster_id, int *log_drop) -{ - FILE *logfp; - int i,flag = 0; - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); - for (i = 0; i<10; i++) { //Should we log these items? [Lupus] - flag += should_log_item(log_config.drop,log_drop[i]); - } - if (flag==0) return 0; //we skip logging this items set - they doesn't met our logging conditions [Lupus] - -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`drop_date`, `kill_char_id`, `monster_id`, `item1`, `item2`, `item3`, `item4`, `item5`, `item6`, `item7`, `item8`, `item9`, `itemCard`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s') ", log_config.log_drop_db, sd->status.char_id, monster_id, log_drop[0], log_drop[1], log_drop[2], log_drop[3], log_drop[4], log_drop[5], log_drop[6], log_drop[7], log_drop[8], log_drop[9], sd->mapname); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_drop,"a+")) != NULL) { - - - time_t curtime; - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_drop[0], log_drop[1], log_drop[2], log_drop[3], log_drop[4], log_drop[5], log_drop[6], log_drop[7], log_drop[8], log_drop[9], RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 1; //Logged -} - -int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp) -{ - FILE *logfp; - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ", log_config.log_mvpdrop_db, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], sd->mapname); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_mvpdrop,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_present(struct map_session_data *sd, int source_type, int nameid) -{ - FILE *logfp; -#ifndef TXT_ONLY - char t_name[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); - if(!should_log_item(log_config.present,nameid)) return 0; //filter [Lupus] -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`present_date`, `src_id`, `account_id`, `char_id`, `char_name`, `nameid`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%s', '%d', '%s') ", - log_config.log_present_db, source_type, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), nameid, sd->mapname); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_present,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, source_type, nameid, RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_produce(struct map_session_data *sd, int nameid, int slot1, int slot2, int slot3, int success) -{ - FILE *logfp; -#ifndef TXT_ONLY - char t_name[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); - if(!should_log_item(log_config.produce,nameid)) return 0; //filter [Lupus] -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`produce_date`, `account_id`, `char_id`, `char_name`, `nameid`, `slot1`, `slot2`, `slot3`, `map`, `success`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%s', '%d') ", - log_config.log_produce_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), nameid, slot1, slot2, slot3, sd->mapname, success); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_produce,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d,%d\t%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, nameid, slot1, slot2, slot3, success, RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_refine(struct map_session_data *sd, int n, int success) -{ - FILE *logfp; - int log_card[4]; - int item_level; - int i; -#ifndef TXT_ONLY - char t_name[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - - nullpo_retr(0, sd); - - if(success == 0) - item_level = 0; - else - item_level = sd->status.inventory[n].refine + 1; - if(!should_log_item(log_config.refine,sd->status.inventory[n].nameid)) return 0; //filter [Lupus] - for(i=0;i<4;i++) - log_card[i] = sd->status.inventory[n].card[i]; - -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`refine_date`, `account_id`, `char_id`, `char_name`, `nameid`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `success`, `item_level`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%d', '%d')", - log_config.log_refine_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->status.inventory[n].nameid, sd->status.inventory[n].refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname, success, item_level); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_refine,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%d,%d\t%d%d%d%d\t%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, sd->status.inventory[n].nameid, sd->status.inventory[n].refine, log_card[0], log_card[1], log_card[2], log_card[3], success, item_level, RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_tostorage(struct map_session_data *sd,int n, int guild) -{ - FILE *logfp; - - if(log_config.enable_logs <= 0 || log_config.storage == 0 || log_config.log_storage[0] == '\0') - return 0; - - nullpo_retr(0, sd); - if(sd->status.inventory[n].nameid==0 || sd->inventory_data[n] == NULL) - return 1; - - if(sd->status.inventory[n].amount < 0) - return 1; - - if((logfp=fopen(log_config.log_trade,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - to %s: %s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d%s", timestring, guild ? "guild_storage": "storage", sd->status.name, sd->status.account_id, sd->status.char_id, - sd->status.inventory[n].nameid, - sd->status.inventory[n].amount, - sd->status.inventory[n].refine, - sd->status.inventory[n].card[0], - sd->status.inventory[n].card[1], - sd->status.inventory[n].card[2], - sd->status.inventory[n].card[3], RETCODE); - fclose(logfp); - } - return 0; -} - -int log_fromstorage(struct map_session_data *sd,int n, int guild) -{ - FILE *logfp; - - if(log_config.enable_logs <= 0 || log_config.storage == 0 || log_config.log_storage[0] == '\0') - return 0; - - nullpo_retr(0, sd); - - if(sd->status.inventory[n].nameid==0 || sd->inventory_data[n] == NULL) - return 1; - - if(sd->status.inventory[n].amount < 0) - return 1; - - if((logfp=fopen(log_config.log_trade,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - from %s: %s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d%s", timestring, guild ? "guild_storage": "storage", sd->status.name, sd->status.account_id, sd->status.char_id, - sd->status.inventory[n].nameid, - sd->status.inventory[n].amount, - sd->status.inventory[n].refine, - sd->status.inventory[n].card[0], - sd->status.inventory[n].card[1], - sd->status.inventory[n].card[2], - sd->status.inventory[n].card[3], RETCODE); - fclose(logfp); - } - return 0; -} - -int log_trade(struct map_session_data *sd, struct map_session_data *target_sd, int n,int amount) -{ - FILE *logfp; - int log_nameid, log_amount, log_refine, log_card[4]; - int i; -#ifndef TXT_ONLY - char t_name[100],t_name2[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - - nullpo_retr(0, sd); - - if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL) - return 1; - - if(sd->status.inventory[n].amount < 0) - return 1; - if(!should_log_item(log_config.trade,sd->status.inventory[n].nameid)) return 0; //filter [Lupus] - log_nameid = sd->status.inventory[n].nameid; - log_amount = sd->status.inventory[n].amount; - log_refine = sd->status.inventory[n].refine; - - for(i=0;i<4;i++) - log_card[i] = sd->status.inventory[n].card[i]; - -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`trade_date`, `src_account_id`, `src_char_id`, `src_char_name`, `des_account_id`, `des_char_id`, `des_char_name`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')", - log_config.log_trade_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), target_sd->status.account_id, target_sd->status.char_id, jstrescapecpy(t_name2, target_sd->status.name), log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_trade,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, target_sd->status.name, target_sd->status.account_id, target_sd->status.char_id, log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_vend(struct map_session_data *sd,struct map_session_data *vsd,int n,int amount, int zeny) -{ - FILE *logfp; - int log_nameid, log_amount, log_refine, log_card[4]; - int i; -#ifndef TXT_ONLY - char t_name[100],t_name2[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); - - if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL) - return 1; - if(sd->status.inventory[n].amount< 0) - return 1; - if(!should_log_item(log_config.vend,sd->status.inventory[n].nameid)) return 0; //filter [Lupus] - log_nameid = sd->status.inventory[n].nameid; - log_amount = sd->status.inventory[n].amount; - log_refine = sd->status.inventory[n].refine; - for(i=0;i<4;i++) - log_card[i] = sd->status.inventory[n].card[i]; - -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`vend_date`, `vend_account_id`, `vend_char_id`, `vend_char_name`, `buy_account_id`, `buy_char_id`, `buy_char_name`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `zeny`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%d')", - log_config.log_vend_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), vsd->status.account_id, vsd->status.char_id, jstrescapecpy(t_name2, vsd->status.name), log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname, zeny); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_vend,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d:%d]\t%s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d\t%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, vsd->status.name, vsd->status.account_id, vsd->status.char_id, log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], zeny, RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_zeny(struct map_session_data *sd, struct map_session_data *target_sd,int amount) -{ - FILE *logfp; -#ifndef TXT_ONLY - char t_name[100],t_name2[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql,"INSERT DELAYED INTO `%s` (`trade_date`, `src_account_id`, `src_char_id`, `src_char_name`, `des_account_id`, `des_char_id`, `des_char_name`, `map`, `zeny`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%s', '%d')", - log_config.log_trade_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), target_sd->status.account_id, target_sd->status.char_id, jstrescapecpy(t_name2, target_sd->status.name), sd->mapname, sd->deal_zeny); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_trade,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d]\t%s[%d]\t%d\t%s", timestring, sd->status.name, sd->status.account_id, target_sd->status.name, target_sd->status.account_id, sd->deal_zeny, RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_atcommand(struct map_session_data *sd, const char *message) -{ - FILE *logfp; -#ifndef TXT_ONLY - char t_name[100]; -#endif - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ", - log_config.log_gm_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->mapname, message); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_gm,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d]: %s%s",timestring,sd->status.name,sd->status.account_id,message,RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_npc(struct map_session_data *sd, const char *message) -{ //[Lupus] - FILE *logfp; - #ifndef TXT_ONLY - char t_name[100]; - #endif - - if(log_config.enable_logs <= 0) - return 0; - nullpo_retr(0, sd); -#ifndef TXT_ONLY - if(log_config.sql_logs > 0) - { - sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ", - log_config.log_npc_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->mapname, message); - if(mysql_query(&mmysql_handle, tmp_sql)) - printf("DB server Error - %s\n",mysql_error(&mmysql_handle)); - } else { -#endif - if((logfp=fopen(log_config.log_npc,"a+")) != NULL) { - time(&curtime); - strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); - fprintf(logfp,"%s - %s[%d]: %s%s",timestring,sd->status.name,sd->status.account_id,message,RETCODE); - fclose(logfp); - } -#ifndef TXT_ONLY - } -#endif - return 0; -} - -int log_config_read(char *cfgName) -{ - char line[1024], w1[1024], w2[1024]; - FILE *fp; - - memset(&log_config, 0, sizeof(log_config)); - - if((fp = fopen(cfgName, "r")) == NULL) - { - printf("Log configuration file not found at: %s\n", cfgName); - return 1; - } - - //LOG FILTER Default values - log_config.refine_items_log = 7; //log refined items, with refine >= +7 - log_config.rare_items_log = 100; //log rare items. drop chance <= 1% - log_config.price_items_log = 1000; //1000z - log_config.amount_items_log = 100; - - while(fgets(line, sizeof(line) -1, fp)) - { - if(line[0] == '/' && line[1] == '/') - continue; - - if(sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) - { - if(strcmpi(w1,"enable_logs") == 0) { - log_config.enable_logs = (atoi(w2)); - } else if(strcmpi(w1,"sql_logs") == 0) { - log_config.sql_logs = (atoi(w2)); -//start of common filter settings - } else if(strcmpi(w1,"rare_items_log") == 0) { - log_config.rare_items_log = (atoi(w2)); - } else if(strcmpi(w1,"refine_items_log") == 0) { - log_config.refine_items_log = (atoi(w2)); - } else if(strcmpi(w1,"price_items_log") == 0) { - log_config.price_items_log = (atoi(w2)); - } else if(strcmpi(w1,"amount_items_log") == 0) { - log_config.amount_items_log = (atoi(w2)); -//end of common filter settings - } else if(strcmpi(w1,"log_branch") == 0) { - log_config.branch = (atoi(w2)); - } else if(strcmpi(w1,"log_drop") == 0) { - log_config.drop = (atoi(w2)); - } else if(strcmpi(w1,"log_mvpdrop") == 0) { - log_config.mvpdrop = (atoi(w2)); - } else if(strcmpi(w1,"log_present") == 0) { - log_config.present = (atoi(w2)); - } else if(strcmpi(w1,"log_produce") == 0) { - log_config.produce = (atoi(w2)); - } else if(strcmpi(w1,"log_refine") == 0) { - log_config.refine = (atoi(w2)); - } else if(strcmpi(w1,"log_trade") == 0) { - log_config.trade = (atoi(w2)); - } else if(strcmpi(w1,"log_storage") == 0) { - log_config.storage = (atoi(w2)); - } else if(strcmpi(w1,"log_vend") == 0) { - log_config.vend = (atoi(w2)); - } else if(strcmpi(w1,"log_zeny") == 0) { - if(log_config.trade != 1) - log_config.zeny = 0; - else - log_config.zeny = (atoi(w2)); - } else if(strcmpi(w1,"log_gm") == 0) { - log_config.gm = (atoi(w2)); - } else if(strcmpi(w1,"log_npc") == 0) { - log_config.npc = (atoi(w2)); - } - -#ifndef TXT_ONLY - else if(strcmpi(w1, "log_branch_db") == 0) { - strcpy(log_config.log_branch_db, w2); - if(log_config.branch == 1) - printf("Logging Dead Branch Usage to table `%s`\n", w2); - } else if(strcmpi(w1, "log_drop_db") == 0) { - strcpy(log_config.log_drop_db, w2); - if(log_config.drop == 1) - printf("Logging Item Drops to table `%s`\n", w2); - } else if(strcmpi(w1, "log_mvpdrop_db") == 0) { - strcpy(log_config.log_mvpdrop_db, w2); - if(log_config.mvpdrop == 1) - printf("Logging MVP Drops to table `%s`\n", w2); - } else if(strcmpi(w1, "log_present_db") == 0) { - strcpy(log_config.log_present_db, w2); - if(log_config.present == 1) - printf("Logging Present Usage & Results to table `%s`\n", w2); - } else if(strcmpi(w1, "log_produce_db") == 0) { - strcpy(log_config.log_produce_db, w2); - if(log_config.produce == 1) - printf("Logging Producing to table `%s`\n", w2); - } else if(strcmpi(w1, "log_refine_db") == 0) { - strcpy(log_config.log_refine_db, w2); - if(log_config.refine == 1) - printf("Logging Refining to table `%s`\n", w2); - } else if(strcmpi(w1, "log_trade_db") == 0) { - strcpy(log_config.log_trade_db, w2); - if(log_config.trade == 1) - { - printf("Logging Item Trades"); - if(log_config.zeny == 1) - printf("and Zeny Trades"); - printf(" to table `%s`\n", w2); - } -// } else if(strcmpi(w1, "log_storage_db") == 0) { -// strcpy(log_config.log_storage_db, w2); -// if(log_config.storage == 1) -// { -// printf("Logging Item Storages"); -// printf(" to table `%s`\n", w2); -// } - } else if(strcmpi(w1, "log_vend_db") == 0) { - strcpy(log_config.log_vend_db, w2); - if(log_config.vend == 1) - printf("Logging Vending to table `%s`\n", w2); - } else if(strcmpi(w1, "log_gm_db") == 0) { - strcpy(log_config.log_gm_db, w2); - if(log_config.gm > 0) - printf("Logging GM Level %d Commands to table `%s`\n", log_config.gm, w2); - } else if(strcmpi(w1, "log_npc_db") == 0) { - strcpy(log_config.log_npc_db, w2); - if(log_config.npc > 0) - printf("Logging NPC 'logmes' to table `%s`\n", w2); - } -#endif - - else if(strcmpi(w1, "log_branch_file") == 0) { - strcpy(log_config.log_branch, w2); - if(log_config.branch > 0 && log_config.sql_logs < 1) - printf("Logging Dead Branch Usage to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_drop_file") == 0) { - strcpy(log_config.log_drop, w2); - if(log_config.drop > 0 && log_config.sql_logs < 1) - printf("Logging Item Drops to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_mvpdrop_file") == 0) { - strcpy(log_config.log_mvpdrop, w2); - if(log_config.mvpdrop > 0 && log_config.sql_logs < 1) - printf("Logging MVP Drops to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_present_file") == 0) { - strcpy(log_config.log_present, w2); - if(log_config.present > 0 && log_config.sql_logs < 1) - printf("Logging Present Usage & Results to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_produce_file") == 0) { - strcpy(log_config.log_produce, w2); - if(log_config.produce > 0 && log_config.sql_logs < 1) - printf("Logging Producing to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_refine_file") == 0) { - strcpy(log_config.log_refine, w2); - if(log_config.refine > 0 && log_config.sql_logs < 1) - printf("Logging Refining to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_trade_file") == 0) { - strcpy(log_config.log_trade, w2); - if(log_config.trade > 0 && log_config.sql_logs < 1) - { - printf("Logging Item Trades"); - if(log_config.zeny > 0) - printf("and Zeny Trades"); - printf(" to file `%s`.txt\n", w2); - } - } else if(strcmpi(w1, "log_storage_file") == 0) { - strcpy(log_config.log_storage, w2); - if(log_config.storage > 0 && log_config.sql_logs < 1) - { - printf("Logging Item Storages"); - printf(" to file `%s`.txt\n", w2); - } - } else if(strcmpi(w1, "log_vend_file") == 0) { - strcpy(log_config.log_vend, w2); - if(log_config.vend > 0 && log_config.sql_logs < 1) - printf("Logging Vending to file `%s`.txt\n", w2); - } else if(strcmpi(w1, "log_gm_file") == 0) { - strcpy(log_config.log_gm, w2); - if(log_config.gm > 0 && log_config.sql_logs < 1) - printf("Logging GM Level %d Commands to file `%s`.txt\n", log_config.gm, w2); - } else if(strcmpi(w1, "log_npc_file") == 0) { - strcpy(log_config.log_npc, w2); - if(log_config.npc > 0 && log_config.sql_logs < 1) - printf("Logging NPC 'logmes' to file `%s`.txt\n", w2); - //support the import command, just like any other config - } else if(strcmpi(w1,"import") == 0) { - log_config_read(w2); - } - } - } - - fclose(fp); - return 0; -} diff --git a/src/map/log.h b/src/map/log.h deleted file mode 100644 index cdb543f0d..000000000 --- a/src/map/log.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _LOG_H_ -#define _LOG_H_ - -#include "map.h" - -#ifndef TXT_ONLY - -extern char db_server_logdb[32]; - -#endif //NOT TXT_ONLY - -int log_branch(struct map_session_data *sd); -int log_drop(struct map_session_data *sd, int monster_id, int *log_drop); -int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp); -int log_present(struct map_session_data *sd, int source_type, int nameid); -int log_produce(struct map_session_data *sd, int nameid, int slot1, int slot2, int slot3, int success); -int log_refine(struct map_session_data *sd, int n, int success); -int log_trade(struct map_session_data *sd,struct map_session_data *target_sd,int n,int amount); -int log_tostorage(struct map_session_data *sd,int n, int guild); -int log_fromstorage(struct map_session_data *sd,int n, int guild); - -int log_vend(struct map_session_data *sd,struct map_session_data *vsd,int n,int amount,int zeny); -int log_zeny(struct map_session_data *sd, struct map_session_data *target_sd,int amount); -int log_atcommand(struct map_session_data *sd, const char *message); -int log_npc(struct map_session_data *sd, const char *message); - -int log_config_read(char *cfgName); - -extern struct Log_Config { - int enable_logs; - int sql_logs; - int rare_items_log,refine_items_log,price_items_log,amount_items_log; - int branch, drop, mvpdrop, present, produce, refine, trade, vend, zeny, gm, npc, storage; - char log_branch[32], log_drop[32], log_mvpdrop[32], log_present[32], log_produce[32], log_refine[32], log_trade[32], log_vend[32], log_gm[32], log_npc[32], log_storage[32]; - char log_branch_db[32], log_drop_db[32], log_mvpdrop_db[32], log_present_db[32], log_produce_db[32], log_refine_db[32], log_trade_db[32], log_vend_db[32], log_gm_db[32], log_npc_db[32]; - int uptime; - char log_uptime[32]; -} log_config; - -#endif diff --git a/src/map/mail.c b/src/map/mail.c deleted file mode 100644 index 42a83de52..000000000 --- a/src/map/mail.c +++ /dev/null @@ -1,337 +0,0 @@ -#ifndef TXT_ONLY -// Mail System for eAthena SQL -// Created by Valaris -// moved all strings to msg_athena.conf [Lupus] - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../common/strlib.h" -#include "../common/socket.h" -#include "../common/timer.h" -#include "../common/nullpo.h" - -#include "map.h" -#include "clif.h" -#include "chrif.h" -#include "intif.h" -#include "atcommand.h" -#include "pc.h" -#include "mail.h" - -char mail_db[32] = "mail"; - -int MAIL_CHECK_TIME = 120000; -int mail_timer; -//extern char *msg_table[1000]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -int mail_check(struct map_session_data *sd,int type) -{ - int i = 0, new_ = 0, priority = 0; - char message[50]; - - nullpo_retr (0, sd); - - sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`read_flag`,`priority`,`check_flag` " - "FROM `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id`", mail_db, sd->status.account_id); - - if (mysql_query(&mail_handle, tmp_msql)) { - printf("Database server error (executing query for %s): %s\n", mail_db, mysql_error(&mail_handle)); - return 0; - } - - mail_res = mysql_store_result(&mail_handle); - if(mail_res) { - if (mysql_num_rows(mail_res) == 0) { - //clif_displaymessage(sd->fd,"You have no messages."); - clif_displaymessage(sd->fd, msg_txt(516)); - - mysql_free_result(mail_res); - return 0; - } - - while ((mail_row = mysql_fetch_row(mail_res))) { - i++; - if(!atoi(mail_row[5])) { - sprintf(tmp_msql,"UPDATE `%s` SET `check_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0])); - if(mysql_query(&mail_handle, tmp_msql) ) { - printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) ); - } - } - - if(!atoi(mail_row[3])) { - new_++; - if(atoi(mail_row[4])) - priority++; - if(type==2 || type==3) { - if(atoi(mail_row[4])) { - //sprintf(message, "%d - From : %s (New - Priority)", i, mail_row[2]); - sprintf(message, msg_txt(511), i, mail_row[2]); - - clif_displaymessage(sd->fd, jstrescape(message)); - } else { - //sprintf(message, "%d - From : %s (New)", i, mail_row[2]); - sprintf(message, msg_txt(512), i, mail_row[2]); - clif_displaymessage(sd->fd, jstrescape(message)); - } - } - } else if(type==2){ - //sprintf(message, "%d - From : %s", i, mail_row[2]); - sprintf(message, msg_txt(513), i, mail_row[2]); - clif_displaymessage(sd->fd, jstrescape(message)); - } - } - - mysql_free_result(mail_res); - } else { - printf("MySQL error (storing query result for %s): %s\n", mail_db, mysql_error(&mail_handle)); - return 0; - } - - if(i>0 && new_>0 && type==1) { - //sprintf(message, "You have %d new messages.", new_); - sprintf(message, msg_txt(514), new_); - - clif_displaymessage(sd->fd, jstrescape(message)); - } - if(i>0 && new_>0 && priority>0 && type==1) { - //sprintf(message, "You have %d unread priority messages.", priority); - sprintf(message, msg_txt(515), priority); - clif_displaymessage(sd->fd, jstrescape(message)); - } - if(!new_) { - //clif_displaymessage(sd->fd, "You have no new messages."); - clif_displaymessage(sd->fd, msg_txt(516)); - } - - return 0; -} - -int mail_read(struct map_session_data *sd, int message_id) -{ - - char message[80]; - - nullpo_retr (0, sd); - - sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`message`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id` LIMIT %d, 1",mail_db,sd->status.account_id,message_id-1); - - if (mysql_query(&mail_handle, tmp_msql)) { - printf("Database server error (executing query for %s): %s\n", mail_db, mysql_error(&mail_handle)); - return 0; - } - - mail_res = mysql_store_result(&mail_handle); - if(mail_res) { - if (mysql_num_rows(mail_res) == 0) { - mysql_free_result(mail_res); - //clif_displaymessage(sd->fd, "Message not found."); - clif_displaymessage(sd->fd, msg_txt(517)); - return 0; - } - - if ((mail_row = mysql_fetch_row(mail_res))) { - if(!atoi(mail_row[6])) { - sprintf(tmp_msql,"UPDATE `%s` SET `check_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0])); - if(mysql_query(&mail_handle, tmp_msql) ) { - printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) ); - } - } - - //sprintf(message, "Reading message from %s", mail_row[2]); - sprintf(message, msg_txt(518), mail_row[2]); - clif_displaymessage(sd->fd, jstrescape(message)); - - sprintf(message, "%s", mail_row[3]); - clif_displaymessage(sd->fd, jstrescape(message)); - - sprintf(tmp_msql,"UPDATE `%s` SET `read_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0])); - if(mysql_query(&mail_handle, tmp_msql) ) { - printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) ); - } - } - - mysql_free_result(mail_res); - - } else { - printf("MySQL error (storing query result for %s): %s\n", mail_db, mysql_error(&mail_handle)); - } - - return 0; -} - -int mail_delete(struct map_session_data *sd, int message_id) -{ - nullpo_retr (0, sd); - - sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id` LIMIT %d, 1",mail_db,sd->status.account_id,message_id-1); - - if (mysql_query(&mail_handle, tmp_msql)) { - printf("Database server error (executing query for %s): %s\n", mail_db, mysql_error(&mail_handle)); - return 0; - } - - mail_res = mysql_store_result(&mail_handle); - if(mail_res) { - if (mysql_num_rows(mail_res) == 0) { - mysql_free_result(mail_res); - //clif_displaymessage(sd->fd, "Message not found."); - clif_displaymessage(sd->fd, msg_txt(517)); - return 0; - } - - if ((mail_row = mysql_fetch_row(mail_res))) { - if(!atoi(mail_row[2]) && atoi(mail_row[3])) { - mysql_free_result(mail_res); - //clif_displaymessage(sd->fd,"Cannot delete unread priority mail."); - clif_displaymessage(sd->fd,msg_txt(519)); - - return 0; - } - if(!atoi(mail_row[4])) { - mysql_free_result(mail_res); - //clif_displaymessage(sd->fd,"You have recieved new mail, use @listmail before deleting."); - clif_displaymessage(sd->fd,msg_txt(520)); - return 0; - } - sprintf(tmp_msql,"DELETE FROM `%s` WHERE `message_id` = \"%d\"", mail_db, atoi(mail_row[0])); - if(mysql_query(&mail_handle, tmp_msql) ) { - mysql_free_result(mail_res); - printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) ); - return 0; - } - //else clif_displaymessage(sd->fd,"Message deleted."); - else clif_displaymessage(sd->fd,msg_txt(521)); - } - - mysql_free_result(mail_res); - - } else { - printf("MySQL error (delete query result for %s): %s\n", mail_db, mysql_error(&mail_handle)); - } - - return 0; -} - -int mail_send(struct map_session_data *sd, char *name, char *message, int flag) -{ - nullpo_retr (0, sd); - - if(pc_isGM(sd) < 80 && sd->mail_counter > 0) { - //clif_displaymessage(sd->fd,"You must wait 10 minutes before sending another message"); - clif_displaymessage(sd->fd,msg_txt(522)); - return 0; - } - - if(strcmp(name,"*")==0) { - if(pc_isGM(sd) < 80) { - //clif_displaymessage(sd->fd, "Access Denied."); - clif_displaymessage(sd->fd, msg_txt(523)); - return 0; - } - else - sprintf(tmp_msql,"SELECT DISTINCT `account_id` FROM `%s` WHERE `account_id` <> '%d' ORDER BY `account_id`", char_db, sd->status.account_id); - } - else - sprintf(tmp_msql,"SELECT `account_id`,`name` FROM `%s` WHERE `name` = \"%s\"", char_db, jstrescape(name)); - - if (mysql_query(&mail_handle, tmp_msql)) { - printf("Database server error (executing query for %s): %s\n", char_db, mysql_error(&mail_handle)); - return 0; - } - - mail_res = mysql_store_result(&mail_handle); - if(mail_res) { - if (mysql_num_rows(mail_res) == 0) { - mysql_free_result(mail_res); - //clif_displaymessage(sd->fd,"Character does not exist."); - clif_displaymessage(sd->fd,msg_txt(524)); - return 0; - } - - while ((mail_row = mysql_fetch_row(mail_res))) { - if(strcmp(name,"*")==0) { - sprintf(tmp_msql, "INSERT DELAYED INTO `%s` (`to_account_id`,`from_account_id`,`from_char_name`,`message`,`priority`)" - " VALUES ('%d', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), sd->status.account_id, sd->status.name, jstrescape(message), flag); - } - else { - sprintf(tmp_msql, "INSERT DELAYED INTO `%s` (`to_account_id`,`to_char_name`,`from_account_id`,`from_char_name`,`message`,`priority`)" - " VALUES ('%d', '%s', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), mail_row[1], sd->status.account_id, sd->status.name, jstrescape(message), flag); - if(pc_isGM(sd) < 80) - sd->mail_counter=5; - } - - if(mysql_query(&mail_handle, tmp_msql) ) { - mysql_free_result(mail_res); - printf("DB server Error (insert `mail_db`)- %s\n", mysql_error(&mail_handle) ); - return 0; - } - } - } - - //clif_displaymessage(sd->fd,"Mail has been sent."); - clif_displaymessage(sd->fd,msg_txt(525)); - - return 0; -} - -int mail_check_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd = NULL; - int i; - - if(mail_timer != tid) - return 0; - - sprintf(tmp_msql,"SELECT DISTINCT `to_account_id` FROM `%s` WHERE `read_flag` = '0' AND `check_flag` = '0'", mail_db); - - if (mysql_query(&mail_handle, tmp_msql)) { - printf("Database server error (executing query for %s): %s\n", char_db, mysql_error(&mail_handle)); - mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0); - return 0; - } - - mail_res = mysql_store_result(&mail_handle); - - if (mail_res) { - if (mysql_num_rows(mail_res) == 0) { - mysql_free_result(mail_res); - mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0); - return 0; - } - - while ((mail_row = mysql_fetch_row(mail_res))) { - for (i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data *) session[i]->session_data) && sd->state.auth){ - if(pc_isGM(sd) < 80 && sd->mail_counter > 0) - sd->mail_counter--; - if(sd->status.account_id==atoi(mail_row[0])) - //clif_displaymessage(sd->fd, "You have new mail."); - clif_displaymessage(sd->fd, msg_txt(526)); - } - } - } - } - - sprintf(tmp_msql,"UPDATE `%s` SET `check_flag`='1' WHERE `check_flag`= '0' ", mail_db); - if(mysql_query(&mail_handle, tmp_msql) ) { - printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) ); - } - - mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0); - return 0; -} - -int do_init_mail(void) -{ - add_timer_func_list(mail_check_timer,"mail_check_timer"); - mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0); - return 0; -} - -#endif diff --git a/src/map/mail.h b/src/map/mail.h deleted file mode 100644 index 6bd8e510c..000000000 --- a/src/map/mail.h +++ /dev/null @@ -1,9 +0,0 @@ -// Mail System for eAthena -// Created by Valaris - -int mail_check(struct map_session_data *sd, int type); -int mail_read(struct map_session_data *sd, int message_id); -int mail_delete(struct map_session_data *sd, int message_id); -int mail_send(struct map_session_data *sd, char *name, char *message, int flag); - -int do_init_mail(void); diff --git a/src/map/map.c b/src/map/map.c deleted file mode 100644 index 386b38954..000000000 --- a/src/map/map.c +++ /dev/null @@ -1,3437 +0,0 @@ -// $Id: map.c,v 1.6 2004/09/25 17:37:01 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#ifdef _WIN32 -#include <winsock.h> -#else -#include <netdb.h> -#endif -#include <math.h> - -#include "core.h" -#include "timer.h" -#include "db.h" -#include "grfio.h" -#include "malloc.h" -#include "version.h" - -#include "map.h" -#include "chrif.h" -#include "clif.h" -#include "intif.h" -#include "npc.h" -#include "pc.h" -#include "status.h" -#include "mob.h" -#include "chat.h" -#include "itemdb.h" -#include "storage.h" -#include "skill.h" -#include "trade.h" -#include "party.h" -#include "battle.h" -#include "script.h" -#include "guild.h" -#include "pet.h" -#include "atcommand.h" -#include "charcommand.h" -#include "nullpo.h" -#include "socket.h" -#include "log.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -// maybe put basic macros to somewhere else -#define swap(a,b) ((a == b) || ((a ^= b), (b ^= a), (a ^= b))) - -#ifndef TXT_ONLY - -#include "mail.h" // mail system [Valaris] - -MYSQL mmysql_handle; -MYSQL_RES* sql_res ; -MYSQL_ROW sql_row ; -char tmp_sql[65535]=""; - -MYSQL lmysql_handle; -MYSQL_RES* lsql_res ; -MYSQL_ROW lsql_row ; -char tmp_lsql[65535]=""; - -MYSQL mail_handle; // mail system [Valaris] -MYSQL_RES* mail_res ; -MYSQL_ROW mail_row ; -char tmp_msql[65535]=""; - -int map_server_port = 3306; -char map_server_ip[16] = "127.0.0.1"; -char map_server_id[32] = "ragnarok"; -char map_server_pw[32] = "ragnarok"; -char map_server_db[32] = "ragnarok"; -int db_use_sqldbs = 0; - -int login_server_port = 3306; -char login_server_ip[16] = "127.0.0.1"; -char login_server_id[32] = "ragnarok"; -char login_server_pw[32] = "ragnarok"; -char login_server_db[32] = "ragnarok"; - -char item_db_db[32] = "item_db"; -char mob_db_db[32] = "mob_db"; -char login_db[32] = "login"; -char login_db_level[32] = "level"; -char login_db_account_id[32] = "account_id"; - -char log_db[32] = "log"; -char log_db_ip[16] = "127.0.0.1"; -char log_db_id[32] = "ragnarok"; -char log_db_pw[32] = "ragnarok"; -int log_db_port = 3306; - -char gm_db[32] = "login"; -char gm_db_level[32] = "level"; -char gm_db_account_id[32] = "account_id"; - -int lowest_gm_level = 1; -int read_gm_interval = 600000; - -char char_db[32] = "char"; - -static int online_timer(int,unsigned int,int,int); -int CHECK_INTERVAL = 3600000; // [Valaris] - -#endif /* not TXT_ONLY */ - -char *INTER_CONF_NAME; -char *LOG_CONF_NAME; -char *MAP_CONF_NAME; -char *BATTLE_CONF_FILENAME; -char *ATCOMMAND_CONF_FILENAME; -char *CHARCOMMAND_CONF_FILENAME; -char *SCRIPT_CONF_NAME; -char *MSG_CONF_NAME; -char *GRF_PATH_FILENAME; - -#define USE_AFM -#define USE_AF2 - -// 極力 staticでロ?カルに?める -static struct dbt * id_db=NULL; -static struct dbt * map_db=NULL; -static struct dbt * nick_db=NULL; -static struct dbt * charid_db=NULL; - -static int users=0; -static struct block_list *objects[MAX_FLOORITEM]; -static int first_free_object_id=0,last_object_id=0; - -#define block_free_max 1048576 -static void *block_free[block_free_max]; -static int block_free_count = 0, block_free_lock = 0; - -#define BL_LIST_MAX 1048576 -static struct block_list *bl_list[BL_LIST_MAX]; -static int bl_list_count = 0; - -static char afm_dir[1024] = ""; // [Valaris] - -struct map_data map[MAX_MAP_PER_SERVER]; -int map_num = 0; - -int map_port=0; - -int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; -int agit_flag = 0; -int night_flag = 0; // 0=day, 1=night [Yor] - -//Added for Mugendai's I'm Alive mod -int imalive_on=0; -int imalive_time=60; -//Added by Mugendai for GUI -int flush_on=1; -int flush_time=100; - -struct charid2nick { - char nick[24]; - int req_id; -}; - -// ォ゙ォテォラォュォ罩テォキォ袮ラ鯑ォユォ鬮ー(map_athana.conf?ェホread_map_from_cacheェヌヲ・) -// 0:ララ鯑ェキェハェ、 1:゙ェ?ワチ 2:?ワチ -int map_read_flag = READ_FROM_GAT; -char map_cache_file[256]="db/map.info"; // ォ゙ォテォラォュォ罩テォキォ雖ユォ。ォ、ォ・」 - -char motd_txt[256] = "conf/motd.txt"; -char help_txt[256] = "conf/help.txt"; - -char wisp_server_name[24] = "Server"; // can be modified in char-server configuration file - -int console = 0; - -/*========================================== - * 全map鯖?計での接??設定 - * (char鯖から送られてくる) - *------------------------------------------ - */ -void map_setusers(int fd) -{ - users = RFIFOL(fd,2); - // send some anser - WFIFOW(fd,0) = 0x2718; - WFIFOSET(fd,2); -} - -/*========================================== - * 全map鯖?計での接??取得 (/wへの?答用) - *------------------------------------------ - */ -int map_getusers(void) { - return users; -} - -// -// block削除の安全性確保?理 -// - -/*========================================== - * blockをfreeするときfreeの?わりに呼ぶ - * ロックされているときはバッファにためる - *------------------------------------------ - */ -int map_freeblock( void *bl ) -{ - if(block_free_lock==0){ - aFree(bl); - bl = NULL; - } - else{ - if( block_free_count>=block_free_max ) { - if(battle_config.error_log) - printf("map_freeblock: *WARNING* too many free block! %d %d\n", - block_free_count,block_free_lock); - } - else - block_free[block_free_count++]=bl; - } - return block_free_lock; -} -/*========================================== - * blockのfreeを一時的に禁止する - *------------------------------------------ - */ -int map_freeblock_lock(void) { - return ++block_free_lock; -} - -/*========================================== - * blockのfreeのロックを解除する - * このとき、ロックが完全になくなると - * バッファにたまっていたblockを全部削除 - *------------------------------------------ - */ -int map_freeblock_unlock(void) { - if ((--block_free_lock) == 0) { - int i; -// if(block_free_count>0) { -// if(battle_config.error_log) -// printf("map_freeblock_unlock: free %d object\n",block_free_count); -// } - for(i=0;i<block_free_count;i++){ - aFree(block_free[i]); - block_free[i] = NULL; - } - block_free_count=0; - }else if(block_free_lock<0){ - if(battle_config.error_log) - printf("map_freeblock_unlock: lock count < 0 !\n"); - block_free_lock = 0; // 次回以降のロックに支障が出てくるのでリセット - } - return block_free_lock; -} - -// map_freeblock_lock() を呼んで map_freeblock_unlock() を呼ばない -// 関数があったので、定期的にblock_free_lockをリセットするようにする。 -// この関数は、do_timer() のトップレベルから呼ばれるので、 -// block_free_lock を直接いじっても支障無いはず。 - -int map_freeblock_timer(int tid,unsigned int tick,int id,int data) { - if(block_free_lock > 0) { - printf("map_freeblock_timer: block_free_lock(%d) is invalid.\n",block_free_lock); - block_free_lock = 1; - map_freeblock_unlock(); - } - // else { - // printf("map_freeblock_timer: check ok\n"); - // } - return 0; -} - -// -// block化?理 -// -/*========================================== - * map[]のblock_listから?がっている場合に - * bl->prevにbl_headのアドレスを入れておく - *------------------------------------------ - */ -static struct block_list bl_head; - -/*========================================== - * map[]のblock_listに追加 - * mobは?が多いので別リスト - * - * ?にlink?みかの確認が無い。危?かも - *------------------------------------------ - */ -int map_addblock(struct block_list *bl) -{ - int m,x,y; - - nullpo_retr(0, bl); - - if(bl->prev != NULL){ - if(battle_config.error_log) - printf("map_addblock error : bl->prev!=NULL\n"); - return 0; - } - - m=bl->m; - x=bl->x; - y=bl->y; - if(m<0 || m>=map_num || - x<0 || x>=map[m].xs || - y<0 || y>=map[m].ys) - return 1; - - if(bl->type==BL_MOB){ - bl->next = map[m].block_mob[x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs]; - bl->prev = &bl_head; - if(bl->next) bl->next->prev = bl; - map[m].block_mob[x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs] = bl; - map[m].block_mob_count[x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs]++; - } else { - bl->next = map[m].block[x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs]; - bl->prev = &bl_head; - if(bl->next) bl->next->prev = bl; - map[m].block[x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs] = bl; - map[m].block_count[x/BLOCK_SIZE+(y/BLOCK_SIZE)*map[m].bxs]++; - if(bl->type==BL_PC) - map[m].users++; - } - - return 0; -} - -/*========================================== - * map[]のblock_listから外す - * prevがNULLの場合listに?がってない - *------------------------------------------ - */ -int map_delblock(struct block_list *bl) -{ - int b; - nullpo_retr(0, bl); - - // ?にblocklistから?けている - if(bl->prev==NULL){ - if(bl->next!=NULL){ - // prevがNULLでnextがNULLでないのは有ってはならない - if(battle_config.error_log) - printf("map_delblock error : bl->next!=NULL\n"); - } - return 0; - } - - b = bl->x/BLOCK_SIZE+(bl->y/BLOCK_SIZE)*map[bl->m].bxs; - - if(bl->type==BL_PC) - map[bl->m].users--; - if(bl->next) - bl->next->prev = bl->prev; - if(bl->prev==&bl_head){ - // リストの頭なので、map[]のblock_listを更新する - if(bl->type==BL_MOB){ - map[bl->m].block_mob[b] = bl->next; - if((map[bl->m].block_mob_count[b]--) < 0) - map[bl->m].block_mob_count[b] = 0; - } else { - map[bl->m].block[b] = bl->next; - if((map[bl->m].block_count[b]--) < 0) - map[bl->m].block_count[b] = 0; - } - } else { - bl->prev->next = bl->next; - } - bl->next = NULL; - bl->prev = NULL; - - return 0; -} - -/*========================================== - * 周?のPC人?を?える (現在未使用) - *------------------------------------------ - */ -int map_countnearpc(int m, int x, int y) { - int bx,by,c=0; - struct block_list *bl=NULL; - - if(map[m].users==0) - return 0; - for(by=y/BLOCK_SIZE-AREA_SIZE/BLOCK_SIZE-1;by<=y/BLOCK_SIZE+AREA_SIZE/BLOCK_SIZE+1;by++){ - if(by<0 || by>=map[m].bys) - continue; - for(bx=x/BLOCK_SIZE-AREA_SIZE/BLOCK_SIZE-1;bx<=x/BLOCK_SIZE+AREA_SIZE/BLOCK_SIZE+1;bx++){ - if(bx<0 || bx>=map[m].bxs) - continue; - bl = map[m].block[bx+by*map[m].bxs]; - for(;bl;bl=bl->next){ - if(bl->type==BL_PC) - c++; - } - } - } - return c; -} - -/*========================================== - * セル上のPCとMOBの?を?える (グランドクロス用) - *------------------------------------------ - */ -int map_count_oncell(int m, int x, int y) { - int bx,by; - struct block_list *bl=NULL; - int i,c; - int count = 0; - - if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys)) - return 1; - bx = x/BLOCK_SIZE; - by = y/BLOCK_SIZE; - - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl->x == x && bl->y == y && bl->type == BL_PC) count++; - } - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl->x == x && bl->y == y) count++; - } - if(!count) count = 1; - return count; -} -/* - * ォサォ・セェホフェヒフクェトェアェソォケォュォ・讚ヒォテォネェレェケ - */ -struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,int y,int skill_id,struct skill_unit *out_unit) -{ - int m,bx,by; - struct block_list *bl; - int i,c; - struct skill_unit *unit; - m = target->m; - - if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys)) - return NULL; - bx = x/BLOCK_SIZE; - by = y/BLOCK_SIZE; - - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if (bl->x != x || bl->y != y || bl->type != BL_SKILL) - continue; - unit = (struct skill_unit *) bl; - if (unit==out_unit || !unit->alive || - !unit->group || unit->group->skill_id!=skill_id) - continue; - if (battle_check_target(&unit->bl,target,unit->group->target_flag)>0) - return unit; - } - return NULL; -} - -/*========================================== - * map m (x0,y0)-(x1,y1)?の全objに?して - * funcを呼ぶ - * type!=0 ならその種類のみ - *------------------------------------------ - */ -void map_foreachinarea(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int type,...) { - va_list ap; - int bx,by; - struct block_list *bl=NULL; - int blockcount=bl_list_count,i,c; - - if(m < 0) - return; - va_start(ap,type); - if (x0 < 0) x0 = 0; - if (y0 < 0) y0 = 0; - if (x1 >= map[m].xs) x1 = map[m].xs-1; - if (y1 >= map[m].ys) y1 = map[m].ys-1; - if (type == 0 || type != BL_MOB) - for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) { - for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl && type && bl->type!=type) - continue; - if(bl && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - } - if(type==0 || type==BL_MOB) - for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){ - for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - } - - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachinarea: *WARNING* block count too many!\n"); - } - - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=blockcount;i<bl_list_count;i++) - if(bl_list[i]->prev) // 有?かどうかチェック - func(bl_list[i],ap); - - map_freeblock_unlock(); // 解放を許可する - - va_end(ap); - bl_list_count = blockcount; -} - -/*========================================== - * 矩形(x0,y0)-(x1,y1)が(dx,dy)移動した時の - * 領域外になる領域(矩形かL字形)?のobjに - * ?してfuncを呼ぶ - * - * dx,dyは-1,0,1のみとする(どんな値でもいいっぽい?) - *------------------------------------------ - */ -void map_foreachinmovearea(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int dx,int dy,int type,...) { - int bx,by; - struct block_list *bl=NULL; - va_list ap; - int blockcount=bl_list_count,i,c; - - va_start(ap,type); - if(dx==0 || dy==0){ - // 矩形領域の場合 - if(dx==0){ - if(dy<0){ - y0=y1+dy+1; - } else { - y1=y0+dy-1; - } - } else if(dy==0){ - if(dx<0){ - x0=x1+dx+1; - } else { - x1=x0+dx-1; - } - } - if(x0<0) x0=0; - if(y0<0) y0=0; - if(x1>=map[m].xs) x1=map[m].xs-1; - if(y1>=map[m].ys) y1=map[m].ys-1; - for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){ - for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl && type && bl->type!=type) - continue; - if(bl && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl && type && bl->type!=type) - continue; - if(bl && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - } - }else{ - // L字領域の場合 - - if(x0<0) x0=0; - if(y0<0) y0=0; - if(x1>=map[m].xs) x1=map[m].xs-1; - if(y1>=map[m].ys) y1=map[m].ys-1; - for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){ - for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl && type && bl->type!=type) - continue; - if((bl) && !(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1)) - continue; - if((bl) && ((dx>0 && bl->x<x0+dx) || (dx<0 && bl->x>x1+dx) || - (dy>0 && bl->y<y0+dy) || (dy<0 && bl->y>y1+dy)) && - bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl && type && bl->type!=type) - continue; - if((bl) && !(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1)) - continue; - if((bl) && ((dx>0 && bl->x<x0+dx) || (dx<0 && bl->x>x1+dx) || - (dy>0 && bl->y<y0+dy) || (dy<0 && bl->y>y1+dy)) && - bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - } - - } - - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachinarea: *WARNING* block count too many!\n"); - } - - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=blockcount;i<bl_list_count;i++) - if(bl_list[i]->prev) { // 有?かどうかチェック - if (bl_list[i]->type == BL_PC - && session[((struct map_session_data *) bl_list[i])->fd] == NULL) - continue; - func(bl_list[i],ap); - } - - map_freeblock_unlock(); // 解放を許可する - - va_end(ap); - bl_list_count = blockcount; -} - -// -- moonsoul (added map_foreachincell which is a rework of map_foreachinarea but -// which only checks the exact single x/y passed to it rather than an -// area radius - may be more useful in some instances) -// -void map_foreachincell(int (*func)(struct block_list*,va_list),int m,int x,int y,int type,...) { - int bx,by; - struct block_list *bl=NULL; - va_list ap; - int blockcount=bl_list_count,i,c; - - va_start(ap,type); - - by=y/BLOCK_SIZE; - bx=x/BLOCK_SIZE; - - if(type==0 || type!=BL_MOB) - { - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next) - { - if(type && bl && bl->type!=type) - continue; - if(bl && bl->x==x && bl->y==y && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - - if(type==0 || type==BL_MOB) - { - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next) - { - if(bl && bl->x==x && bl->y==y && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachincell: *WARNING* block count too many!\n"); - } - - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=blockcount;i<bl_list_count;i++) - if(bl_list[i]->prev) // 有?かどうかチェック - func(bl_list[i],ap); - - map_freeblock_unlock(); // 解放を許可する - - va_end(ap); - bl_list_count = blockcount; -} - -/*============================================================ -* For checking a path between two points (x0, y0) and (x1, y1) -*------------------------------------------------------------ - */ -void map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int type,...) -{ -/* va_list ap; - double deltax = 0.0; - double deltay = 0.0; - int t, bx, by; - int *xs, *ys; - int blockcount = bl_list_count, i, c; - struct block_list *bl = NULL; - - if(m < 0) - return; - va_start(ap,type); - if (x0 < 0) x0 = 0; - if (y0 < 0) y0 = 0; - if (x1 >= map[m].xs) x1 = map[m].xs-1; - if (y1 >= map[m].ys) y1 = map[m].ys-1; - - // I'm not finished thinking on it - // but first it might better use a parameter equation - // x=(x1-x0)*t+x0; y=(y1-y0)*t+y0; t=[0,1] - // would not need special case aproximating for infinity/zero slope - // so maybe this way: - - // find maximum runindex - int tmax = abs(y1-y0); - if(tmax < abs(x1-x0)) - tmax = abs(x1-x0); - - xs = (int *)aCallocA(tmax + 1, sizeof(int)); - ys = (int *)aCallocA(tmax + 1, sizeof(int)); - - // pre-calculate delta values for x and y destination - // should speed up cause you don't need to divide in the loop - if(tmax>0) - { - deltax = ((double)(x1-x0)) / ((double)tmax); - deltay = ((double)(y1-y0)) / ((double)tmax); - } - // go along the index - for(t=0; t<=tmax; t++) - { - int x = (int)floor(deltax * (double)t +0.5)+x0; - int y = (int)floor(deltay * (double)t +0.5)+y0; - // the xy pairs of points in line between x0y0 and x1y1 - // including start and end point - xs[t] = x; - ys[t] = y; - } - - if (type == 0 || type != BL_MOB) - - -this here is wrong, -there is no check if x0<x1 and y0<y1 -but this is not valid in 3 of 4 cases, -so in this case here you check only blocks when shooting to a positive direction -shooting in other directions just do nothing like the skill has failed -if you want to keep this that way then check and swap x0,y0 with x1,y1 - - for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) { - for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ - bl = map[m].block[bx+by*map[m].bxs]; - c = map[m].block_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl) { - if (type && bl->type!=type) - continue; - for(t=0; t<=tmax; t++) - if(bl->x==xs[t] && bl->y==ys[t] && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - } - } - if(type==0 || type==BL_MOB) - for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){ - for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl) { - for(t=0; t<=tmax; t++) - if(bl->x==xs[t] && bl->y==ys[t] && bl_list_count<BL_LIST_MAX) - bl_list[bl_list_count++]=bl; - } - } - } - } - - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachinarea: *WARNING* block count too many!\n"); - } - - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=blockcount;i<bl_list_count;i++) - if(bl_list[i]->prev) // 有?かどうかチェック - func(bl_list[i],ap); - - map_freeblock_unlock(); // 解放を許可する - - bl_list_count = blockcount; - aFree (xs); - aFree (ys); - va_end(ap); - -*/ - -/* -////////////////////////////////////////////////////////////// -// -// sharp shooting 1 -// -////////////////////////////////////////////////////////////// -// problem: -// finding targets standing on and within some range of a line -// (t1,t2 t3 and t4 get hit) -// -// target 1 -// x t4 -// t2 -// t3 x -// x -// S -////////////////////////////////////////////////////////////// -// solution 1 (straight forward, but a bit calculation expensive) -// calculating perpendiculars from quesionable mobs to the straight line -// if the mob is hit then depends on the distance to the line -// -// solution 2 (complex, need to handle many cases, but maybe faster) -// make a formula to deside if a given (x,y) is within a shooting area -// the shape can be ie. rectangular or triangular -// if the mob is hit then depends on if the mob is inside or outside the area -// I'm not going to implement this, but if somebody is interested -// in vector algebra, it might be some fun - -////////////////////////////////////////////////////////////// -// possible shooting ranges (I prefer the second one) -////////////////////////////////////////////////////////////// -// -// ---------------- ------ -// ---------------- ------------ -// Sxxxxxxxxxxxxxxxxtarget Sxxxxxxxxxxxxxxxxtarget -// ---------------- ------------ -// ---------------- ----- -// -// the original code implemented the left structure -// might be not that realistic, so I changed to the other one -// I take "range" as max distance from the line -////////////////////////////////////////////////////////////// - - va_list ap; - int i, blockcount = bl_list_count; - struct block_list *bl; - int c1,c2; - -/////////// - double deltax,deltay; - double k,kfact,knorm; - double v1,v2,distance; - double xm,ym,rd; - int bx,by,bx0,bx1,by0,by1; -////////////// - // no map - if(m < 0) return; - - // xy out of range - if (x0 < 0) x0 = 0; - if (y0 < 0) y0 = 0; - if (x1 >= map[m].xs) x1 = map[m].xs-1; - if (y1 >= map[m].ys) y1 = map[m].ys-1; - - /////////////////////////////// - // stuff for a linear equation in xy coord to calculate - // the perpendicular from a block xy to the straight line - deltax = (x1-x0); - deltay = (y1-y0); - kfact = (deltax*deltax+deltay*deltay); // the sqare length of the line - knorm = -deltax*x0-deltay*y0; // the offset vector param - -//printf("(%i,%i)(%i,%i) range: %i\n",x0,y0,x1,y1,range); - - if(kfact==0) return; // shooting at the standing position should not happen - kfact = 1/kfact; // divide here and multiply in the loop - - range *= range; // compare with range^2 so we can skip a sqrt and signs - - /////////////////////////////// - // prepare shooting area check - xm = (x1+x0)/2.0; - ym = (y1+y0)/2.0;// middle point on the shooting line - // the sqared radius of a circle around the shooting range - // plus the sqared radius of a block - rd = (x0-xm)*(x0-xm) + (y0-ym)*(y0-ym) + (range*range) - +BLOCK_SIZE*BLOCK_SIZE/2; - // so whenever a block midpoint is within this circle - // some of the block area is possibly within the shooting range - - /////////////////////////////// - // what blocks we need to test - // blocks covered by the xy position of begin and end of the line - bx0 = x0/BLOCK_SIZE; - bx1 = x1/BLOCK_SIZE; - by0 = y0/BLOCK_SIZE; - by1 = y1/BLOCK_SIZE; - // swap'em for a smallest-to-biggest run - if(bx0>bx1) swap(bx0,bx1); - if(by0>by1) swap(by0,by1); - - // enlarge the block area by a range value and 1 - // so we can be sure to process all blocks that might touch the shooting area - // in this case here with BLOCK_SIZE=8 and range=2 it will be only enlarged by 1 - // but I implement it anyway just in case that ranges will be larger - // or BLOCK_SIZE smaller in future - i = (range/BLOCK_SIZE+1);//temp value - if(bx0>i) bx0 -=i; else bx0=0; - if(by0>i) by0 -=i; else by0=0; - if(bx1+i<map[m].bxs) bx1 +=i; else bx1=map[m].bxs-1; - if(by1+i<map[m].bys) by1 +=i; else by1=map[m].bys-1; - - -//printf("run for (%i,%i)(%i,%i)\n",bx0,by0,bx1,by1); - for(bx=bx0; bx<=bx1; bx++) - for(by=by0; by<=by1; by++) - { // block xy - c1 = map[m].block_count[bx+by*map[m].bxs]; // number of elements in the block - c2 = map[m].block_mob_count[bx+by*map[m].bxs]; // number of mobs in the mob block - if( (c1==0) && (c2==0) ) continue; // skip if nothing in the blocks - -//printf("block(%i,%i) %i %i\n",bx,by,c1,c2);fflush(stdout); - // test if the mid-point of the block is too far away - // so we could skip the whole block in this case - v1 = (bx*BLOCK_SIZE+BLOCK_SIZE/2-xm)*(bx*BLOCK_SIZE+BLOCK_SIZE/2-xm) - +(by*BLOCK_SIZE+BLOCK_SIZE/2-ym)*(by*BLOCK_SIZE+BLOCK_SIZE/2-ym); -//printf("block(%i,%i) v1=%f rd=%f\n",bx,by,v1,rd);fflush(stdout); - // check for the worst case scenario - if(v1 > rd) continue; - - // it seems that the block is at least partially covered by the shooting range - // so we go into it - if(type==0 || type!=BL_MOB) { - bl = map[m].block[bx+by*map[m].bxs]; // a block with the elements - for(i=0;i<c1 && bl;i++,bl=bl->next){ // go through all elements - if( bl && ( !type || bl->type==type ) && bl_list_count<BL_LIST_MAX ) - { - // calculate the perpendicular from block xy to the straight line - k = kfact*(deltax*bl->x + deltay*bl->y + knorm); - // check if the perpendicular is within start and end of our line - if(k>=0 && k<=1) - { // calculate the distance - v1 = deltax*k+x0 - bl->x; - v2 = deltay*k+y0 - bl->y; - distance = v1*v1+v2*v2; - // triangular shooting range - if( distance <= range*k ) - bl_list[bl_list_count++]=bl; - } - } - }//end for elements - } - - if(type==0 || type==BL_MOB) { - bl = map[m].block_mob[bx+by*map[m].bxs]; // and the mob block - for(i=0;i<c2 && bl;i++,bl=bl->next){ - if(bl && bl_list_count<BL_LIST_MAX) { - // calculate the perpendicular from block xy to the straight line - k = kfact*(deltax*bl->x + deltay*bl->y + knorm); -//printf("mob: (%i,%i) k=%f ",bl->x,bl->y, k); - // check if the perpendicular is within start and end of our line - if(k>=0 && k<=1) - { - v1 = deltax*k+x0 - bl->x; - v2 = deltay*k+y0 - bl->y; - distance = v1*v1+v2*v2; -//printf("dist: %f",distance); - // triangular shooting range - if( distance <= range*k ) - { -//printf(" hit"); - bl_list[bl_list_count++]=bl; - } - } -//printf("\n"); - } - }//end for mobs - } - }//end for(bx,by) - - - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachinarea: *WARNING* block count too many!\n"); - } - - va_start(ap,type); - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=blockcount;i<bl_list_count;i++) - if(bl_list[i]->prev) // 有?かどうかチェック - func(bl_list[i],ap); - - map_freeblock_unlock(); // 解放を許可する - va_end(ap); - - bl_list_count = blockcount; - -*/ - - -////////////////////////////////////////////////////////////// -// -// sharp shooting 2 -// -////////////////////////////////////////////////////////////// -// problem: -// finding targets standing exactly on a line -// (only t1 and t2 get hit) -// -// target 1 -// x t4 -// t2 -// t3 x -// x -// S -////////////////////////////////////////////////////////////// - va_list ap; - int i, blockcount = bl_list_count; - struct block_list *bl; - int c1,c2; - - ////////////////////////////////////////////////////////////// - // linear parametric equation - // x=(x1-x0)*t+x0; y=(y1-y0)*t+y0; t=[0,1] - ////////////////////////////////////////////////////////////// - // linear equation for finding a single line between (x0,y0)->(x1,y1) - // independent of the given xy-values - double dx = 0.0; - double dy = 0.0; - int bx=-1; // initialize block coords to some impossible value - int by=-1; - - int t; - /////////////////////////////// - // find maximum runindex - int tmax = abs(y1-y0); - if(tmax < abs(x1-x0)) - tmax = abs(x1-x0); - // pre-calculate delta values for x and y destination - // should speed up cause you don't need to divide in the loop - if(tmax>0) - { - dx = ((double)(x1-x0)) / ((double)tmax); - dy = ((double)(y1-y0)) / ((double)tmax); - } - // go along the index - for(t=0; t<=tmax; t++) - { // xy-values of the line including start and end point - int x = (int)floor(dx * (double)t +0.5)+x0; - int y = (int)floor(dy * (double)t +0.5)+y0; - - // check the block index of the calculated xy - if( (bx!=x/BLOCK_SIZE) || (by!=y/BLOCK_SIZE) ) - { // we have reached a new block - // so we store the current block coordinates - bx = x/BLOCK_SIZE; - by = y/BLOCK_SIZE; - - // and process the data - c1 = map[m].block_count[bx+by*map[m].bxs]; // number of elements in the block - c2 = map[m].block_mob_count[bx+by*map[m].bxs]; // number of mobs in the mob block - if( (c1==0) && (c2==0) ) continue; // skip if nothing in the block - - if(type==0 || type!=BL_MOB) { - bl = map[m].block[bx+by*map[m].bxs]; // a block with the elements - for(i=0;i<c1 && bl;i++,bl=bl->next){ // go through all elements - if( bl && ( !type || bl->type==type ) && bl_list_count<BL_LIST_MAX ) - { - // check if block xy is on the line - if( (bl->x-x0)*(y1-y0) == (bl->y-y0)*(x1-x0) ) - // and if it is within start and end point - if( (((x0<=x1)&&(x0<=bl->x)&&(bl->x<=x1)) || ((x0>=x1)&&(x0>=bl->x)&&(bl->x>=x1))) && - (((y0<=y1)&&(y0<=bl->y)&&(bl->y<=y1)) || ((y0>=y1)&&(y0>=bl->y)&&(bl->y>=y1))) ) - bl_list[bl_list_count++]=bl; - } - }//end for elements - } - - if(type==0 || type==BL_MOB) { - bl = map[m].block_mob[bx+by*map[m].bxs]; // and the mob block - for(i=0;i<c2 && bl;i++,bl=bl->next){ - if(bl && bl_list_count<BL_LIST_MAX) { - // check if mob xy is on the line - if( (bl->x-x0)*(y1-y0) == (bl->y-y0)*(x1-x0) ) - // and if it is within start and end point - if( (((x0<=x1)&&(x0<=bl->x)&&(bl->x<=x1)) || ((x0>=x1)&&(x0>=bl->x)&&(bl->x>=x1))) && - (((y0<=y1)&&(y0<=bl->y)&&(bl->y<=y1)) || ((y0>=y1)&&(y0>=bl->y)&&(bl->y>=y1))) ) - bl_list[bl_list_count++]=bl; - } - }//end for mobs - } - } - }//end for index - - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachinarea: *WARNING* block count too many!\n"); - } - - va_start(ap,type); - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=blockcount;i<bl_list_count;i++) - if(bl_list[i]->prev) // 有?かどうかチェック - func(bl_list[i],ap); - - map_freeblock_unlock(); // 解放を許可する - va_end(ap); - - bl_list_count = blockcount; -} - -/*========================================== - * 床アイテムやエフェクト用の一時obj割り?て - * object[]への保存とid_db登?まで - * - * bl->idもこの中で設定して問題無い? - *------------------------------------------ - */ -int map_addobject(struct block_list *bl) { - int i; - if( bl == NULL ){ - printf("map_addobject nullpo?\n"); - return 0; - } - if(first_free_object_id<2 || first_free_object_id>=MAX_FLOORITEM) - first_free_object_id=2; - for(i=first_free_object_id;i<MAX_FLOORITEM;i++) - if(objects[i]==NULL) - break; - if(i>=MAX_FLOORITEM){ - if(battle_config.error_log) - printf("no free object id\n"); - return 0; - } - first_free_object_id=i; - if(last_object_id<i) - last_object_id=i; - objects[i]=bl; - numdb_insert(id_db,i,bl); - return i; -} - -/*========================================== - * 一時objectの解放 - * map_delobjectのfreeしないバ?ジョン - *------------------------------------------ - */ -int map_delobjectnofree(int id) { - if(objects[id]==NULL) - return 0; - - map_delblock(objects[id]); - numdb_erase(id_db,id); -// map_freeblock(objects[id]); - objects[id]=NULL; - - if(first_free_object_id>id) - first_free_object_id=id; - - while(last_object_id>2 && objects[last_object_id]==NULL) - last_object_id--; - - return 0; -} - -/*========================================== - * 一時objectの解放 - * block_listからの削除、id_dbからの削除 - * object dataのfree、object[]へのNULL代入 - * - * addとの??性が無いのが?になる - *------------------------------------------ - */ -int map_delobject(int id) { - struct block_list *obj = objects[id]; - - if(obj==NULL) - return 0; - - map_delobjectnofree(id); - map_freeblock(obj); - - return 0; -} - -/*========================================== - * 全一時obj相手にfuncを呼ぶ - * - *------------------------------------------ - */ -void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...) { - int i; - int blockcount=bl_list_count; - va_list ap; - - va_start(ap,type); - - for(i=2;i<=last_object_id;i++){ - if(objects[i]){ - if(type && objects[i]->type!=type) - continue; - if(bl_list_count>=BL_LIST_MAX) { - if(battle_config.error_log) - printf("map_foreachobject: too many block !\n"); - } - else - bl_list[bl_list_count++]=objects[i]; - } - } - - map_freeblock_lock(); - - for(i=blockcount;i<bl_list_count;i++) - if( bl_list[i]->prev || bl_list[i]->next ) - func(bl_list[i],ap); - - map_freeblock_unlock(); - - va_end(ap); - bl_list_count = blockcount; -} - -/*========================================== - * 床アイテムを消す - * - * data==0の時はtimerで消えた時 - * data!=0の時は拾う等で消えた時として動作 - * - * 後者は、map_clearflooritem(id)へ - * map.h?で#defineしてある - *------------------------------------------ - */ -int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) { - struct flooritem_data *fitem=NULL; - - fitem = (struct flooritem_data *)objects[id]; - if(fitem==NULL || fitem->bl.type!=BL_ITEM || (!data && fitem->cleartimer != tid)){ - if(battle_config.error_log) - printf("map_clearflooritem_timer : error\n"); - return 1; - } - if(data) - delete_timer(fitem->cleartimer,map_clearflooritem_timer); - else if(fitem->item_data.card[0] == (short)0xff00) - intif_delete_petdata(*((long *)(&fitem->item_data.card[1]))); - clif_clearflooritem(fitem,0); - map_delobject(fitem->bl.id); - - return 0; -} - -/*========================================== - * (m,x,y)の周?rangeマス?の空き(=侵入可能)cellの - * ?から適?なマス目の座標をx+(y<<16)で返す - * - * 現?range=1でアイテムドロップ用途のみ - *------------------------------------------ - */ -int map_searchrandfreecell(int m,int x,int y,int range) { - int free_cell,i,j; - - for(free_cell=0,i=-range;i<=range;i++){ - if(i+y<0 || i+y>=map[m].ys) - continue; - for(j=-range;j<=range;j++){ - if(j+x<0 || j+x>=map[m].xs) - continue; - if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS)) - continue; - free_cell++; - } - } - if(free_cell==0) - return -1; - free_cell=rand()%free_cell; - for(i=-range;i<=range;i++){ - if(i+y<0 || i+y>=map[m].ys) - continue; - for(j=-range;j<=range;j++){ - if(j+x<0 || j+x>=map[m].xs) - continue; - if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS)) - continue; - if(free_cell==0){ - x+=j; - y+=i; - i=range+1; - break; - } - free_cell--; - } - } - - return x+(y<<16); -} - -/*========================================== - * (m,x,y)を中心に3x3以?に床アイテム設置 - * - * item_dataはamount以外をcopyする - *------------------------------------------ - */ -int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct map_session_data *first_sd, - struct map_session_data *second_sd,struct map_session_data *third_sd,int type) { - int xy,r; - unsigned int tick; - struct flooritem_data *fitem=NULL; - - nullpo_retr(0, item_data); - - if((xy=map_searchrandfreecell(m,x,y,1))<0) - return 0; - r=rand(); - - fitem = (struct flooritem_data *)aCalloc(1,sizeof(*fitem)); - fitem->bl.type=BL_ITEM; - fitem->bl.prev = fitem->bl.next = NULL; - fitem->bl.m=m; - fitem->bl.x=xy&0xffff; - fitem->bl.y=(xy>>16)&0xffff; - fitem->first_get_id = 0; - fitem->first_get_tick = 0; - fitem->second_get_id = 0; - fitem->second_get_tick = 0; - fitem->third_get_id = 0; - fitem->third_get_tick = 0; - - fitem->bl.id = map_addobject(&fitem->bl); - if(fitem->bl.id==0){ - aFree(fitem); - return 0; - } - - tick = gettick(); - if(first_sd) { - fitem->first_get_id = first_sd->bl.id; - if(type) - fitem->first_get_tick = tick + battle_config.mvp_item_first_get_time; - else - fitem->first_get_tick = tick + battle_config.item_first_get_time; - } - if(second_sd) { - fitem->second_get_id = second_sd->bl.id; - if(type) - fitem->second_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time; - else - fitem->second_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time; - } - if(third_sd) { - fitem->third_get_id = third_sd->bl.id; - if(type) - fitem->third_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time + battle_config.mvp_item_third_get_time; - else - fitem->third_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time + battle_config.item_third_get_time; - } - - memcpy(&fitem->item_data,item_data,sizeof(*item_data)); - fitem->item_data.amount=amount; - fitem->subx=(r&3)*3+3; - fitem->suby=((r>>2)&3)*3+3; - fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0); - - map_addblock(&fitem->bl); - clif_dropflooritem(fitem); - - return fitem->bl.id; -} - -/*========================================== - * charid_dbへ追加(返信待ちがあれば返信) - *------------------------------------------ - */ -void map_addchariddb(int charid, char *name) { - struct charid2nick *p=NULL; - int req=0; - - p = (struct charid2nick*)numdb_search(charid_db,charid); - if(p==NULL){ // デ?タベ?スにない - p = (struct charid2nick *)aCallocA(1,sizeof(struct charid2nick)); - p->req_id=0; - }else - numdb_erase(charid_db,charid); - - req=p->req_id; - memcpy(p->nick,name,24); - p->req_id=0; - numdb_insert(charid_db,charid,p); - if(req){ // 返信待ちがあれば返信 - struct map_session_data *sd = map_id2sd(req); - if(sd!=NULL) - clif_solved_charname(sd,charid); - } -} - -/*========================================== - * charid_dbへ追加(返信要求のみ) - *------------------------------------------ - */ -int map_reqchariddb(struct map_session_data * sd,int charid) { - struct charid2nick *p=NULL; - - nullpo_retr(0, sd); - - p = (struct charid2nick*)numdb_search(charid_db,charid); - if(p!=NULL) // デ?タベ?スにすでにある - return 0; - p = (struct charid2nick *)aCalloc(1,sizeof(struct charid2nick)); - p->req_id=sd->bl.id; - numdb_insert(charid_db,charid,p); - return 0; -} - -/*========================================== - * id_dbへblを追加 - *------------------------------------------ - */ -void map_addiddb(struct block_list *bl) { - nullpo_retv(bl); - - numdb_insert(id_db,bl->id,bl); -} - -/*========================================== - * id_dbからblを削除 - *------------------------------------------ - */ -void map_deliddb(struct block_list *bl) { - nullpo_retv(bl); - - numdb_erase(id_db,bl->id); -} - -/*========================================== - * nick_dbへsdを追加 - *------------------------------------------ - */ -void map_addnickdb(struct map_session_data *sd) { - nullpo_retv(sd); - - strdb_insert(nick_db,sd->status.name,sd); -} - -/*========================================== - * PCのquit?理 map.c?分 - * - * quit?理の主?が違うような?もしてきた - *------------------------------------------ - */ -int map_quit(struct map_session_data *sd) { - nullpo_retr(0, sd); - - if(!sd->state.waitingdisconnect) { - if (sd->state.event_disconnect) { - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.logout_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLogoutNPC - sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.logout_event_name); - ShowStatus(tmp_output); - } - } else { - sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.logout_event_name, sd->bl.id), script_config.logout_event_name); - ShowStatus(tmp_output); - } - } - - if(sd->chatID) // チャットから出る - chat_leavechat(sd); - - if(sd->trade_partner) // 取引を中?する - trade_tradecancel(sd); - - if(sd->party_invite>0) // パ?ティ?誘を拒否する - party_reply_invite(sd,sd->party_invite_account,0); - - if(sd->guild_invite>0) // ギルド?誘を拒否する - guild_reply_invite(sd,sd->guild_invite,0); - if(sd->guild_alliance>0) // ギルド同盟?誘を拒否する - guild_reply_reqalliance(sd,sd->guild_alliance_account,0); - - party_send_logout(sd); // パ?ティのログアウトメッセ?ジ送信 - - guild_send_memberinfoshort(sd,0); // ギルドのログアウトメッセ?ジ送信 - - pc_cleareventtimer(sd); // イベントタイマを破棄する - - if(sd->state.storage_flag) - storage_guild_storage_quit(sd,0); - else - storage_storage_quit(sd); // 倉庫を開いてるなら保存する - - // check if we've been authenticated [celest] - if (sd->state.auth) - skill_castcancel(&sd->bl,0); // 詠唱を中?する - - skill_stop_dancing(&sd->bl,1);// ダンス/演奏中? - - if(sd->sc_data && sd->sc_data[SC_BERSERK].timer!=-1) //バ?サ?ク中の終了はHPを100に - sd->status.hp = 100; - - status_change_clear(&sd->bl,1); // ステ?タス異常を解除する - skill_clear_unitgroup(&sd->bl); // スキルユニットグル?プの削除 - skill_cleartimerskill(&sd->bl); - - // check if we've been authenticated [celest] - if (sd->state.auth) { - pc_stop_walking(sd,0); - pc_stopattack(sd); - pc_delinvincibletimer(sd); - } - pc_delspiritball(sd,sd->spiritball,1); - skill_gangsterparadise(sd,0); - skill_unit_move(&sd->bl,gettick(),0); - - if (sd->state.auth) - status_calc_pc(sd,4); - // skill_clear_unitgroup(&sd->bl); // [Sara-chan] - - clif_clearchar_area(&sd->bl,2); - - if(sd->status.pet_id && sd->pd) { - pet_lootitem_drop(sd->pd,sd); - pet_remove_map(sd); - if(sd->pet.intimate <= 0) { - intif_delete_petdata(sd->status.pet_id); - sd->status.pet_id = 0; - sd->pd = NULL; - sd->petDB = NULL; - } - else - intif_save_petdata(sd->status.account_id,&sd->pet); - } - - if(pc_isdead(sd)) - pc_setrestartvalue(sd,2); - - pc_clean_skilltree(sd); - pc_makesavestatus(sd); - chrif_save(sd); - storage_storage_dirty(sd); - storage_storage_save(sd); - map_delblock(&sd->bl); - } - - if( sd->npc_stackbuf && sd->npc_stackbuf != NULL) { - aFree( sd->npc_stackbuf ); - sd->npc_stackbuf = NULL; - } - - chrif_char_offline(sd); - - { - void *p = numdb_search(charid_db,sd->status.char_id); - if(p) { - numdb_erase(charid_db,sd->status.char_id); - aFree(p); - } - } - strdb_erase(nick_db,sd->status.name); - numdb_erase(charid_db,sd->status.char_id); - numdb_erase(id_db,sd->bl.id); - aFree(sd->reg); - aFree(sd->regstr); - - return 0; -} - -/*========================================== - * id番?のPCを探す。居なければNULL - *------------------------------------------ - */ -struct map_session_data * map_id2sd(int id) { -// remove search from db, because: -// 1 - all players, npc, items and mob are in this db (to search, it's not speed, and search in session is more sure) -// 2 - DB seems not always correct. Sometimes, when a player disconnects, its id (account value) is not removed and structure -// point to a memory area that is not more a session_data and value are incorrect (or out of available memory) -> crash -// replaced by searching in all session. -// by searching in session, we are sure that fd, session, and account exist. -/* - struct block_list *bl; - - bl=numdb_search(id_db,id); - if(bl && bl->type==BL_PC) - return (struct map_session_data*)bl; - return NULL; -*/ - int i; - struct map_session_data *sd; - - if (id <= 0) return 0; - - for(i = 0; i < fd_max; i++) - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->bl.id == id) - return sd; - - return NULL; -} - -/*========================================== - * char_id番?の名前を探す - *------------------------------------------ - */ -char * map_charid2nick(int id) { - struct charid2nick *p = (struct charid2nick*)numdb_search(charid_db,id); - - if(p==NULL) - return NULL; - if(p->req_id!=0) - return NULL; - return p->nick; -} - -struct map_session_data * map_charid2sd(int id) { - int i; - struct map_session_data *sd; - - if (id <= 0) return 0; - - for(i = 0; i < fd_max; i++) - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->status.char_id == id) - return sd; - - return NULL; -} - -/*========================================== - * Search session data from a nick name - * (without sensitive case if necessary) - * return map_session_data pointer or NULL - *------------------------------------------ - */ -struct map_session_data * map_nick2sd(char *nick) { - int i, quantity=0, nicklen; - struct map_session_data *sd = NULL; - struct map_session_data *pl_sd = NULL; - - if (nick == NULL) - return NULL; - - nicklen = strlen(nick); - - for (i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data*)session[i]->session_data) && pl_sd->state.auth) - // Without case sensitive check (increase the number of similar character names found) - if (strnicmp(pl_sd->status.name, nick, nicklen) == 0) { - // Strict comparison (if found, we finish the function immediatly with correct value) - if (strcmp(pl_sd->status.name, nick) == 0) - return pl_sd; - quantity++; - sd = pl_sd; - } - } - // Here, the exact character name is not found - // We return the found index of a similar account ONLY if there is 1 similar character - if (quantity == 1) - return sd; - - // Exact character name is not found and 0 or more than 1 similar characters have been found ==> we say not found - return NULL; -} - -/*========================================== - * id番?の物を探す - * 一時objectの場合は配列を引くのみ - *------------------------------------------ - */ -struct block_list * map_id2bl(int id) -{ - struct block_list *bl=NULL; - if(id >= 0 && id < sizeof(objects)/sizeof(objects[0])) - bl = objects[id]; - else - bl = (struct block_list*)numdb_search(id_db,id); - - return bl; -} - -/*========================================== - * id_db?の全てにfuncを?行 - *------------------------------------------ - */ -int map_foreachiddb(int (*func)(void*,void*,va_list),...) { - va_list ap; - - va_start(ap,func); - numdb_foreach(id_db,func,ap); - va_end(ap); - return 0; -} - -/*========================================== - * map.npcへ追加 (warp等の領域持ちのみ) - *------------------------------------------ - */ -int map_addnpc(int m,struct npc_data *nd) { - int i; - if(m<0 || m>=map_num) - return -1; - for(i=0;i<map[m].npc_num && i<MAX_NPC_PER_MAP;i++) - if(map[m].npc[i]==NULL) - break; - if(i==MAX_NPC_PER_MAP){ - if(battle_config.error_log) - printf("too many NPCs in one map %s\n",map[m].name); - return -1; - } - if(i==map[m].npc_num){ - map[m].npc_num++; - } - - nullpo_retr(0, nd); - - map[m].npc[i]=nd; - nd->n = i; - numdb_insert(id_db,nd->bl.id,nd); - - return i; -} - -void map_removenpc(void) { - int i,m,n=0; - - for(m=0;m<map_num;m++) { - for(i=0;i<map[m].npc_num && i<MAX_NPC_PER_MAP;i++) { - if(map[m].npc[i]!=NULL) { - clif_clearchar_area(&map[m].npc[i]->bl,2); - map_delblock(&map[m].npc[i]->bl); - numdb_erase(id_db,map[m].npc[i]->bl.id); - if(map[m].npc[i]->bl.subtype==SCRIPT) { - aFree(map[m].npc[i]->u.scr.script); - aFree(map[m].npc[i]->u.scr.label_list); - } - aFree(map[m].npc[i]); - map[m].npc[i] = NULL; - n++; - } - } - } - - sprintf(tmp_output,"Successfully removed and freed from memory '"CL_WHITE"%d"CL_RESET"' NPCs.\n",n); - ShowStatus(tmp_output); -} - -/*========================================== - * map名からmap番?へ?換 - *------------------------------------------ - */ -int map_mapname2mapid(char *name) { - struct map_data *md=NULL; - - md = (struct map_data*)strdb_search(map_db,name); - -#ifdef USE_AFM - // If we can't find the .gat map try .afm instead [celest] - if(md==NULL && strstr(name,".gat")) { - char *afm_name = strdup(name); - strcpy(&afm_name[strlen(name) - 3], "afm"); - md = (struct map_data*)strdb_search(map_db,afm_name); - } -#endif - - if(md==NULL || md->gat==NULL) - return -1; - return md->m; -} - -/*========================================== - * 他鯖map名からip,port?換 - *------------------------------------------ - */ -int map_mapname2ipport(char *name,int *ip,int *port) { - struct map_data_other_server *mdos=NULL; - - mdos = (struct map_data_other_server*)strdb_search(map_db,name); - if(mdos==NULL || mdos->gat) - return -1; - *ip=mdos->ip; - *port=mdos->port; - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int map_check_dir(int s_dir,int t_dir) { - if(s_dir == t_dir) - return 0; - switch(s_dir) { - case 0: - if(t_dir == 7 || t_dir == 1 || t_dir == 0) - return 0; - break; - case 1: - if(t_dir == 0 || t_dir == 2 || t_dir == 1) - return 0; - break; - case 2: - if(t_dir == 1 || t_dir == 3 || t_dir == 2) - return 0; - break; - case 3: - if(t_dir == 2 || t_dir == 4 || t_dir == 3) - return 0; - break; - case 4: - if(t_dir == 3 || t_dir == 5 || t_dir == 4) - return 0; - break; - case 5: - if(t_dir == 4 || t_dir == 6 || t_dir == 5) - return 0; - break; - case 6: - if(t_dir == 5 || t_dir == 7 || t_dir == 6) - return 0; - break; - case 7: - if(t_dir == 6 || t_dir == 0 || t_dir == 7) - return 0; - break; - } - return 1; -} - -/*========================================== - * 彼我の方向を計算 - *------------------------------------------ - */ -int map_calc_dir( struct block_list *src,int x,int y) { - int dir=0; - int dx,dy; - - nullpo_retr(0, src); - - dx=x-src->x; - dy=y-src->y; - if( dx==0 && dy==0 ){ // 彼我の場所一致 - dir=0; // 上 - }else if( dx>=0 && dy>=0 ){ // 方向的に右上 - dir=7; // 右上 - if( dx*3-1<dy ) dir=0; // 上 - if( dx>dy*3 ) dir=6; // 右 - }else if( dx>=0 && dy<=0 ){ // 方向的に右下 - dir=5; // 右下 - if( dx*3-1<-dy ) dir=4; // 下 - if( dx>-dy*3 ) dir=6; // 右 - }else if( dx<=0 && dy<=0 ){ // 方向的に左下 - dir=3; // 左下 - if( dx*3+1>dy ) dir=4; // 下 - if( dx<dy*3 ) dir=2; // 左 - }else{ // 方向的に左上 - dir=1; // 左上 - if( -dx*3-1<dy ) dir=0; // 上 - if( -dx>dy*3 ) dir=2; // 左 - } - return dir; -} - -// gat系 -/*========================================== - * (m,x,y)の状態を調べる - *------------------------------------------ - */ - -int map_getcell(int m,int x,int y,cell_t cellchk) -{ - return (m < 0 || m > MAX_MAP_PER_SERVER) ? 0 : map_getcellp(&map[m],x,y,cellchk); -} - -int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk) -{ - int type; - nullpo_ret(m); - - if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1) - { - if(cellchk==CELL_CHKNOPASS) return 1; - return 0; - } - type = m->gat[x+y*m->xs]; - if (cellchk<0x10) - type &= CELL_MASK; - - switch(cellchk) - { - case CELL_CHKPASS: - return (type!=1 && type!=5); - case CELL_CHKNOPASS: - return (type==1 || type==5); - case CELL_CHKWALL: - return (type==1); - case CELL_CHKWATER: - return (type==3); - case CELL_CHKGROUND: - return (type==5); - case CELL_GETTYPE: - return type; - case CELL_CHKNPC: - return (type&CELL_NPC); - case CELL_CHKBASILICA: - return (type&CELL_BASILICA); - default: - return 0; - } -} - -/*========================================== - * (m,x,y)の状態を設定する - *------------------------------------------ - */ -void map_setcell(int m,int x,int y,int cell) -{ - int j; - if(x<0 || x>=map[m].xs || y<0 || y>=map[m].ys) - return; - j=x+y*map[m].xs; - - switch (cell) { - case CELL_SETNPC: - map[m].gat[j] |= CELL_NPC; - break; - case CELL_SETBASILICA: - map[m].gat[j] |= CELL_BASILICA; - break; - case CELL_CLRBASILICA: - map[m].gat[j] &= ~CELL_BASILICA; - break; - default: - map[m].gat[j] = (map[m].gat[j]&~CELL_MASK) + cell; - break; - } -} - -/*========================================== - * 他鯖管理のマップをdbに追加 - *------------------------------------------ - */ -int map_setipport(char *name,unsigned long ip,int port) { - struct map_data *md=NULL; - struct map_data_other_server *mdos=NULL; - - md = (struct map_data*)strdb_search(map_db,name); - if(md==NULL){ // not exist -> add new data - mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server)); - memcpy(mdos->name,name,24); - mdos->gat = NULL; - mdos->ip = ip; - mdos->port = port; - mdos->map = NULL; - strdb_insert(map_db,mdos->name,mdos); - } else if(md->gat){ - if(ip!=clif_getip() || port!=clif_getport()){ - // 読み込んでいたけど、担当外になったマップ - mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server)); - memcpy(mdos->name,name,24); - mdos->gat = NULL; - mdos->ip = ip; - mdos->port = port; - mdos->map = md; - strdb_insert(map_db,mdos->name,mdos); - // printf("from char server : %s -> %08lx:%d\n",name,ip,port); - } else { - // 読み込んでいて、担当になったマップ(何もしない) - ; - } - } else { - mdos=(struct map_data_other_server *)md; - if(ip == clif_getip() && port == clif_getport()) { - // 自分の担当になったマップ - if(mdos->map == NULL) { - // 読み込んでいないので終了する - printf("map_setipport : %s is not loaded.\n",name); - exit(1); - } else { - // 読み込んでいるので置き換える - md = mdos->map; - aFree(mdos); - strdb_insert(map_db,md->name,md); - } - } else { - // 他の鯖の担当マップなので置き換えるだけ - mdos->ip = ip; - mdos->port = port; - } - } - return 0; -} - -/*========================================== - * 他鯖管理のマップを全て削除 - *------------------------------------------ - */ -int map_eraseallipport_sub(void *key,void *data,va_list va) { - struct map_data_other_server *mdos = (struct map_data_other_server*)data; - if(mdos->gat == NULL && mdos->map == NULL) { - strdb_erase(map_db,key); - aFree(mdos); - } - return 0; -} - -int map_eraseallipport(void) { - strdb_foreach(map_db,map_eraseallipport_sub); - return 1; -} - -/*========================================== - * 他鯖管理のマップをdbから削除 - *------------------------------------------ - */ -int map_eraseipport(char *name,unsigned long ip,int port) -{ - struct map_data *md; - struct map_data_other_server *mdos; -// unsigned char *p=(unsigned char *)&ip; - - md=(struct map_data *) strdb_search(map_db,name); - if(md){ - if(md->gat) // local -> check data - return 0; - else { - mdos=(struct map_data_other_server *)md; - if(mdos->ip==ip && mdos->port == port) { - if(mdos->map) { - // このマップ鯖でも読み込んでいるので移動できる - return 1; // 呼び出し元で chrif_sendmap() をする - } else { - strdb_erase(map_db,name); - aFree(mdos); - } -// if(battle_config.etc_log) -// printf("erase map %s %d.%d.%d.%d:%d\n",name,p[0],p[1],p[2],p[3],port); - } - } - } - return 0; -} - -// 初期化周り -/*========================================== - * 水場高さ設定 - *------------------------------------------ - */ -static struct waterlist_ { - char mapname[24]; - int waterheight; -} *waterlist=NULL; - -#define NO_WATER 1000000 - -static int map_waterheight(char *mapname) { - if(waterlist){ - int i; - for(i=0;waterlist[i].mapname[0] && i < MAX_MAP_PER_SERVER;i++) - if(strcmp(waterlist[i].mapname,mapname)==0) - return waterlist[i].waterheight; - } - return NO_WATER; -} - -static void map_readwater(char *watertxt) { - char line[1024],w1[1024]; - FILE *fp=NULL; - int n=0; - - fp=fopen(watertxt,"r"); - if(fp==NULL){ - printf("file not found: %s\n",watertxt); - return; - } - if(waterlist==NULL) - waterlist = (struct waterlist_*)aCallocA(MAX_MAP_PER_SERVER,sizeof(*waterlist)); - while(fgets(line,1020,fp) && n < MAX_MAP_PER_SERVER){ - int wh,count; - if(line[0] == '/' && line[1] == '/') - continue; - if((count=sscanf(line,"%s%d",w1,&wh)) < 1){ - continue; - } - strcpy(waterlist[n].mapname,w1); - if(count >= 2) - waterlist[n].waterheight = wh; - else - waterlist[n].waterheight = 3; - n++; - } - fclose(fp); -} -/*========================================== -* マップキャッシュに追加する -*===========================================*/ - -// マップキャッシュの最大値 -#define MAX_MAP_CACHE 768 - -//各マップごとの最小限情報を入れるもの、READ_FROM_BITMAP用 -struct map_cache_info { - char fn[32];//ファイル名 - int xs,ys; //幅と高さ - int water_height; - int pos; // データが入れてある場所 - int compressed; // zilb通せるようにする為の予約 - int compressed_len; // zilb通せるようにする為の予約 -}; // 56 byte - -struct map_cache_head { - int sizeof_header; - int sizeof_map; - // 上の2つ改変不可 - int nmaps; // マップの個数 - int filesize; -}; - -struct { - struct map_cache_head head; - struct map_cache_info *map; - FILE *fp; - int dirty; -} map_cache; - -static int map_cache_open(char *fn); -static void map_cache_close(void); -static int map_cache_read(struct map_data *m); -static int map_cache_write(struct map_data *m); - -static int map_cache_open(char *fn) -{ - atexit(map_cache_close); - if(map_cache.fp) { - map_cache_close(); - } - map_cache.fp = fopen(fn,"r+b"); - if(map_cache.fp) { - fread(&map_cache.head,1,sizeof(struct map_cache_head),map_cache.fp); - fseek(map_cache.fp,0,SEEK_END); - if( - map_cache.head.sizeof_header == sizeof(struct map_cache_head) && - map_cache.head.sizeof_map == sizeof(struct map_cache_info) && - map_cache.head.nmaps == MAX_MAP_CACHE && - map_cache.head.filesize == ftell(map_cache.fp) - ) { - // キャッシュ読み込み成功 - map_cache.map = (struct map_cache_info *) aMalloc(sizeof(struct map_cache_info) * map_cache.head.nmaps); - fseek(map_cache.fp,sizeof(struct map_cache_head),SEEK_SET); - fread(map_cache.map,sizeof(struct map_cache_info),map_cache.head.nmaps,map_cache.fp); - return 1; - } - fclose(map_cache.fp); - } - // 読み込みに失敗したので新規に作成する - map_cache.fp = fopen(fn,"wb"); - if(map_cache.fp) { - memset(&map_cache.head,0,sizeof(struct map_cache_head)); - map_cache.map = (struct map_cache_info *) aCalloc(sizeof(struct map_cache_info),MAX_MAP_CACHE); - map_cache.head.nmaps = MAX_MAP_CACHE; - map_cache.head.sizeof_header = sizeof(struct map_cache_head); - map_cache.head.sizeof_map = sizeof(struct map_cache_info); - - map_cache.head.filesize = sizeof(struct map_cache_head); - map_cache.head.filesize += sizeof(struct map_cache_info) * map_cache.head.nmaps; - - map_cache.dirty = 1; - return 1; - } - return 0; -} - -static void map_cache_close(void) -{ - if(!map_cache.fp) { return; } - if(map_cache.dirty) { - fseek(map_cache.fp,0,SEEK_SET); - fwrite(&map_cache.head,1,sizeof(struct map_cache_head),map_cache.fp); - fwrite(map_cache.map,map_cache.head.nmaps,sizeof(struct map_cache_info),map_cache.fp); - } - fclose(map_cache.fp); - aFree(map_cache.map); - map_cache.fp = NULL; - return; -} - -int map_cache_read(struct map_data *m) -{ - int i; - if(!map_cache.fp) { return 0; } - for(i = 0;i < map_cache.head.nmaps ; i++) { - if(!strcmp(m->name,map_cache.map[i].fn)) { - if(map_cache.map[i].water_height != map_waterheight(m->name)) { - // 水場の高さが違うので読み直し - return 0; - } else if(map_cache.map[i].compressed == 0) { - // 非圧縮ファイル - int size = map_cache.map[i].xs * map_cache.map[i].ys; - m->xs = map_cache.map[i].xs; - m->ys = map_cache.map[i].ys; - m->gat = (unsigned char *)aCalloc(m->xs * m->ys,sizeof(unsigned char)); - fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET); - if(fread(m->gat,1,size,map_cache.fp) == size) { - // 成功 - return 1; - } else { - // なぜかファイル後半が欠けてるので読み直し - m->xs = 0; m->ys = 0; m->gat = NULL; aFree(m->gat); - return 0; - } - } else if(map_cache.map[i].compressed == 1) { - // 圧縮フラグ=1 : zlib - unsigned char *buf; - unsigned long dest_len; - int size_compress = map_cache.map[i].compressed_len; - m->xs = map_cache.map[i].xs; - m->ys = map_cache.map[i].ys; - m->gat = (unsigned char *)aMalloc(m->xs * m->ys * sizeof(unsigned char)); - buf = (unsigned char*)aMalloc(size_compress); - fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET); - if(fread(buf,1,size_compress,map_cache.fp) != size_compress) { - // なぜかファイル後半が欠けてるので読み直し - printf("fread error\n"); - aFree(m->gat); m->xs = 0; m->ys = 0; m->gat = NULL; - aFree(buf); - return 0; - } - dest_len = m->xs * m->ys; - decode_zip(m->gat,&dest_len,buf,size_compress); - if(dest_len != map_cache.map[i].xs * map_cache.map[i].ys) { - // 正常に解凍が出来てない - aFree(m->gat); m->xs = 0; m->ys = 0; m->gat = NULL; - aFree(buf); - return 0; - } - aFree(buf); - return 1; - } - } - } - return 0; -} - -static int map_cache_write(struct map_data *m) -{ - int i; - unsigned long len_new , len_old; - char *write_buf; - if(!map_cache.fp) { return 0; } - for(i = 0;i < map_cache.head.nmaps ; i++) { - if(!strcmp(m->name,map_cache.map[i].fn)) { - // 同じエントリーがあれば上書き - if(map_cache.map[i].compressed == 0) { - len_old = map_cache.map[i].xs * map_cache.map[i].ys; - } else if(map_cache.map[i].compressed == 1) { - len_old = map_cache.map[i].compressed_len; - } else { - // サポートされてない形式なので長さ0 - len_old = 0; - } - if(map_read_flag == 2) { - // 圧縮保存 - // さすがに2倍に膨れる事はないという事で - write_buf = (char *) aMalloc(m->xs * m->ys * 2); - len_new = m->xs * m->ys * 2; - encode_zip((unsigned char *) write_buf,&len_new,m->gat,m->xs * m->ys); - map_cache.map[i].compressed = 1; - map_cache.map[i].compressed_len = len_new; - } else { - len_new = m->xs * m->ys; - write_buf = (char *) m->gat; - map_cache.map[i].compressed = 0; - map_cache.map[i].compressed_len = 0; - } - if(len_new <= len_old) { - // サイズが同じか小さくなったので場所は変わらない - fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET); - fwrite(write_buf,1,len_new,map_cache.fp); - } else { - // 新しい場所に登録 - fseek(map_cache.fp,map_cache.head.filesize,SEEK_SET); - fwrite(write_buf,1,len_new,map_cache.fp); - map_cache.map[i].pos = map_cache.head.filesize; - map_cache.head.filesize += len_new; - } - map_cache.map[i].xs = m->xs; - map_cache.map[i].ys = m->ys; - map_cache.map[i].water_height = map_waterheight(m->name); - map_cache.dirty = 1; - if(map_read_flag == 2) { - aFree(write_buf); - } - return 0; - } - } - // 同じエントリが無ければ書き込める場所を探す - for(i = 0;i < map_cache.head.nmaps ; i++) { - if(map_cache.map[i].fn[0] == 0) { - // 新しい場所に登録 - if(map_read_flag == 2) { - write_buf = (char *) aMalloc(m->xs * m->ys * 2); - len_new = m->xs * m->ys * 2; - encode_zip((unsigned char *) write_buf,&len_new,m->gat,m->xs * m->ys); - map_cache.map[i].compressed = 1; - map_cache.map[i].compressed_len = len_new; - } else { - len_new = m->xs * m->ys; - write_buf = (char *) m->gat; - map_cache.map[i].compressed = 0; - map_cache.map[i].compressed_len = 0; - } - strncpy(map_cache.map[i].fn,m->name,sizeof(map_cache.map[0].fn)); - fseek(map_cache.fp,map_cache.head.filesize,SEEK_SET); - fwrite(write_buf,1,len_new,map_cache.fp); - map_cache.map[i].pos = map_cache.head.filesize; - map_cache.map[i].xs = m->xs; - map_cache.map[i].ys = m->ys; - map_cache.map[i].water_height = map_waterheight(m->name); - map_cache.head.filesize += len_new; - map_cache.dirty = 1; - if(map_read_flag == 2) { - aFree(write_buf); - } - return 0; - } - } - // 書き込めなかった - return 1; -} - -#ifdef USE_AFM -static int map_readafm(int m,char *fn) { - - /* - Advanced Fusion Maps Support - (c) 2003-2004, The Fusion Project - - AlexKreuz - - The following code has been provided by me for eAthena - under the GNU GPL. It provides Advanced Fusion - Map, the map format desgined by me for Fusion, support - for the eAthena emulator. - - I understand that because it is under the GPL - that other emulators may very well use this code in their - GNU project as well. - - The AFM map format was not originally a part of the GNU - GPL. It originated from scratch by my own hand. I understand - that distributing this code to read the AFM maps with eAthena - causes the GPL to apply to this code. But the actual AFM - maps are STILL copyrighted to the Fusion Project. By choosing - - In exchange for that 'act of faith' I ask for the following. - - A) Give credit where it is due. If you use this code, do not - place your name on the changelog. Credit should be given - to AlexKreuz. - B) As an act of courtesy, ask me and let me know that you are putting - AFM support in your project. You will have my blessings if you do. - C) Use the code in its entirety INCLUDING the copyright message. - Although the code provided may now be GPL, the AFM maps are not - and so I ask you to display the copyright message on the STARTUP - SCREEN as I have done here. (refer to core.c) - "Advanced Fusion Maps (c) 2003-2004 The Fusion Project" - - Without this copyright, you are NOT entitled to bundle or distribute - the AFM maps at all. On top of that, your "support" for AFM maps - becomes just as shady as your "support" for Gravity GRF files. - - The bottom line is this. I know that there are those of you who - would like to use this code but aren't going to want to provide the - proper credit. I know this because I speak frome experience. If - you are one of those people who is going to try to get around my - requests, then save your breath because I don't want to hear it. - - I have zero faith in GPL and I know and accept that if you choose to - not display the copyright for the AFMs then there is absolutely nothing - I can do about it. I am not about to start a legal battle over something - this silly. - - Provide the proper credit because you believe in the GPL. If you choose - not to and would rather argue about it, consider the GPL failed. - - October 18th, 2004 - - AlexKreuz - - The Fusion Project - */ - - - int s; - int x,y,xs,ys; - size_t size; - - char afm_line[65535]; - int afm_size[2]; - FILE *afm_file; - char *str; - - afm_file = fopen(fn, "r"); - if (afm_file != NULL) { - -// printf("\rLoading Maps [%d/%d]: %-50s ",m,map_num,fn); -// fflush(stdout); - - str=fgets(afm_line, sizeof(afm_line)-1, afm_file); - str=fgets(afm_line, sizeof(afm_line)-1, afm_file); - str=fgets(afm_line, sizeof(afm_line)-1, afm_file); - sscanf(str , "%d%d", &afm_size[0], &afm_size[1]); - - map[m].m = m; - xs = map[m].xs = afm_size[0]; - ys = map[m].ys = afm_size[1]; - // check this, unsigned where it might not need to be - map[m].gat = (unsigned char*)aCallocA(s = map[m].xs * map[m].ys, 1); - - if(map[m].gat==NULL){ - printf("out of memory : map_readmap gat\n"); - exit(1); - } - - map[m].npc_num=0; - map[m].users=0; - memset(&map[m].flag,0,sizeof(map[m].flag)); - - if(battle_config.pk_mode) map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris] - - for (y = 0; y < ys; y++) { - str=fgets(afm_line, sizeof(afm_line)-1, afm_file); - for (x = 0; x < xs; x++) { - map[m].gat[x+y*xs] = str[x]-48; - } - } - - map[m].bxs=(xs+BLOCK_SIZE-1)/BLOCK_SIZE; - map[m].bys=(ys+BLOCK_SIZE-1)/BLOCK_SIZE; - size = map[m].bxs * map[m].bys * sizeof(struct block_list*); - map[m].block = (struct block_list**)aCalloc(size, 1); - - if(map[m].block == NULL){ - printf("out of memory : map_readmap block\n"); - exit(1); - } - - map[m].block_mob = (struct block_list**)aCalloc(size, 1); - if (map[m].block_mob == NULL) { - printf("out of memory : map_readmap block_mob\n"); - exit(1); - } - - size = map[m].bxs*map[m].bys*sizeof(int); - - map[m].block_count = (int*)aCallocA(size, 1); - if(map[m].block_count==NULL){ - printf("out of memory : map_readmap block\n"); - exit(1); - } - memset(map[m].block_count,0,size); - - map[m].block_mob_count = (int*)aCallocA(size, 1); - if(map[m].block_mob_count==NULL){ - printf("out of memory : map_readmap block_mob\n"); - exit(1); - } - memset(map[m].block_mob_count,0,size); - - strdb_insert(map_db,map[m].name,&map[m]); - - fclose(afm_file); - - } - - return 0; -} -#endif - -/*========================================== - * マップ1枚読み込み - * ===================================================*/ -static int map_readmap(int m,char *fn, char *alias, int *map_cache, int maxmap) { - char *gat=""; - size_t size; - - int i = 0; - int e = 0; - char progress[21] = " "; - - //printf("\rLoading Maps [%d/%d]: %-50s ",m,map_num,fn); - if (maxmap) { //avoid map-server crashing if there are 0 maps - char c = '-'; - static int lasti = -1; - static int last_time = -1; - i=m*20/maxmap; - if ((i != lasti) || (last_time != time(0))) { - lasti = i; - printf("\r"); - ShowStatus("Progress: "); - printf("["); - for (e=0;e<i;e++) progress[e] = '#'; - printf(progress); - printf("] Working: ["); - last_time = time(0); - switch(last_time % 4) { - case 0: c='\\'; break; - case 1: c='|'; break; - case 2: c='/'; break; - case 3: c='-'; break; - } - printf("%c]",c); - fflush(stdout); - } - } - - if(map_cache_read(&map[m])) { - // キャッシュから読み込めた - (*map_cache)++; - } else { - int s; - int wh; - int x,y,xs,ys; - struct gat_1cell {float high[4]; int type;} *p=NULL; - // read & convert fn - // again, might not need to be unsigned char - gat = (char*)grfio_read(fn); - if(gat==NULL) { - return -1; - // さすがにマップが読めないのはまずいので終了する - //printf("Can't load map %s\n",fn); - //exit(1); - } - - xs=map[m].xs=*(int*)(gat+6); - ys=map[m].ys=*(int*)(gat+10); - map[m].gat = (unsigned char *)aCallocA(s = map[m].xs * map[m].ys,sizeof(unsigned char)); - wh=map_waterheight(map[m].name); - for(y=0;y<ys;y++){ - p=(struct gat_1cell*)(gat+y*xs*20+14); - for(x=0;x<xs;x++){ - if(wh!=NO_WATER && p->type==0){ - // 水場判定 - map[m].gat[x+y*xs]=(p->high[0]>wh || p->high[1]>wh || p->high[2]>wh || p->high[3]>wh) ? 3 : 0; - } else { - map[m].gat[x+y*xs]=p->type; - } - p++; - } - } - map_cache_write(&map[m]); - aFree(gat); - } - - map[m].m=m; - map[m].npc_num=0; - map[m].users=0; - memset(&map[m].flag,0,sizeof(map[m].flag)); - if(battle_config.pk_mode) - map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris] - map[m].bxs=(map[m].xs+BLOCK_SIZE-1)/BLOCK_SIZE; - map[m].bys=(map[m].ys+BLOCK_SIZE-1)/BLOCK_SIZE; - size = map[m].bxs * map[m].bys * sizeof(struct block_list*); - map[m].block = (struct block_list **)aCalloc(1,size); - map[m].block_mob = (struct block_list **)aCalloc(1,size); - size = map[m].bxs*map[m].bys*sizeof(int); - map[m].block_count = (int *)aCallocA(1,size); - map[m].block_mob_count=(int *)aCallocA(1,size); - if (alias) - strdb_insert(map_db,alias,&map[m]); - else - strdb_insert(map_db,map[m].name,&map[m]); - -// printf("%s read done\n",fn); - - return 0; -} - -/*========================================== - * 全てのmapデ?タを?み?む - *------------------------------------------ - */ -int map_readallmap(void) { - int i,maps_removed=0; - char fn[256]; -#ifdef USE_AFM - FILE *afm_file; -#endif - int map_cache = 0; - - // マップキャッシュを開く - if(map_read_flag >= READ_FROM_BITMAP) { - map_cache_open(map_cache_file); - } - - sprintf(tmp_output, "Loading Maps%s...\n", - (map_read_flag == CREATE_BITMAP_COMPRESSED ? " (Generating Map Cache w/ Compression)" : - map_read_flag == CREATE_BITMAP ? " (Generating Map Cache)" : - map_read_flag >= READ_FROM_BITMAP ? " (w/ Map Cache)" : - map_read_flag == READ_FROM_AFM ? " (w/ AFM)" : "")); - ShowStatus(tmp_output); - - // 先に全部のャbプの存在を確認 - for(i=0;i<map_num;i++){ - -#ifdef USE_AFM - char afm_name[256] = ""; - char *p; - if(!strstr(map[i].name,".afm")) { - // check if it's necessary to replace the extension - speeds up loading abit - strncpy(afm_name, map[i].name, strlen(map[i].name) - 4); - strcat(afm_name, ".afm"); - } - map[i].alias = NULL; - sprintf(fn,"%s\\%s",afm_dir,afm_name); - for(p=&fn[0];*p!=0;p++) if (*p=='\\') *p = '/'; // * At the time of Unix - - afm_file = fopen(fn, "r"); - if (afm_file != NULL) { - map_readafm(i,fn); - fclose(afm_file); - } - else if(strstr(map[i].name,".gat")!=NULL) { -#else - if(strstr(map[i].name,".gat")!=NULL) { -#endif - char *p = strstr(map[i].name, "<"); // [MouseJstr] - if (p != NULL) { - char buf[64]; - *p++ = '\0'; - sprintf(buf,"data\\%s", p); - map[i].alias = aStrdup(buf); - } else - map[i].alias = NULL; - - sprintf(fn,"data\\%s",map[i].name); - if(map_readmap(i,fn, p, &map_cache, map_num) == -1) { - map_delmap(map[i].name); - maps_removed++; - i--; - } - } - } - - aFree(waterlist); - printf("\r"); - snprintf(tmp_output,sizeof(tmp_output),"Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps.%30s\n",map_num,""); - ShowInfo(tmp_output); - - map_cache_close(); - if(map_read_flag == CREATE_BITMAP || map_read_flag == CREATE_BITMAP_COMPRESSED) { - --map_read_flag; - } - - if (maps_removed) { - snprintf(tmp_output,sizeof(tmp_output),"Maps Removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed); - ShowNotice(tmp_output); - } - return 0; -} - -/*========================================== - * ?み?むmapを追加する - *------------------------------------------ - */ -int map_addmap(char *mapname) { - if (strcmpi(mapname,"clear")==0) { - map_num=0; - return 0; - } - - if (map_num >= MAX_MAP_PER_SERVER - 1) { - snprintf(tmp_output,sizeof(tmp_output),"Could not add map '" - CL_WHITE"%s"CL_RESET"', the limit of maps has been reached.\n",mapname); - ShowError(tmp_output); - return 1; - } - memcpy(map[map_num].name, mapname, 24); - map_num++; - return 0; -} - -/*========================================== - * ?み?むmapを削除する - *------------------------------------------ - */ -int map_delmap(char *mapname) { - - int i; - - if (strcmpi(mapname, "all") == 0) { - map_num = 0; - return 0; - } - - for(i = 0; i < map_num; i++) { - if (strcmp(map[i].name, mapname) == 0) { - printf("Removing map [ %s ] from maplist\n",map[i].name); - memmove(map+i, map+i+1, sizeof(map[0])*(map_num-i-1)); - map_num--; - } - } - return 0; -} - -static int map_ip_set_ = 0; -static int char_ip_set_ = 0; -//static int bind_ip_set_ = 0; - -/*========================================== - * Console Command Parser [Wizputer] - *------------------------------------------ - */ -int parse_console(char *buf) { - char *type,*command,*map, *buf2; - int x = 0, y = 0; - int m, n; - struct map_session_data *sd; - - sd = (struct map_session_data*)aCalloc(sizeof(*sd), 1); - - sd->fd = 0; - strcpy( sd->status.name , "console"); - - type = (char *)aMallocA(64); - command = (char *)aMallocA(64); - map = (char *)aMallocA(64); - buf2 = (char *)aMallocA(72); - - memset(type,0,64); - memset(command,0,64); - memset(map,0,64); - memset(buf2,0,72); - - if ( ( n = sscanf(buf, "%[^:]:%[^:]:%99s %d %d[^\n]", type , command , map , &x , &y )) < 5 ) - if ( ( n = sscanf(buf, "%[^:]:%[^\n]", type , command )) < 2 ) - n = sscanf(buf,"%[^\n]",type); - - if ( n == 5 ) { - if (x <= 0) { - x = rand() % 399 + 1; - sd->bl.x = x; - } else { - sd->bl.x = x; - } - - if (y <= 0) { - y = rand() % 399 + 1; - sd->bl.y = y; - } else { - sd->bl.y = y; - } - - m = map_mapname2mapid(map); - if ( m >= 0 ) - sd->bl.m = m; - else { - printf("Console: Unknown map\n"); - goto end; - } - } - - printf("Type of command: %s || Command: %s || Map: %s Coords: %d %d\n",type,command,map,x,y); - - if ( strcmpi("admin",type) == 0 && n == 5 ) { - sprintf(buf2,"console: %s",command); - if( is_atcommand(sd->fd,sd,buf2,99) == AtCommand_None ) - printf("Console: not atcommand\n"); - } else if ( strcmpi("server",type) == 0 && n == 2 ) { - if ( strcmpi("shutdown", command) == 0 || strcmpi("exit",command) == 0 || strcmpi("quit",command) == 0 ) { - exit(0); - } - } else if ( strcmpi("help",type) == 0 ) { - printf("To use GM commands:\n"); - printf("admin:<gm command>:<map of \"gm\"> <x> <y>\n"); - printf("You can use any GM command that doesn't require the GM.\n"); - printf("No using @item or @warp however you can use @charwarp\n"); - printf("The <map of \"gm\"> <x> <y> is for commands that need coords of the GM\n"); - printf("IE: @spawn\n"); - printf("To shutdown the server:\n"); - printf("server:shutdown\n"); - } - - end: - aFree(buf); - aFree(type); - aFree(command); - aFree(map); - aFree(buf2); - aFree(sd); - - return 0; -} - -/*========================================== - * 設定ファイルを?み?む - *------------------------------------------ - */ -int map_config_read(char *cfgName) { - char line[1024], w1[1024], w2[1024]; - FILE *fp; - struct hostent *h = NULL; - - fp = fopen(cfgName,"r"); - if (fp == NULL) { - printf("Map configuration file not found at: %s\n", cfgName); - exit(1); - } - while(fgets(line, sizeof(line) -1, fp)) { - if (line[0] == '/' && line[1] == '/') - continue; - if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) { - if (strcmpi(w1, "userid")==0){ - chrif_setuserid(w2); - } else if (strcmpi(w1, "passwd") == 0) { - chrif_setpasswd(w2); - } else if (strcmpi(w1, "char_ip") == 0) { - char_ip_set_ = 1; - h = gethostbyname (w2); - if(h != NULL) { - snprintf(tmp_output,sizeof(tmp_output),"Char Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - ShowInfo(tmp_output); - sprintf(w2,"%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - } - chrif_setip(w2); - } else if (strcmpi(w1, "char_port") == 0) { - chrif_setport(atoi(w2)); - } else if (strcmpi(w1, "map_ip") == 0) { - map_ip_set_ = 1; - h = gethostbyname (w2); - if (h != NULL) { - snprintf(tmp_output,sizeof(tmp_output),"Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - ShowInfo(tmp_output); - sprintf(w2, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - } - clif_setip(w2); - } else if (strcmpi(w1, "bind_ip") == 0) { - //bind_ip_set_ = 1; - h = gethostbyname (w2); - if (h != NULL) { - snprintf(tmp_output,sizeof(tmp_output),"Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - ShowInfo(tmp_output); - sprintf(w2, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - } - clif_setbindip(w2); - } else if (strcmpi(w1, "map_port") == 0) { - clif_setport(atoi(w2)); - map_port = (atoi(w2)); - } else if (strcmpi(w1, "water_height") == 0) { - map_readwater(w2); - } else if (strcmpi(w1, "map") == 0) { - map_addmap(w2); - } else if (strcmpi(w1, "delmap") == 0) { - map_delmap(w2); - } else if (strcmpi(w1, "npc") == 0) { - npc_addsrcfile(w2); - } else if (strcmpi(w1, "delnpc") == 0) { - npc_delsrcfile(w2); - } else if (strcmpi(w1, "data_grf") == 0) { - grfio_setdatafile(w2); - } else if (strcmpi(w1, "sdata_grf") == 0) { - grfio_setsdatafile(w2); - } else if (strcmpi(w1, "adata_grf") == 0) { - grfio_setadatafile(w2); - } else if (strcmpi(w1, "autosave_time") == 0) { - autosave_interval = atoi(w2) * 1000; - if (autosave_interval <= 0) - autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; - } else if (strcmpi(w1, "motd_txt") == 0) { - strcpy(motd_txt, w2); - } else if (strcmpi(w1, "help_txt") == 0) { - strcpy(help_txt, w2); - } else if (strcmpi(w1, "mapreg_txt") == 0) { - strcpy(mapreg_txt, w2); - }else if(strcmpi(w1,"read_map_from_cache")==0){ - if (atoi(w2) == 2) - map_read_flag = READ_FROM_BITMAP_COMPRESSED; - else if (atoi(w2) == 1) - map_read_flag = READ_FROM_BITMAP; - else - map_read_flag = READ_FROM_GAT; - }else if(strcmpi(w1,"map_cache_file")==0){ - strncpy(map_cache_file,w2,255); - } else if (strcmpi(w1, "import") == 0) { - map_config_read(w2); - } else if (strcmpi(w1, "console") == 0) { - if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 ) { - console = 1; - ShowNotice("Console Commands is enabled.\n"); - } - } else if(strcmpi(w1,"imalive_on")==0){ //Added by Mugendai for I'm Alive mod - imalive_on = atoi(w2); //Added by Mugendai for I'm Alive mod - } else if(strcmpi(w1,"imalive_time")==0){ //Added by Mugendai for I'm Alive mod - imalive_time = atoi(w2); //Added by Mugendai for I'm Alive mod - } else if(strcmpi(w1,"flush_on")==0){ //Added by Mugendai for GUI - flush_on = atoi(w2); //Added by Mugendai for GUI - } else if(strcmpi(w1,"flush_time")==0){ //Added by Mugendai for GUI - flush_time = atoi(w2); //Added by Mugendai for GUI - } - - } - } - fclose(fp); - - return 0; -} - -int inter_config_read(char *cfgName) -{ - int i; - char line[1024],w1[1024],w2[1024]; - FILE *fp; - - fp=fopen(cfgName,"r"); - if(fp==NULL){ - snprintf(tmp_output,sizeof(tmp_output),"File not found: '%s'.\n",cfgName); - ShowError(tmp_output); - return 1; - } - while(fgets(line,1020,fp)){ - if(line[0] == '/' && line[1] == '/') - continue; - i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2); - if(i!=2) - continue; - //support the import command, just like any other config - if(strcmpi(w1,"import")==0){ - inter_config_read(w2); - #ifndef TXT_ONLY - } else if(strcmpi(w1,"item_db_db")==0){ - strcpy(item_db_db,w2); - } else if(strcmpi(w1,"mob_db_db")==0){ - strcpy(mob_db_db,w2); - } else if(strcmpi(w1,"login_db_level")==0){ - strcpy(login_db_level,w2); - } else if(strcmpi(w1,"login_db_account_id")==0){ - strcpy(login_db_account_id,w2); - } else if(strcmpi(w1,"login_db")==0){ - strcpy(login_db,w2); - } else if (strcmpi(w1, "char_db") == 0) { - strcpy(char_db, w2); - } else if(strcmpi(w1,"gm_db_level")==0){ - strcpy(gm_db_level,w2); - } else if(strcmpi(w1,"gm_db_account_id")==0){ - strcpy(gm_db_account_id,w2); - } else if(strcmpi(w1,"gm_db")==0){ - strcpy(gm_db,w2); - //Map Server SQL DB - } else if(strcmpi(w1,"map_server_ip")==0){ - strcpy(map_server_ip, w2); - } else if(strcmpi(w1,"map_server_port")==0){ - map_server_port=atoi(w2); - } else if(strcmpi(w1,"map_server_id")==0){ - strcpy(map_server_id, w2); - } else if(strcmpi(w1,"map_server_pw")==0){ - strcpy(map_server_pw, w2); - } else if(strcmpi(w1,"map_server_db")==0){ - strcpy(map_server_db, w2); - } else if(strcmpi(w1,"use_sql_db")==0){ - db_use_sqldbs = battle_config_switch(w2); - printf ("Using SQL dbs: %s\n",w2); - //Login Server SQL DB - } else if(strcmpi(w1,"login_server_ip")==0){ - strcpy(login_server_ip, w2); - } else if(strcmpi(w1,"login_server_port")==0){ - login_server_port = atoi(w2); - } else if(strcmpi(w1,"login_server_id")==0){ - strcpy(login_server_id, w2); - } else if(strcmpi(w1,"login_server_pw")==0){ - strcpy(login_server_pw, w2); - } else if(strcmpi(w1,"login_server_db")==0){ - strcpy(login_server_db, w2); - } else if(strcmpi(w1,"lowest_gm_level")==0){ - lowest_gm_level = atoi(w2); - } else if(strcmpi(w1,"read_gm_interval")==0){ - read_gm_interval = ( atoi(w2) * 60 * 1000 ); // Minutes multiplied by 60 secs per min by 1000 milliseconds per second - } else if(strcmpi(w1,"log_db")==0) { - strcpy(log_db, w2); - } else if(strcmpi(w1,"log_db_ip")==0) { - strcpy(log_db_ip, w2); - } else if(strcmpi(w1,"log_db")==0) { - strcpy(log_db, w2); - } else if(strcmpi(w1,"log_db_id")==0) { - strcpy(log_db_id, w2); - } else if(strcmpi(w1,"log_db_pw")==0) { - strcpy(log_db_pw, w2); - } else if(strcmpi(w1,"log_db_port")==0) { - log_db_port = atoi(w2); - #endif - } - } - fclose(fp); - - return 0; -} - -#ifndef TXT_ONLY -/*======================================= - * MySQL Init - *--------------------------------------- - */ - -int map_sql_init(void){ - - mysql_init(&mmysql_handle); - - //DB connection start - printf("Connect Map DB Server....\n"); - if(!mysql_real_connect(&mmysql_handle, map_server_ip, map_server_id, map_server_pw, - map_server_db ,map_server_port, (char *)NULL, 0)) { - //pointer check - printf("%s\n",mysql_error(&mmysql_handle)); - exit(1); - } - else { - printf ("connect success! (Map Server Connection)\n"); - } - - mysql_init(&lmysql_handle); - - //DB connection start - printf("Connect Login DB Server....\n"); - if(!mysql_real_connect(&lmysql_handle, login_server_ip, login_server_id, login_server_pw, - login_server_db ,login_server_port, (char *)NULL, 0)) { - //pointer check - printf("%s\n",mysql_error(&lmysql_handle)); - exit(1); - } - else { - printf ("connect success! (Login Server Connection)\n"); - } - - if(battle_config.mail_system) { // mail system [Valaris] - mysql_init(&mail_handle); - if(!mysql_real_connect(&mail_handle, map_server_ip, map_server_id, map_server_pw, - map_server_db ,map_server_port, (char *)NULL, 0)) { - printf("%s\n",mysql_error(&mail_handle)); - exit(1); - } - } - - return 0; -} - -int map_sql_close(void){ - mysql_close(&mmysql_handle); - printf("Close Map DB Connection....\n"); - - mysql_close(&lmysql_handle); - printf("Close Login DB Connection....\n"); - return 0; -} - -int log_sql_init(void){ - - mysql_init(&mmysql_handle); - - //DB connection start - printf(""CL_WHITE"[SQL]"CL_RESET": Connecting to Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db,log_db_ip); - if(!mysql_real_connect(&mmysql_handle, log_db_ip, log_db_id, log_db_pw, - log_db ,log_db_port, (char *)NULL, 0)) { - //pointer check - printf(""CL_WHITE"[SQL Error]"CL_RESET": %s\n",mysql_error(&mmysql_handle)); - exit(1); - } else { - printf(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db); - } - - return 0; -} - -int online_timer (int tid,unsigned int tick,int id,int data) -{ - char_online_check(); - return 0; -} -void char_online_check(void) -{ - int i; - struct map_session_data *sd; - - chrif_char_reset_offline(); - - for (i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->state.auth && - !(battle_config.hide_GM_session && pc_isGM(sd))) - if(sd->status.char_id) - chrif_char_online(sd); - } -} -#endif /* not TXT_ONLY */ - -//----------------------------------------------------- -//I'm Alive Alert -//Used to output 'I'm Alive' every few seconds -//Intended to let frontends know if the app froze -//----------------------------------------------------- -int imalive_timer(int tid, unsigned int tick, int id, int data){ - printf("I'm Alive\n"); - return 0; -} - -//----------------------------------------------------- -//Flush stdout -//stdout buffer needs flushed to be seen in GUI -//----------------------------------------------------- -int flush_timer(int tid, unsigned int tick, int id, int data){ - fflush(stdout); - return 0; -} - -int id_db_final(void *k,void *d,va_list ap) { return 0; } -int map_db_final(void *k,void *d,va_list ap) { return 0; } -int nick_db_final(void *k,void *d,va_list ap) -{ - char *p = (char *) d; - if (p) aFree(p); - return 0; -} -int charid_db_final(void *k,void *d,va_list ap) -{ - struct charid2nick *p = (struct charid2nick *) d; - if (p) aFree(p); - return 0; -} -int cleanup_sub(struct block_list *bl, va_list ap) { - nullpo_retr(0, bl); - - switch(bl->type) { - case BL_PC: - map_quit((struct map_session_data *) bl); - break; - case BL_NPC: - npc_unload((struct npc_data *)bl); - break; - case BL_MOB: - mob_unload((struct mob_data *)bl); - break; - case BL_PET: - pet_remove_map((struct map_session_data *)bl); - break; - case BL_ITEM: - map_clearflooritem(bl->id); - break; - case BL_SKILL: - skill_delunit((struct skill_unit *) bl); - break; - } - - return 0; -} - -/*========================================== - * map鯖終了時?理 - *------------------------------------------ - */ -void do_final(void) { - int i; - ShowStatus("Terminating...\n"); - - for (i = 0; i < map_num; i++) - if(map[i].m) - map_foreachinarea(cleanup_sub, i, 0, 0, map[i].xs, map[i].ys, 0, 0); - -#ifndef TXT_ONLY - chrif_char_reset_offline(); -#endif - - chrif_flush_fifo(); - -//#if 0 // why is this here? >_> - do_final_chrif(); // この内部でキャラを全て切断する - do_final_npc(); -// map_removenpc(); - do_final_script(); - do_final_itemdb(); - do_final_storage(); - do_final_guild(); - do_final_party(); - do_final_pc(); - do_final_pet(); - do_final_msg(); - - for (i=0; i<map_num; i++) { - if(map[i].gat) aFree(map[i].gat); - if(map[i].block) aFree(map[i].block); - if(map[i].block_mob) aFree(map[i].block_mob); - if(map[i].block_count) aFree(map[i].block_count); - if(map[i].block_mob_count) aFree(map[i].block_mob_count); - } - -// do_final_timer(); (we used timer_final() instead) - timer_final(); - numdb_final(id_db, id_db_final); - strdb_final(map_db, map_db_final); - strdb_final(nick_db, nick_db_final); - numdb_final(charid_db, charid_db_final); - exit_dbn(); - -//#endif - -#ifndef TXT_ONLY - map_sql_close(); -#endif /* not TXT_ONLY */ - ShowStatus("Successfully terminated.\n"); -} - -/*====================================================== - * Map-Server Version Screen [MC Cameri] - *------------------------------------------------------ - */ -void map_helpscreen(int flag) { // by MC Cameri - puts("Usage: map-server [options]"); - puts("Options:"); - puts(CL_WHITE" Commands\t\t\tDescription"CL_RESET); - puts("-----------------------------------------------------------------------------"); - puts(" --help, --h, --?, /? Displays this help screen"); - puts(" --map-config <file> Load map-server configuration from <file>"); - puts(" --battle-config <file> Load battle configuration from <file>"); - puts(" --atcommand-config <file> Load atcommand configuration from <file>"); - puts(" --charcommand-config <file> Load charcommand configuration from <file>"); - puts(" --script-config <file> Load script configuration from <file>"); - puts(" --msg-config <file> Load message configuration from <file>"); - puts(" --grf-path-file <file> Load grf path file configuration from <file>"); - puts(" --sql-config <file> Load inter-server configuration from <file>"); - puts(" (SQL Only)"); - puts(" --log-config <file> Load logging configuration from <file>"); - puts(" (SQL Only)"); - puts(" --version, --v, -v, /v Displays the server's version"); - puts("\n"); - if (flag) exit(1); -} - -/*====================================================== - * Map-Server Version Screen [MC Cameri] - *------------------------------------------------------ - */ -void map_versionscreen(int flag) { - printf("CL_WHITE" "eAthena version %d.%02d.%02d, Athena Mod version %d" CL_RESET"\n", - ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION, - ATHENA_MOD_VERSION); - puts(CL_GREEN "Website/Forum:" CL_RESET "\thttp://eathena.deltaanime.net/"); - puts(CL_GREEN "Download URL:" CL_RESET "\thttp://eathena.systeminplace.net/"); - puts(CL_GREEN "IRC Channel:" CL_RESET "\tirc://irc.deltaanime.net/#athena"); - puts("\nOpen " CL_WHITE "readme.html" CL_RESET " for more information."); - if (ATHENA_RELEASE_FLAG) ShowNotice("This version is not for release.\n"); - if (flag) exit(1); -} - -/*====================================================== - * Map-Server Init and Command-line Arguments [Valaris] - *------------------------------------------------------ - */ -int do_init(int argc, char *argv[]) { - int i; - FILE *data_conf; - char line[1024], w1[1024], w2[1024]; - - SERVER_TYPE = SERVER_MAP; -#ifdef GCOLLECT - GC_enable_incremental(); -#endif - - INTER_CONF_NAME="conf/inter_athena.conf"; - LOG_CONF_NAME="conf/log_athena.conf"; - MAP_CONF_NAME = "conf/map_athena.conf"; - BATTLE_CONF_FILENAME = "conf/battle_athena.conf"; - ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf"; - CHARCOMMAND_CONF_FILENAME = "conf/charcommand_athena.conf"; - SCRIPT_CONF_NAME = "conf/script_athena.conf"; - MSG_CONF_NAME = "conf/msg_athena.conf"; - GRF_PATH_FILENAME = "conf/grf-files.txt"; - - chrif_connected = 0; - - srand(gettick()); - - for (i = 1; i < argc ; i++) { - if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--h") == 0 || strcmp(argv[i], "--?") == 0 || strcmp(argv[i], "/?") == 0) - map_helpscreen(1); - if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "--v") == 0 || strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "/v") == 0) - map_versionscreen(1); - else if (strcmp(argv[i], "--map_config") == 0 || strcmp(argv[i], "--map-config") == 0) - MAP_CONF_NAME=argv[i+1]; - else if (strcmp(argv[i],"--battle_config") == 0 || strcmp(argv[i],"--battle-config") == 0) - BATTLE_CONF_FILENAME = argv[i+1]; - else if (strcmp(argv[i],"--atcommand_config") == 0 || strcmp(argv[i],"--atcommand-config") == 0) - ATCOMMAND_CONF_FILENAME = argv[i+1]; - else if (strcmp(argv[i],"--charcommand_config") == 0 || strcmp(argv[i],"--charcommand-config") == 0) - CHARCOMMAND_CONF_FILENAME = argv[i+1]; - else if (strcmp(argv[i],"--script_config") == 0 || strcmp(argv[i],"--script-config") == 0) - SCRIPT_CONF_NAME = argv[i+1]; - else if (strcmp(argv[i],"--msg_config") == 0 || strcmp(argv[i],"--msg-config") == 0) - MSG_CONF_NAME = argv[i+1]; - else if (strcmp(argv[i],"--grf_path_file") == 0 || strcmp(argv[i],"--grf-path-file") == 0) - GRF_PATH_FILENAME = argv[i+1]; -#ifndef TXT_ONLY - else if (strcmp(argv[i],"--inter_config") == 0 || strcmp(argv[i],"--inter-config") == 0) - INTER_CONF_NAME = argv[i+1]; -#endif /* not TXT_ONLY */ - else if (strcmp(argv[i],"--log_config") == 0 || strcmp(argv[i],"--log-config") == 0) - LOG_CONF_NAME = argv[i+1]; - else if (strcmp(argv[i],"--run_once") == 0) // close the map-server as soon as its done.. for testing [Celest] - runflag = 0; - } - - map_config_read(MAP_CONF_NAME); - - if ((naddr_ == 0) && (map_ip_set_ == 0 || char_ip_set_ == 0)) { - printf("\nUnable to determine your IP address... please edit\n"); - printf("the map_athena.conf file and set it.\n"); - printf("(127.0.0.1 is valid if you have no network interface)\n"); - } - - if (map_ip_set_ == 0 || char_ip_set_ == 0) { - // The map server should know what IP address it is running on - // - MouseJstr - int localaddr = ntohl(addr_[0]); - unsigned char *ptr = (unsigned char *) &localaddr; - char buf[16]; - sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);; - if (naddr_ != 1) - printf("Multiple interfaces detected.. using %s as our IP address\n", buf); - else - printf("Defaulting to %s as our IP address\n", buf); - if (map_ip_set_ == 0) - clif_setip(buf); - if (char_ip_set_ == 0) - chrif_setip(buf); - - if (ptr[0] == 192 && ptr[1] == 168) - printf("\nFirewall detected.. \n edit lan_support.conf and map_athena.conf\n\n"); - } - if (SHOW_DEBUG_MSG) ShowNotice("Server running in '"CL_WHITE"Debug Mode"CL_RESET"'.\n"); - battle_config_read(BATTLE_CONF_FILENAME); - msg_config_read(MSG_CONF_NAME); - atcommand_config_read(ATCOMMAND_CONF_FILENAME); - charcommand_config_read(CHARCOMMAND_CONF_FILENAME); - script_config_read(SCRIPT_CONF_NAME); - inter_config_read(INTER_CONF_NAME); - log_config_read(LOG_CONF_NAME); - - atexit(do_final); - - id_db = numdb_init(); - map_db = strdb_init(16); - nick_db = strdb_init(24); - charid_db = numdb_init(); -#ifndef TXT_ONLY - map_sql_init(); -#endif /* not TXT_ONLY */ - - grfio_init(GRF_PATH_FILENAME); - - data_conf = fopen(GRF_PATH_FILENAME, "r"); - // It will read, if there is grf-files.txt. - if (data_conf) { - while(fgets(line, 1020, data_conf)) { - if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) { - if(strcmp(w1,"afm_dir") == 0) - strcpy(afm_dir, w2); - } - } - fclose(data_conf); - } // end of reading grf-files.txt for AFMs - - - map_readallmap(); - - add_timer_func_list(map_freeblock_timer,"map_freeblock_timer"); - add_timer_func_list(map_clearflooritem_timer, "map_clearflooritem_timer"); - add_timer_interval(gettick()+1000,map_freeblock_timer,0,0,60*1000); - - //Added by Mugendai for GUI support - if (flush_on) - add_timer_interval(gettick()+10, flush_timer,0,0,flush_time); - //Added for Mugendais I'm Alive mod - if (imalive_on) - add_timer_interval(gettick()+10, imalive_timer,0,0,imalive_time*1000); - -#ifndef TXT_ONLY // online status timer, checks every hour [Valaris] - add_timer_func_list(online_timer, "online_timer"); - add_timer_interval(gettick()+10, online_timer, 0, 0, CHECK_INTERVAL); -#endif /* not TXT_ONLY */ - - do_init_chrif(); - do_init_clif(); - do_init_itemdb(); - do_init_mob(); // npcの初期化時?でmob_spawnして、mob_dbを?照するのでinit_npcより先 - do_init_script(); - do_init_pc(); - do_init_status(); - do_init_party(); - do_init_guild(); - do_init_storage(); - do_init_skill(); - do_init_pet(); - do_init_npc(); - -#ifndef TXT_ONLY /* mail system [Valaris] */ - if(battle_config.mail_system) - do_init_mail(); - - if (log_config.sql_logs && (log_config.branch || log_config.drop || log_config.mvpdrop || - log_config.present || log_config.produce || log_config.refine || log_config.trade)) - { - log_sql_init(); - } -#endif /* not TXT_ONLY */ - - npc_event_do_oninit(); // npcのOnInitイベント?行 - - if ( console ) { - set_defaultconsoleparse(parse_console); - start_console(); - } - - if (battle_config.pk_mode == 1) - ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n"); - - sprintf(tmp_output,"Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port); - ShowStatus(tmp_output); - - return 0; -} - -int compare_item(struct item *a, struct item *b) { - return ( - (a->nameid == b->nameid) && - (a->identify == b->identify) && - (a->refine == b->refine) && - (a->attribute == b->attribute) && - (a->card[0] == b->card[0]) && - (a->card[1] == b->card[1]) && - (a->card[2] == b->card[2]) && - (a->card[3] == b->card[3])); -} diff --git a/src/map/map.h b/src/map/map.h deleted file mode 100644 index 01d9fef0e..000000000 --- a/src/map/map.h +++ /dev/null @@ -1,864 +0,0 @@ -// $Id: map.h,v 1.8 2004/09/25 11:39:17 MouseJstr Exp $ -#ifndef _MAP_H_ -#define _MAP_H_ - -#include <stdarg.h> -#include "mmo.h" - -#define MAX_PC_CLASS (1+6+6+1+6+1+1+1+1+4023) -#define PC_CLASS_BASE 0 -#define PC_CLASS_BASE2 (PC_CLASS_BASE + 4001) -#define PC_CLASS_BASE3 (PC_CLASS_BASE2 + 22) -#define MAX_NPC_PER_MAP 512 -#define BLOCK_SIZE 8 // Never zero -#define AREA_SIZE battle_config.area_size -#define LOCAL_REG_NUM 16 -#define LIFETIME_FLOORITEM 60 -#define DAMAGELOG_SIZE 30 -#define LOOTITEM_SIZE 10 -#define MAX_SKILL_LEVEL 100 -#define MAX_STATUSCHANGE 210 -#define MAX_SKILLUNITGROUP 32 -#define MAX_MOBSKILLUNITGROUP 8 -#define MAX_SKILLUNITGROUPTICKSET 32 -#define MAX_SKILLTIMERSKILL 32 -#define MAX_MOBSKILLTIMERSKILL 10 -#define MAX_MOBSKILL 32 -#define MAX_EVENTQUEUE 2 -#define MAX_EVENTTIMER 32 -#define NATURAL_HEAL_INTERVAL 500 -#define MAX_FLOORITEM 500000 -#define MAX_LEVEL 255 -#define MAX_WALKPATH 32 -#define MAX_DROP_PER_MAP 48 -#define MAX_IGNORE_LIST 80 -#define MAX_VENDING 12 - -#define DEFAULT_AUTOSAVE_INTERVAL 60*1000 - -#define OPTION_HIDE 0x40 - -enum { BL_NUL, BL_PC, BL_NPC, BL_MOB, BL_ITEM, BL_CHAT, BL_SKILL , BL_PET }; -enum { WARP, SHOP, SCRIPT, MONS }; - -struct block_list { - struct block_list *next,*prev; - int id; - short m,x,y; - unsigned char type; - unsigned char subtype; -}; - -struct walkpath_data { - unsigned char path_len,path_pos,path_half; - unsigned char path[MAX_WALKPATH]; -}; -struct shootpath_data { - int rx,ry,len; - int x[MAX_WALKPATH]; - int y[MAX_WALKPATH]; -}; - -struct script_reg { - int index; - int data; -}; -struct script_regstr { - int index; - char data[256]; -}; -struct status_change { - int timer; - int val1,val2,val3,val4; -}; -struct vending { - short index; - unsigned short amount; - unsigned int value; -}; - -struct skill_unit_group; -struct skill_unit { - struct block_list bl; - - struct skill_unit_group *group; - - int limit; - int val1,val2; - short alive,range; -}; -struct skill_unit_group { - int src_id; - int party_id; - int guild_id; - int map; - int target_flag; - unsigned int tick; - int limit,interval; - - int skill_id,skill_lv; - int val1,val2,val3; - char *valstr; - int unit_id; - int group_id; - int unit_count,alive_count; - struct skill_unit *unit; -}; -struct skill_unit_group_tickset { - unsigned int tick; - int id; -}; -struct skill_timerskill { - int timer; - int src_id; - int target_id; - int map; - short x,y; - short skill_id,skill_lv; - int type; - int flag; -}; - -struct npc_data; -struct pet_db; -struct item_data; -struct square; - -struct map_session_data { - struct block_list bl; - struct { - unsigned auth : 1; - unsigned change_walk_target : 1; - unsigned attack_continue : 1; - unsigned menu_or_input : 1; - unsigned dead_sit : 2; - unsigned skillcastcancel : 1; - unsigned waitingdisconnect : 1; - unsigned lr_flag : 2; - unsigned connect_new : 1; - unsigned arrow_atk : 1; - unsigned attack_type : 3; - unsigned skill_flag : 1; - unsigned gangsterparadise : 1; - unsigned produce_flag : 1; - unsigned make_arrow_flag : 1; - unsigned potionpitcher_flag : 1; - unsigned storage_flag : 1; - unsigned snovice_flag : 4; - int gmaster_flag; - // originally by Qamera, adapted by celest - unsigned event_death : 1; - unsigned event_kill : 1; - unsigned event_disconnect : 1; - } state; - struct { - unsigned killer : 1; - unsigned killable : 1; - unsigned restart_full_recover : 1; - unsigned no_castcancel : 1; - unsigned no_castcancel2 : 1; - unsigned no_sizefix : 1; - unsigned no_magic_damage : 1; - unsigned no_weapon_damage : 1; - unsigned no_gemstone : 1; - unsigned infinite_endure : 1; - } special_state; - int char_id, login_id1, login_id2, sex; - int packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor]) - struct mmo_charstatus status; - struct item_data *inventory_data[MAX_INVENTORY]; - short equip_index[11]; - unsigned short unbreakable_equip; - unsigned short unbreakable; // chance to prevent equipment breaking [celest] - int weight,max_weight; - int cart_weight,cart_max_weight,cart_num,cart_max_num; - char mapname[24]; - int fd,new_fd; - short to_x,to_y; - short speed,prev_speed; - short opt1,opt2,opt3; - char dir,head_dir; - unsigned int client_tick,server_tick; - struct walkpath_data walkpath; - int walktimer; - int next_walktime; - int npc_id,areanpc_id,npc_shopid; - int npc_pos; - int npc_menu; - int npc_amount; - int npc_stack,npc_stackmax; - char *npc_script,*npc_scriptroot; - char *npc_stackbuf; - char npc_str[256]; - unsigned int chatID; - unsigned long idletime; - - struct{ - char name[24]; - } ignore[MAX_IGNORE_LIST]; - int ignoreAll; - - int attacktimer; - int attacktarget; - short attacktarget_lv; - unsigned int attackabletime; - - int followtimer; // [MouseJstr] - int followtarget; - - time_t emotionlasttime; // to limit flood with emotion packets - - short attackrange,attackrange_; - int skilltimer; - int skilltarget; - short skillx,skilly; - short skillid,skilllv; - short skillitem,skillitemlv; - short skillid_old,skilllv_old; - short skillid_dance,skilllv_dance; - struct skill_unit_group skillunit[MAX_SKILLUNITGROUP]; - struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET]; - struct skill_timerskill skilltimerskill[MAX_SKILLTIMERSKILL]; - char blockskill[MAX_SKILL]; // [celest] - //unsigned int skillstatictimer[MAX_SKILL]; - unsigned short timerskill_count; // [celest] - int cloneskill_id; - int potion_hp,potion_sp,potion_per_hp,potion_per_sp; - - int invincible_timer; - unsigned int canact_tick; - unsigned int canmove_tick; - unsigned int canlog_tick; - unsigned int canregen_tick; - int hp_sub,sp_sub; - int inchealhptick,inchealsptick,inchealspirithptick,inchealspiritsptick; -// -- moonsoul (new tick for berserk self-damage) -// int berserkdamagetick; - int fame; - - short view_class; - short weapontype1,weapontype2; - short disguiseflag,disguise; // [Valaris] - int paramb[6],paramc[6],parame[6],paramcard[6]; - int hit,flee,flee2,aspd,amotion,dmotion; - int watk,watk2,atkmods[3]; - int def,def2,mdef,mdef2,critical,matk1,matk2; - int atk_ele,def_ele,star,overrefine; - int castrate,delayrate,hprate,sprate,dsprate; - int addele[10],addrace[12],addsize[3],subele[10],subrace[12]; - int addeff[10],addeff2[10],reseff[10]; - int watk_,watk_2,atkmods_[3],addele_[10],addrace_[12],addsize_[3]; //二刀流のために追加 - int atk_ele_,star_,overrefine_; //二刀流のために追加 - int base_atk,atk_rate; - int weapon_atk[16],weapon_atk_rate[16]; - int arrow_atk,arrow_ele,arrow_cri,arrow_hit,arrow_range; - int arrow_addele[10],arrow_addrace[12],arrow_addsize[3],arrow_addeff[10],arrow_addeff2[10]; - int nhealhp,nhealsp,nshealhp,nshealsp,nsshealhp,nsshealsp; - int aspd_rate,speed_rate,hprecov_rate,sprecov_rate,critical_def,double_rate; - int near_attack_def_rate,long_attack_def_rate,magic_def_rate,misc_def_rate; - int matk_rate,ignore_def_ele,ignore_def_race,ignore_def_ele_,ignore_def_race_; - int ignore_mdef_ele,ignore_mdef_race; - int magic_addele[10],magic_addrace[12],magic_subrace[12]; - int perfect_hit,get_zeny_num; - int critical_rate,hit_rate,flee_rate,flee2_rate,def_rate,def2_rate,mdef_rate,mdef2_rate; - int def_ratio_atk_ele,def_ratio_atk_ele_,def_ratio_atk_race,def_ratio_atk_race_; - int add_damage_class_count,add_damage_class_count_,add_magic_damage_class_count; - short add_damage_classid[10],add_damage_classid_[10],add_magic_damage_classid[10]; - int add_damage_classrate[10],add_damage_classrate_[10],add_magic_damage_classrate[10]; - short add_def_class_count,add_mdef_class_count; - short add_def_classid[10],add_mdef_classid[10]; - int add_def_classrate[10],add_mdef_classrate[10]; - short monster_drop_item_count; - short monster_drop_itemid[10]; - int monster_drop_race[10],monster_drop_itemrate[10]; - int double_add_rate,speed_add_rate,aspd_add_rate,perfect_hit_add, get_zeny_add_num; - short splash_range,splash_add_range; - short autospell_id,autospell_lv,autospell_rate; - short hp_drain_rate,hp_drain_per,sp_drain_rate,sp_drain_per; - short hp_drain_rate_,hp_drain_per_,sp_drain_rate_,sp_drain_per_; - short hp_drain_value,sp_drain_value,hp_drain_value_,sp_drain_value_; - int short_weapon_damage_return,long_weapon_damage_return; - int weapon_coma_ele[10],weapon_coma_race[12]; - int break_weapon_rate,break_armor_rate; - short add_steal_rate; - //--- 02/15's new card effects [celest] - int crit_atk_rate; - int critaddrace[12]; - short no_regen; - int addeff3[10]; - short addeff3_type[10]; - short autospell2_id,autospell2_lv,autospell2_rate,autospell2_type; - int skillatk[2]; - unsigned short unstripable_equip; - short add_damage_classid2[10],add_damage_class_count2; - int add_damage_classrate2[10]; - short sp_gain_value, hp_gain_value; - short sp_drain_type; - short ignore_def_mob, ignore_def_mob_; - int hp_loss_tick, hp_loss_rate; - short hp_loss_value, hp_loss_type; - int addrace2[12],addrace2_[12]; - int subsize[3]; - short unequip_losehp[11]; - short unequip_losesp[11]; - int itemid; - int itemhealrate[7]; - //--- 03/15's new card effects - int expaddrace[12]; - int subrace2[12]; - short sp_gain_race[12]; - - short spiritball, spiritball_old; - int spirit_timer[MAX_SKILL_LEVEL]; - int magic_damage_return; // AppleGirl Was Here - int random_attack_increase_add,random_attack_increase_per; // [Valaris] - int perfect_hiding; // [Valaris] - int classchange; // [Valaris] - - int die_counter; - short doridori_counter; - - int reg_num; - struct script_reg *reg; - int regstr_num; - struct script_regstr *regstr; - - struct status_change sc_data[MAX_STATUSCHANGE]; - short sc_count; - struct square dev; - - int trade_partner; - int deal_item_index[10]; - int deal_item_amount[10]; - int deal_zeny; - short deal_locked; - - int party_sended,party_invite,party_invite_account; - int party_hp,party_x,party_y; - - int guild_sended,guild_invite,guild_invite_account; - int guild_emblem_id,guild_alliance,guild_alliance_account; - int guildspy; // [Syrus22] - int partyspy; // [Syrus22] - - int vender_id; - int vend_num; - char message[80]; - struct vending vending[MAX_VENDING]; - - int catch_target_class; - struct s_pet pet; - struct pet_db *petDB; - struct pet_data *pd; - int pet_hungry_timer; - - int pvp_point,pvp_rank,pvp_timer,pvp_lastusers; - - char eventqueue[MAX_EVENTQUEUE][50]; - int eventtimer[MAX_EVENTTIMER]; - unsigned short eventcount; // [celest] - - int last_skillid,last_skilllv; // Added by RoVeRT - - unsigned char change_level; // [celest] - int autoloot; //by Upa-Kun - unsigned nodelay :1; - unsigned noexp :1; - unsigned detach :1; - -#ifndef TXT_ONLY - int mail_counter; // mail counter for mail system [Valaris] -#endif - -}; - -struct npc_timerevent_list { - int timer,pos; -}; -struct npc_label_list { - char name[24]; - int pos; -}; -struct npc_item_list { - int nameid,value; -}; -struct npc_data { - struct block_list bl; - short n; - short class_,dir; - short speed; - char name[24]; - char exname[24]; - int chat_id; - short opt1,opt2,opt3,option; - short flag; - int walktimer; // [Valaris] - short to_x,to_y; // [Valaris] - struct walkpath_data walkpath; - unsigned int next_walktime; - unsigned int canmove_tick; - - struct { // [Valaris] - unsigned state : 8; - unsigned change_walk_target : 1; - unsigned walk_easy : 1; - } state; - - union { - struct { - char *script; - short xs,ys; - int guild_id; - int timer,timerid,timeramount,nexttimer,rid; - unsigned int timertick; - struct npc_timerevent_list *timer_event; - int label_list_num; - struct npc_label_list *label_list; - int src_id; - } scr; - struct npc_item_list shop_item[1]; - struct { - short xs,ys; - short x,y; - char name[16]; - } warp; - } u; - // ここにメンバを追加してはならない(shop_itemが可変長の為) - - char eventqueue[MAX_EVENTQUEUE][50]; - int eventtimer[MAX_EVENTTIMER]; - short arenaflag; - - void *chatdb; -}; -struct mob_data { - struct block_list bl; - short n; - short base_class,class_,dir,mode,level; - short m,x0,y0,xs,ys; - char name[24]; - int spawndelay1,spawndelay2; - struct { - unsigned state : 8; - unsigned skillstate : 8; - unsigned targettype : 1; - unsigned steal_flag : 1; - unsigned steal_coin_flag : 1; - unsigned skillcastcancel : 1; - unsigned master_check : 1; - unsigned change_walk_target : 1; - unsigned walk_easy : 1; - unsigned special_mob_ai : 3; - unsigned soul_change_flag : 1; // Celest - int provoke_flag; // Celest - } state; - int timer; - short to_x,to_y; - short target_dir; - short speed; - int hp; - int target_id,attacked_id; - short target_lv; - struct walkpath_data walkpath; - unsigned int next_walktime; - unsigned int attackabletime; - unsigned int last_deadtime,last_spawntime,last_thinktime; - unsigned int canmove_tick; - short move_fail_count; - struct { - int id; - int dmg; - } dmglog[DAMAGELOG_SIZE]; - struct item *lootitem; - short lootitem_count; - - struct status_change sc_data[MAX_STATUSCHANGE]; - short sc_count; - short opt1,opt2,opt3,option; - short min_chase; - int guild_id; - int deletetimer; - - int skilltimer; - int skilltarget; - short skillx,skilly; - short skillid,skilllv,skillidx; - unsigned int skilldelay[MAX_MOBSKILL]; - int def_ele; - int master_id,master_dist; - int exclusion_src,exclusion_party,exclusion_guild; - struct skill_timerskill skilltimerskill[MAX_MOBSKILLTIMERSKILL]; - struct skill_unit_group skillunit[MAX_MOBSKILLUNITGROUP]; - struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET]; - char npc_event[50]; - unsigned char size; - short recall_flag; - int recallmob_count; - short recallcount; -}; -struct pet_data { - struct block_list bl; - short n; - short class_,dir; - short speed; - char name[24]; - struct { - unsigned state : 8 ; - unsigned skillstate : 8 ; - unsigned change_walk_target : 1 ; - short skillbonus; - } state; - int timer; - short to_x,to_y; - short equip; - struct walkpath_data walkpath; - int target_id; - short target_lv; - int move_fail_count; - unsigned int attackabletime,next_walktime,last_thinktime; - int skilltype,skillval,skilltimer,skillduration; // [Valaris] - //int skillbonustype,skillbonusval,skillbonustimer,skillbonusduration; // [Valaris] - int skillbonustype,skillbonusval,skillbonustimer; - struct item *lootitem; - short loot; // [Valaris] - short lootmax; // [Valaris] - short lootitem_count; - short lootitem_weight; - int lootitem_timer; - struct skill_timerskill skilltimerskill[MAX_MOBSKILLTIMERSKILL]; // [Valaris] - struct skill_unit_group skillunit[MAX_MOBSKILLUNITGROUP]; // [Valaris] - struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET]; // [Valaris] - struct map_session_data *msd; -}; - -enum { MS_IDLE,MS_WALK,MS_ATTACK,MS_DEAD,MS_DELAY }; - -enum { NONE_ATTACKABLE,ATTACKABLE }; - -enum { ATK_LUCKY=1,ATK_FLEE,ATK_DEF}; // 囲まれペナルティ計算用 - -// 装備コード -enum { - EQP_WEAPON = 0x0002, // 右手 - EQP_ARMOR = 0x0010, // 体 - EQP_SHIELD = 0x0020, // 左手 - EQP_HELM = 0x0100, // 頭上段 -}; - -struct map_data { - char name[24]; - unsigned char *gat; // NULLなら下のmap_data_other_serverとして扱う - char *alias; // [MouseJstr] - struct block_list **block; - struct block_list **block_mob; - int *block_count,*block_mob_count; - int m; - short xs,ys; - short bxs,bys; - int npc_num; - int users; - struct { - unsigned alias : 1; - unsigned nomemo : 1; - unsigned noteleport : 1; - unsigned noreturn : 1; - unsigned monster_noteleport : 1; - unsigned nosave : 1; - unsigned nobranch : 1; - unsigned nopenalty : 1; - unsigned pvp : 1; - unsigned pvp_noparty : 1; - unsigned pvp_noguild : 1; - unsigned pvp_nightmaredrop :1; - unsigned pvp_nocalcrank : 1; - unsigned gvg : 1; - unsigned gvg_noparty : 1; - unsigned nozenypenalty : 1; - unsigned notrade : 1; - unsigned noskill : 1; - unsigned nowarp : 1; - unsigned nowarpto : 1; - unsigned nopvp : 1; // [Valaris] - unsigned noicewall : 1; // [Valaris] - unsigned snow : 1; // [Valaris] - unsigned fog : 1; // [Valaris] - unsigned sakura : 1; // [Valaris] - unsigned leaves : 1; // [Valaris] - unsigned rain : 1; // [Valaris] - unsigned indoors : 1; // celest - unsigned nogo : 1; // [Valaris] - } flag; - struct point save; - struct npc_data *npc[MAX_NPC_PER_MAP]; - struct { - int drop_id; - int drop_type; - int drop_per; - } drop_list[MAX_DROP_PER_MAP]; -}; -struct map_data_other_server { - char name[24]; - unsigned char *gat; // NULL固定にして判断 - unsigned long ip; - unsigned int port; - struct map_data* map; -}; - -struct flooritem_data { - struct block_list bl; - short subx,suby; - int cleartimer; - int first_get_id,second_get_id,third_get_id; - unsigned int first_get_tick,second_get_tick,third_get_tick; - struct item item_data; -}; - -enum { - SP_SPEED,SP_BASEEXP,SP_JOBEXP,SP_KARMA,SP_MANNER,SP_HP,SP_MAXHP,SP_SP, // 0-7 - SP_MAXSP,SP_STATUSPOINT,SP_0a,SP_BASELEVEL,SP_SKILLPOINT,SP_STR,SP_AGI,SP_VIT, // 8-15 - SP_INT,SP_DEX,SP_LUK,SP_CLASS,SP_ZENY,SP_SEX,SP_NEXTBASEEXP,SP_NEXTJOBEXP, // 16-23 - SP_WEIGHT,SP_MAXWEIGHT,SP_1a,SP_1b,SP_1c,SP_1d,SP_1e,SP_1f, // 24-31 - SP_USTR,SP_UAGI,SP_UVIT,SP_UINT,SP_UDEX,SP_ULUK,SP_26,SP_27, // 32-39 - SP_28,SP_ATK1,SP_ATK2,SP_MATK1,SP_MATK2,SP_DEF1,SP_DEF2,SP_MDEF1, // 40-47 - SP_MDEF2,SP_HIT,SP_FLEE1,SP_FLEE2,SP_CRITICAL,SP_ASPD,SP_36,SP_JOBLEVEL, // 48-55 - SP_UPPER,SP_PARTNER,SP_CART,SP_FAME,SP_UNBREAKABLE, //56-60 - SP_CARTINFO=99, // 99 - - SP_BASEJOB=119, // 100+19 - celest - - // original 1000- - SP_ATTACKRANGE=1000, SP_ATKELE,SP_DEFELE, // 1000-1002 - SP_CASTRATE, SP_MAXHPRATE, SP_MAXSPRATE, SP_SPRATE, // 1003-1006 - SP_ADDELE, SP_ADDRACE, SP_ADDSIZE, SP_SUBELE, SP_SUBRACE, // 1007-1011 - SP_ADDEFF, SP_RESEFF, // 1012-1013 - SP_BASE_ATK,SP_ASPD_RATE,SP_HP_RECOV_RATE,SP_SP_RECOV_RATE,SP_SPEED_RATE, // 1014-1018 - SP_CRITICAL_DEF,SP_NEAR_ATK_DEF,SP_LONG_ATK_DEF, // 1019-1021 - SP_DOUBLE_RATE, SP_DOUBLE_ADD_RATE, SP_MATK, SP_MATK_RATE, // 1022-1025 - SP_IGNORE_DEF_ELE,SP_IGNORE_DEF_RACE, // 1026-1027 - SP_ATK_RATE,SP_SPEED_ADDRATE,SP_ASPD_ADDRATE, // 1028-1030 - SP_MAGIC_ATK_DEF,SP_MISC_ATK_DEF, // 1031-1032 - SP_IGNORE_MDEF_ELE,SP_IGNORE_MDEF_RACE, // 1033-1034 - SP_MAGIC_ADDELE,SP_MAGIC_ADDRACE,SP_MAGIC_SUBRACE, // 1035-1037 - SP_PERFECT_HIT_RATE,SP_PERFECT_HIT_ADD_RATE,SP_CRITICAL_RATE,SP_GET_ZENY_NUM,SP_ADD_GET_ZENY_NUM, // 1038-1042 - SP_ADD_DAMAGE_CLASS,SP_ADD_MAGIC_DAMAGE_CLASS,SP_ADD_DEF_CLASS,SP_ADD_MDEF_CLASS, // 1043-1046 - SP_ADD_MONSTER_DROP_ITEM,SP_DEF_RATIO_ATK_ELE,SP_DEF_RATIO_ATK_RACE,SP_ADD_SPEED, // 1047-1050 - SP_HIT_RATE,SP_FLEE_RATE,SP_FLEE2_RATE,SP_DEF_RATE,SP_DEF2_RATE,SP_MDEF_RATE,SP_MDEF2_RATE, // 1051-1057 - SP_SPLASH_RANGE,SP_SPLASH_ADD_RANGE,SP_AUTOSPELL,SP_HP_DRAIN_RATE,SP_SP_DRAIN_RATE, // 1058-1062 - SP_SHORT_WEAPON_DAMAGE_RETURN,SP_LONG_WEAPON_DAMAGE_RETURN,SP_WEAPON_COMA_ELE,SP_WEAPON_COMA_RACE, // 1063-1066 - SP_ADDEFF2,SP_BREAK_WEAPON_RATE,SP_BREAK_ARMOR_RATE,SP_ADD_STEAL_RATE, // 1067-1070 - SP_MAGIC_DAMAGE_RETURN,SP_RANDOM_ATTACK_INCREASE,SP_ALL_STATS,SP_AGI_VIT,SP_AGI_DEX_STR,SP_PERFECT_HIDE, // 1071-1076 - SP_DISGUISE,SP_CLASSCHANGE, // 1077-1078 - SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080 - SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082 - SP_DELAYRATE, // 1083 - - SP_RESTART_FULL_RECORVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005 - SP_NO_CASTCANCEL2,SP_INFINITE_ENDURE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010 - SP_UNBREAKABLE_SHIELD, SP_LONG_ATK_RATE, // 2011-2012 - - SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017 - SP_SKILL_ATK, SP_UNSTRIPABLE, SP_ADD_DAMAGE_BY_CLASS, // 2018-2020 - SP_SP_GAIN_VALUE, SP_IGNORE_DEF_MOB, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025 - SP_SUBSIZE, SP_DAMAGE_WHEN_UNEQUIP, SP_ADD_ITEM_HEAL_RATE, SP_LOSESP_WHEN_UNEQUIP, SP_EXP_ADDRACE, // 2026-2030 - SP_SP_GAIN_RACE, SP_SUBRACE2, SP_ADDEFF_WHENHIT_SHORT, // 2031-2033 - SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD // 2034-2037 -}; - -enum { - LOOK_BASE,LOOK_HAIR,LOOK_WEAPON,LOOK_HEAD_BOTTOM,LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HAIR_COLOR,LOOK_CLOTHES_COLOR,LOOK_SHIELD,LOOK_SHOES -}; - -// CELL -#define CELL_MASK 0x0f -#define CELL_NPC 0x80 // NPCセル -#define CELL_BASILICA 0x40 // BASILICAセル -#define CELL_MOONLIT 0x100 -#define CELL_REGEN 0x200 -/* - * map_getcell()で使用されるフラグ - */ -typedef enum { - CELL_CHKWALL=0, // 壁(セルタイプ1) - CELL_CHKWATER, // 水場(セルタイプ3) - CELL_CHKGROUND, // 地面障害物(セルタイプ5) - CELL_CHKPASS, // 通過可能(セルタイプ1,5以外) - CELL_CHKNOPASS, // 通過不可(セルタイプ1,5) - CELL_GETTYPE, // セルタイプを返す - CELL_CHKNPC=0x10, // タッチタイプのNPC(セルタイプ0x80フラグ) - CELL_CHKBASILICA, // バジリカ(セルタイプ0x40フラグ) -} cell_t; -// map_setcell()で使用されるフラグ -enum { - CELL_SETNPC=0x10, // タッチタイプのNPCをセット - CELL_SETBASILICA, // バジリカをセット - CELL_CLRBASILICA, // バジリカをクリア -}; - -struct chat_data { - struct block_list bl; - - unsigned char pass[8]; /* password */ - unsigned char title[61]; /* room title MAX 60 */ - unsigned char limit; /* join limit */ - unsigned char trigger; - unsigned char users; /* current users */ - unsigned char pub; /* room attribute */ - struct map_session_data *usersd[20]; - struct block_list *owner_; - struct block_list **owner; - char npc_event[50]; -}; - -extern struct map_data map[]; -extern int map_num; -extern int autosave_interval; -extern int agit_flag; -extern int night_flag; // 0=day, 1=night [Yor] - -// gat?ヨァ -int map_getcell(int,int,int,cell_t); -int map_getcellp(struct map_data*,int,int,cell_t); -void map_setcell(int,int,int,int); -extern int map_read_flag; // 0: grfォユォ。ォ、ォ 1: ォュォ罩テォキォ 2: ォュォ罩テォキォ(?) -enum { - READ_FROM_GAT, READ_FROM_AFM, - READ_FROM_BITMAP, CREATE_BITMAP, - READ_FROM_BITMAP_COMPRESSED, CREATE_BITMAP_COMPRESSED -}; - -extern char motd_txt[]; -extern char help_txt[]; - -extern char talkie_mes[]; - -extern char wisp_server_name[]; - -// 鯖全体情報 -void map_setusers(int); -int map_getusers(void); -// block削除関連 -int map_freeblock( void *bl ); -int map_freeblock_lock(void); -int map_freeblock_unlock(void); -// block関連 -int map_addblock(struct block_list *); -int map_delblock(struct block_list *); -void map_foreachinarea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,...); -// -- moonsoul (added map_foreachincell) -void map_foreachincell(int (*)(struct block_list*,va_list),int,int,int,int,...); -void map_foreachinmovearea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,int,int,...); -void map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int type,...); // Celest -int map_countnearpc(int,int,int); -//block関連に追加 -int map_count_oncell(int m,int x,int y); -struct skill_unit *map_find_skill_unit_oncell(struct block_list *,int x,int y,int skill_id,struct skill_unit *); -// 一時的object関連 -int map_addobject(struct block_list *); -int map_delobject(int); -int map_delobjectnofree(int id); -void map_foreachobject(int (*)(struct block_list*,va_list),int,...); -// -int map_quit(struct map_session_data *); -// npc -int map_addnpc(int,struct npc_data *); - -// 床アイテム関連 -int map_clearflooritem_timer(int,unsigned int,int,int); -#define map_clearflooritem(id) map_clearflooritem_timer(0,0,id,1) -int map_addflooritem(struct item *,int,int,int,int,struct map_session_data *,struct map_session_data *,struct map_session_data *,int); -int map_searchrandfreecell(int,int,int,int); - -// キャラid=>キャラ名 変換関連 -void map_addchariddb(int charid,char *name); -void map_delchariddb(int charid); -int map_reqchariddb(struct map_session_data * sd,int charid); -char * map_charid2nick(int); -struct map_session_data * map_charid2sd(int); - -struct map_session_data * map_id2sd(int); -struct block_list * map_id2bl(int); -int map_mapname2mapid(char*); -int map_mapname2ipport(char*,int*,int*); -int map_setipport(char *name,unsigned long ip,int port); -int map_eraseipport(char *name,unsigned long ip,int port); -int map_eraseallipport(void); -void map_addiddb(struct block_list *); -void map_deliddb(struct block_list *bl); -int map_foreachiddb(int (*)(void*,void*,va_list),...); -void map_addnickdb(struct map_session_data *); -struct map_session_data * map_nick2sd(char*); -int compare_item(struct item *a, struct item *b); - -// その他 -int map_check_dir(int s_dir,int t_dir); -int map_calc_dir( struct block_list *src,int x,int y); - -// path.cより -int path_search(struct walkpath_data*,int,int,int,int,int,int); -int path_search_long(struct shootpath_data *,int,int,int,int,int); -int path_blownpos(int m,int x0,int y0,int dx,int dy,int count); - -int map_who(int fd); - -int cleanup_sub(struct block_list *bl, va_list ap); - -void map_helpscreen(); // [Valaris] -int map_delmap(char *mapname); - -extern char *INTER_CONF_NAME; -extern char *LOG_CONF_NAME; -extern char *MAP_CONF_NAME; -extern char *BATTLE_CONF_FILENAME; -extern char *ATCOMMAND_CONF_FILENAME; -extern char *CHARCOMMAND_CONF_FILENAME; -extern char *SCRIPT_CONF_NAME; -extern char *MSG_CONF_NAME; -extern char *GRF_PATH_FILENAME; - -#ifndef TXT_ONLY - -// MySQL -#ifdef __WIN32 -#include <my_global.h> -#include <my_sys.h> -#endif -#include <mysql.h> - -void char_online_check(void); // [Valaris] -void char_offline(struct map_session_data *sd); - -extern MYSQL mmysql_handle; -extern char tmp_sql[65535]; -extern MYSQL_RES* sql_res ; -extern MYSQL_ROW sql_row ; - -extern MYSQL lmysql_handle; -extern char tmp_lsql[65535]; -extern MYSQL_RES* lsql_res ; -extern MYSQL_ROW lsql_row ; - -extern MYSQL mail_handle; -extern MYSQL_RES* mail_res ; -extern MYSQL_ROW mail_row ; -extern char tmp_msql[65535]; - -extern int db_use_sqldbs; - -extern char item_db_db[32]; -extern char mob_db_db[32]; -extern char login_db[32]; - -extern char login_db_level[32]; -extern char login_db_account_id[32]; - -extern char gm_db[32]; -extern char gm_db_level[32]; -extern char gm_db_account_id[32]; - -extern int lowest_gm_level; -extern int read_gm_interval; - -extern char char_db[32]; -#endif /* not TXT_ONLY */ - -#endif diff --git a/src/map/mob.c b/src/map/mob.c deleted file mode 100644 index f076b7530..000000000 --- a/src/map/mob.c +++ /dev/null @@ -1,4577 +0,0 @@ -// $Id: mob.c,v 1.7 2004/09/25 05:32:18 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> - -#include "timer.h" -#include "socket.h" -#include "db.h" -#include "nullpo.h" -#include "malloc.h" -#include "map.h" -#include "clif.h" -#include "intif.h" -#include "pc.h" -#include "status.h" -#include "mob.h" -#include "guild.h" -#include "itemdb.h" -#include "skill.h" -#include "battle.h" -#include "party.h" -#include "npc.h" -#include "log.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define MIN_MOBTHINKTIME 100 - -#define MOB_LAZYMOVEPERC 50 // Move probability in the negligent mode MOB (rate of 1000 minute) -#define MOB_LAZYWARPPERC 20 // Warp probability in the negligent mode MOB (rate of 1000 minute) - -struct mob_db mob_db[MAX_MOB_DB+1]; - -#define CLASSCHANGE_BOSS_NUM 21 - -/*========================================== - * Local prototype declaration (only required thing) - *------------------------------------------ - */ -static int distance(int,int,int,int); -static int mob_makedummymobdb(int); -static int mob_timer(int,unsigned int,int,int); -int mobskill_use(struct mob_data *md,unsigned int tick,int event); -int mobskill_deltimer(struct mob_data *md ); -int mob_skillid2skillidx(int class_,int skillid); -int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx); -static int mob_unlocktarget(struct mob_data *md,int tick); - -/*========================================== - * Mob is searched with a name. - *------------------------------------------ - */ -int mobdb_searchname(const char *str) -{ - int i; - - for(i=0;i<sizeof(mob_db)/sizeof(mob_db[0]);i++){ - if( strcmpi(mob_db[i].name,str)==0 || strcmp(mob_db[i].jname,str)==0 || - memcmp(mob_db[i].name,str,24)==0 || memcmp(mob_db[i].jname,str,24)==0) - return i; - } - - return 0; -} - -/*========================================== - * Id Mob is checked. - *------------------------------------------ - */ -int mobdb_checkid(const int id) -{ - if (id <= 0 || id >= (sizeof(mob_db) / sizeof(mob_db[0])) || mob_db[id].name[0] == '\0') - return 0; - - return id; -} - -/*========================================== - * The minimum data set for MOB spawning - *------------------------------------------ - */ -int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class_) -{ - nullpo_retr(0, md); - - md->bl.prev=NULL; - md->bl.next=NULL; - if(strcmp(mobname,"--en--")==0) - memcpy(md->name,mob_db[class_].name,24); - else if(strcmp(mobname,"--ja--")==0) - memcpy(md->name,mob_db[class_].jname,24); - else - memcpy(md->name,mobname,24); - - md->n = 0; - md->base_class = md->class_ = class_; - md->bl.id= npc_get_new_npc_id(); - - memset(&md->state,0,sizeof(md->state)); - md->timer = -1; - md->target_id=0; - md->attacked_id=0; - md->speed=mob_db[class_].speed; - - return 0; -} - - -/*========================================== - * The MOB appearance for one time (for scripts) - *------------------------------------------ - */ -int mob_once_spawn (struct map_session_data *sd, char *mapname, - int x, int y, const char *mobname, int class_, int amount, const char *event) -{ - struct mob_data *md = NULL; - int m, count, lv = 255; - int i, j; - - if(sd) lv = sd->status.base_level; - - if(sd && strcmp(mapname,"this")==0) - m = sd->bl.m; - else - m = map_mapname2mapid(mapname); - - if (m < 0 || amount <= 0 || (class_ >= 0 && class_ <= 1000) || class_ > MAX_MOB_DB + 4000) // 値が異常なら召喚を止める - return 0; - - if (class_ < 0) { // ランダムに召喚 - int k; - i = 0; - j = -class_-1; - if(j >= 0 && j < MAX_RANDOMMONSTER) { - do { - class_ = rand() % 1000 + 1001; - k = rand() % 1000000; - } while ((mob_db[class_].max_hp <= 0 || mob_db[class_].summonper[j] <= k || - (battle_config.random_monster_checklv && lv < mob_db[class_].lv)) && (i++) < 2000); - if(i >= 2000) - class_ = mob_db[0].summonper[j]; - } else - return 0; -// if(battle_config.etc_log) -// printf("mobclass=%d try=%d\n",class_,i); - } - if (sd) { //even if the coords were wrong, spawn mob anyways (but look for most suitable coords first) Got from Freya [Lupus] - if (x <= 0 || y <= 0) { - if (x <= 0) x = sd->bl.x + rand() % 3 - 1; - if (y <= 0) y = sd->bl.y + rand() % 3 - 1; - if (map_getcell(m, x, y, CELL_CHKNOPASS)) { - x = sd->bl.x; - y = sd->bl.y; - } - } - } else if (x <= 0 || y <= 0) { - i = j = 0; - printf("mob_once_spawn: %i at %s x:%i y:%i\n ??\n",class_,map[m].name,x,y); //got idea from Freya [Lupus] - do { - x = rand() % (map[m].xs - 2) + 1; - y = rand() % (map[m].ys - 2) + 1; - } while ((i = map_getcell(m, x, y, CELL_CHKNOPASS)) && j++ < 64); - if (i) { // not solved? - x = 0; - y = 0; - } - } - - for (count = 0; count < amount; count++) { - md = (struct mob_data *)aCalloc(1,sizeof(struct mob_data)); - memset (md, '\0', sizeof *md); - - if (class_ > MAX_MOB_DB + 2000) { // large/tiny mobs [Valaris] - md->size = 2; - class_ -= (MAX_MOB_DB + 2000); - } else if (class_ > MAX_MOB_DB) { - md->size = 1; - class_ -= MAX_MOB_DB; - } - - if(mob_db[class_].mode & 0x02) - md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item)); - else - md->lootitem = NULL; - - mob_spawn_dataset (md, mobname, class_); - md->bl.m = m; - md->bl.x = x; - md->bl.y = y; - if (class_ < 0 && battle_config.dead_branch_active) - md->mode = 0x1 + 0x4 + 0x80; //移動してアクティブで反撃する - md->m = m; - md->x0 = x; - md->y0 = y; - //md->xs = 0; - //md->ys = 0; - md->spawndelay1 = -1; // 一度のみフラグ - md->spawndelay2 = -1; // 一度のみフラグ - - memcpy(md->npc_event, event, strlen(event)); - - md->bl.type = BL_MOB; - map_addiddb (&md->bl); - mob_spawn (md->bl.id); - - if(class_ == 1288) { // emperium hp based on defense level [Valaris] - struct guild_castle *gc = guild_mapname2gc(map[md->bl.m].name); - if(gc) { - mob_db[class_].max_hp += 2000 * gc->defense; - md->hp = mob_db[class_].max_hp; - } - } // end addition [Valaris] - } - return (amount > 0) ? md->bl.id : 0; -} -/*========================================== - * The MOB appearance for one time (& area specification for scripts) - *------------------------------------------ - */ -int mob_once_spawn_area(struct map_session_data *sd,char *mapname, - int x0,int y0,int x1,int y1, - const char *mobname,int class_,int amount,const char *event) -{ - int x,y,i,max,lx=-1,ly=-1,id=0; - int m; - - if(strcmp(mapname,"this")==0) - m=sd->bl.m; - else - m=map_mapname2mapid(mapname); - - max=(y1-y0+1)*(x1-x0+1)*3; - if(max>1000)max=1000; - - if(m<0 || amount<=0 || (class_>=0 && class_<=1000) || class_>MAX_MOB_DB) // A summon is stopped if a value is unusual - return 0; - - for(i=0;i<amount;i++){ - int j=0; - do{ - x=rand()%(x1-x0+1)+x0; - y=rand()%(y1-y0+1)+y0; - } while (map_getcell(m,x,y,CELL_CHKNOPASS) && (++j)<max); - // freya }while( ( (c=map_getcell(m,x,y))==1 || c==5)&& (++j)<max ); - if(j>=max){ - if(lx>=0){ // Since reference went wrong, the place which boiled before is used. - x=lx; - y=ly; - }else - return 0; // Since reference of the place which boils first went wrong, it stops. - } - if(x==0||y==0) printf("xory=0, x=%d,y=%d,x0=%d,y0=%d\n",x,y,x0,y0); - id=mob_once_spawn(sd,mapname,x,y,mobname,class_,1,event); - lx=x; - ly=y; - } - return id; -} - -/*========================================== - * Summoning Guardians [Valaris] - *------------------------------------------ - */ -int mob_spawn_guardian(struct map_session_data *sd,char *mapname, - int x,int y,const char *mobname,int class_,int amount,const char *event,int guardian) -{ - struct mob_data *md=NULL; - int m,count=1,lv=255; - - if( sd ) - lv=sd->status.base_level; - - if( sd && strcmp(mapname,"this")==0) - m=sd->bl.m; - else - m=map_mapname2mapid(mapname); - - if(m<0 || amount<=0 || (class_>=0 && class_<=1000) || class_>MAX_MOB_DB) // Invalid monster classes - return 0; - - if(class_<0) - return 0; - - if(sd){ - if(x<=0) x=sd->bl.x; - if(y<=0) y=sd->bl.y; - } - - else if(x<=0 || y<=0) - printf("mob_spawn_guardian: ??\n"); - - - for(count=0;count<amount;count++){ - struct guild_castle *gc; - md=(struct mob_data *) aCalloc(sizeof(struct mob_data), 1); - memset(md, '\0', sizeof *md); - - mob_spawn_dataset(md,mobname,class_); - md->bl.m=m; - md->bl.x=x; - md->bl.y=y; - md->m =m; - md->x0=x; - md->y0=y; - md->xs=0; - md->ys=0; - md->spawndelay1=-1; // Only once is a flag. - md->spawndelay2=-1; // Only once is a flag. - - memcpy(md->npc_event,event,sizeof(md->npc_event)); - - md->bl.type=BL_MOB; - map_addiddb(&md->bl); - mob_spawn(md->bl.id); - - gc=guild_mapname2gc(map[md->bl.m].name); - if(gc) { - mob_db[class_].max_hp+=2000*gc->defense; - if(guardian==0) { md->hp=gc->Ghp0; gc->GID0=md->bl.id; } - if(guardian==1) { md->hp=gc->Ghp1; gc->GID1=md->bl.id; } - if(guardian==2) { md->hp=gc->Ghp2; gc->GID2=md->bl.id; } - if(guardian==3) { md->hp=gc->Ghp3; gc->GID3=md->bl.id; } - if(guardian==4) { md->hp=gc->Ghp4; gc->GID4=md->bl.id; } - if(guardian==5) { md->hp=gc->Ghp5; gc->GID5=md->bl.id; } - if(guardian==6) { md->hp=gc->Ghp6; gc->GID6=md->bl.id; } - if(guardian==7) { md->hp=gc->Ghp7; gc->GID7=md->bl.id; } - } - } - - return (amount>0)?md->bl.id:0; -} - -/*========================================== - * The disregard ID is added to mob. - *------------------------------------------ - */ -int mob_exclusion_add(struct mob_data *md,int type,int id) -{ - nullpo_retr(0, md); - - if(type==1) - md->exclusion_src=id; - if(type==2) - md->exclusion_party=id; - if(type==3) - md->exclusion_guild=id; - - return 0; -} - -/*========================================== - * The disregard ID of mob is checked. (TAGE?) - *------------------------------------------ - */ -int mob_exclusion_check(struct mob_data *md,struct map_session_data *sd) -{ - nullpo_retr(0, sd); - nullpo_retr(0, md); - - if(sd->bl.type==BL_PC){ - if(md->exclusion_src && md->exclusion_src==sd->bl.id) - return 1; - if(md->exclusion_party && md->exclusion_party==sd->status.party_id) - return 2; - if(md->exclusion_guild && md->exclusion_guild==sd->status.guild_id) - return 3; - } - return 0; -} - -/*========================================== - * Appearance income of mob - *------------------------------------------ - */ -int mob_get_viewclass(int class_) -{ - return mob_db[class_].view_class; -} -int mob_get_sex(int class_) -{ - return mob_db[class_].sex; -} -short mob_get_hair(int class_) -{ - return mob_db[class_].hair; -} -short mob_get_hair_color(int class_) -{ - return mob_db[class_].hair_color; -} -short mob_get_weapon(int class_) -{ - return mob_db[class_].weapon; -} -short mob_get_shield(int class_) -{ - return mob_db[class_].shield; -} -short mob_get_head_top(int class_) -{ - return mob_db[class_].head_top; -} -short mob_get_head_mid(int class_) -{ - return mob_db[class_].head_mid; -} -short mob_get_head_buttom(int class_) -{ - return mob_db[class_].head_buttom; -} -short mob_get_clothes_color(int class_) // Add for player monster dye - Valaris -{ - return mob_db[class_].clothes_color; // End -} -int mob_get_equip(int class_) // mob equip [Valaris] -{ - return mob_db[class_].equip; -} -/*========================================== - * Is MOB in the state in which the present movement is possible or not? - *------------------------------------------ - */ -int mob_can_move(struct mob_data *md) -{ - nullpo_retr(0, md); - - if(md->canmove_tick > gettick() || (md->opt1 > 0 && md->opt1 != 6) || md->option&2) - return 0; - // アンクル中で動けないとか - if( md->sc_data[SC_ANKLE].timer != -1 || //アンクルスネア - md->sc_data[SC_AUTOCOUNTER].timer != -1 || //オートカウンター - md->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り - md->sc_data[SC_SPIDERWEB].timer != -1 //スパイダーウェッブ - ) - return 0; - - return 1; -} - -/*========================================== - * Time calculation concerning one step next to mob - *------------------------------------------ - */ -static int calc_next_walk_step(struct mob_data *md) -{ - nullpo_retr(0, md); - - if(md->walkpath.path_pos>=md->walkpath.path_len) - return -1; - if(md->walkpath.path[md->walkpath.path_pos]&1) - return status_get_speed(&md->bl)*14/10; - return status_get_speed(&md->bl); -} - -static int mob_walktoxy_sub(struct mob_data *md); - -/*========================================== - * Mob Walk processing - *------------------------------------------ - */ -static int mob_walk(struct mob_data *md,unsigned int tick,int data) -{ - int moveblock; - int i; - static int dirx[8]={0,-1,-1,-1,0,1,1,1}; - static int diry[8]={1,1,0,-1,-1,-1,0,1}; - int x,y,dx,dy; - - nullpo_retr(0, md); - - md->state.state=MS_IDLE; - if(md->walkpath.path_pos>=md->walkpath.path_len || md->walkpath.path_pos!=data) - return 0; - - md->walkpath.path_half ^= 1; - if(md->walkpath.path_half==0){ - md->walkpath.path_pos++; - if(md->state.change_walk_target){ - mob_walktoxy_sub(md); - return 0; - } - } - else { - if(md->walkpath.path[md->walkpath.path_pos]>=8) - return 1; - - x = md->bl.x; - y = md->bl.y; - if(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS)) { - mob_stop_walking(md,1); - return 0; - } - md->dir=md->walkpath.path[md->walkpath.path_pos]; - dx = dirx[md->dir]; - dy = diry[md->dir]; - - if (map_getcell(md->bl.m,x+dx,y+dy,CELL_CHKBASILICA) && !(status_get_mode(&md->bl)&0x20)) { - mob_stop_walking(md,1); - return 0; - } - - if (map_getcell(md->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) { - mob_walktoxy_sub(md); - return 0; - } - - if (skill_check_moonlit (&md->bl,x+dx,y+dy)) { - mob_walktoxy_sub(md); - return 0; - } - moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE); - - md->state.state=MS_WALK; - map_foreachinmovearea(clif_moboutsight,md->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,md); - - x += dx; - y += dy; - if(md->min_chase>13) - md->min_chase--; - - skill_unit_move(&md->bl,tick,0); - if(moveblock) map_delblock(&md->bl); - md->bl.x = x; - md->bl.y = y; - if(moveblock) map_addblock(&md->bl); - skill_unit_move(&md->bl,tick,1); - - map_foreachinmovearea(clif_mobinsight,md->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,md); - md->state.state=MS_IDLE; - - if(md->option&4) - skill_check_cloaking(&md->bl); - } - if((i=calc_next_walk_step(md))>0){ - i = i>>1; - if(i < 1 && md->walkpath.path_half == 0) - i = 1; - md->timer=add_timer(tick+i,mob_timer,md->bl.id,md->walkpath.path_pos); - md->state.state=MS_WALK; - - if(md->walkpath.path_pos>=md->walkpath.path_len) - clif_fixmobpos(md); // とまったときに位置の再送信 - } - return 0; -} - -/*========================================== - * Attack processing of mob - *------------------------------------------ - */ -static int mob_attack(struct mob_data *md,unsigned int tick,int data) -{ - struct block_list *tbl=NULL; - struct map_session_data *tsd=NULL; - struct mob_data *tmd=NULL; - - int mode,race,range; - - nullpo_retr(0, md); - - md->min_chase=13; - md->state.state=MS_IDLE; - md->state.skillstate=MSS_IDLE; - - if( md->skilltimer!=-1 ) // スキル使用中 - return 0; - - if(md->opt1>0 || md->option&2) - return 0; - - if(md->sc_data[SC_AUTOCOUNTER].timer != -1) - return 0; - - if(md->sc_data[SC_BLADESTOP].timer != -1) - return 0; - - if((tbl=map_id2bl(md->target_id))==NULL){ - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - return 0; - } - - if(tbl->type==BL_PC) - tsd=(struct map_session_data *)tbl; - else if(tbl->type==BL_MOB) - tmd=(struct mob_data *)tbl; - else - return 0; - - if(tsd){ - if( pc_isdead(tsd) || tsd->invincible_timer != -1 || pc_isinvisible(tsd) || md->bl.m != tbl->m || tbl->prev == NULL || distance(md->bl.x,md->bl.y,tbl->x,tbl->y)>=13 ){ - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - return 0; - } - } - if(tmd){ - if(md->bl.m != tbl->m || tbl->prev == NULL || distance(md->bl.x,md->bl.y,tbl->x,tbl->y)>=13){ - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - return 0; - } - } - - - if(!md->mode) - mode=mob_db[md->class_].mode; - else - mode=md->mode; - - race=mob_db[md->class_].race; - if(!(mode&0x80)){ - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - return 0; - } - if(tsd && !(mode&0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 || tsd->sc_data[SC_BASILICA].timer != -1 || - ((pc_ishiding(tsd) || tsd->state.gangsterparadise) && !((race == 4 || race == 6) && !tsd->perfect_hiding) ) ) ) { - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - return 0; - } - - range = mob_db[md->class_].range; - if(mode&1) - range++; - if(distance(md->bl.x,md->bl.y,tbl->x,tbl->y) > range) - return 0; - if(battle_config.monster_attack_direction_change) - md->dir=map_calc_dir(&md->bl, tbl->x,tbl->y ); // 向き設定 - - //clif_fixmobpos(md); - - md->state.skillstate=MSS_ATTACK; - if( mobskill_use(md,tick,-2) ) // スキル使用 - return 0; - - md->target_lv = battle_weapon_attack(&md->bl,tbl,tick,0); - - if(!(battle_config.monster_cloak_check_type&2) && md->sc_data[SC_CLOAKING].timer != -1) - status_change_end(&md->bl,SC_CLOAKING,-1); - - md->attackabletime = tick + status_get_adelay(&md->bl); - - md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0); - md->state.state=MS_ATTACK; - - return 0; -} - - -/*========================================== - * The attack of PC which is attacking id is stopped. - * The callback function of clif_foreachclient - *------------------------------------------ - */ -int mob_stopattacked(struct map_session_data *sd,va_list ap) -{ - int id; - - nullpo_retr(0, sd); - nullpo_retr(0, ap); - - id=va_arg(ap,int); - if(sd->attacktarget==id) - pc_stopattack(sd); - return 0; -} -/*========================================== - * The timer in which the mob's states changes - *------------------------------------------ - */ -int mob_changestate(struct mob_data *md,int state,int type) -{ - unsigned int tick; - int i; - - nullpo_retr(0, md); - - if(md->timer != -1) - delete_timer(md->timer,mob_timer); - md->timer=-1; - md->state.state=state; - - switch(state){ - case MS_WALK: - if((i=calc_next_walk_step(md))>0){ - i = i>>2; - md->timer=add_timer(gettick()+i,mob_timer,md->bl.id,0); - } - else - md->state.state=MS_IDLE; - break; - case MS_ATTACK: - tick = gettick(); - i=DIFF_TICK(md->attackabletime,tick); - if(i>0 && i<2000) - md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0); - else if(type) { - md->attackabletime = tick + status_get_amotion(&md->bl); - md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0); - } - else { - md->attackabletime = tick + 1; - md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0); - } - break; - case MS_DELAY: - md->timer=add_timer(gettick()+type,mob_timer,md->bl.id,0); - break; - case MS_DEAD: - skill_castcancel(&md->bl,0); -// mobskill_deltimer(md); - md->state.skillstate=MSS_DEAD; - md->last_deadtime=gettick(); - // Since it died, all aggressors' attack to this mob is stopped. - clif_foreachclient(mob_stopattacked,md->bl.id); - skill_unit_move(&md->bl,gettick(),0); - status_change_clear(&md->bl,2); // ステータス異常を解除する - skill_clear_unitgroup(&md->bl); // 全てのスキルユニットグループを削除する - skill_cleartimerskill(&md->bl); - if(md->deletetimer!=-1) - delete_timer(md->deletetimer,mob_timer_delete); - md->deletetimer=-1; - md->hp=md->target_id=md->attacked_id=0; - md->state.targettype = NONE_ATTACKABLE; - break; - } - - return 0; -} - -/*========================================== - * timer processing of mob (timer function) - * It branches to a walk and an attack. - *------------------------------------------ - */ -static int mob_timer(int tid,unsigned int tick,int id,int data) -{ - struct mob_data *md; - struct block_list *bl; - - if( (bl=map_id2bl(id)) == NULL ){ //攻撃してきた敵がもういないのは正常のようだ - return 1; - } - - if(!bl || !bl->type || bl->type!=BL_MOB) - return 1; - - nullpo_retr(1, md=(struct mob_data*)bl); - - if(md->timer != tid){ - if(battle_config.error_log) - printf("mob_timer %d != %d\n",md->timer,tid); - return 0; - } - md->timer=-1; - if(md->bl.prev == NULL || md->state.state == MS_DEAD) - return 1; - - map_freeblock_lock(); - switch(md->state.state){ - case MS_WALK: - mob_walk(md,tick,data); - break; - case MS_ATTACK: - mob_attack(md,tick,data); - break; - case MS_DELAY: - mob_changestate(md,MS_IDLE,0); - break; - default: - if(battle_config.error_log) - printf("mob_timer : %d ?\n",md->state.state); - break; - } - - if (md->timer == -1) - mob_changestate(md,MS_WALK,0); - - map_freeblock_unlock(); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static int mob_walktoxy_sub(struct mob_data *md) -{ - struct walkpath_data wpd; - int x,y; - static int dirx[8]={0,-1,-1,-1,0,1,1,1}; - static int diry[8]={1,1,0,-1,-1,-1,0,1}; - - nullpo_retr(0, md); - - memset(&wpd, 0, sizeof(wpd)); - - if(path_search(&wpd,md->bl.m,md->bl.x,md->bl.y,md->to_x,md->to_y,md->state.walk_easy)) - return 1; - if (wpd.path[0] >= 8) - return 1; - x = md->bl.x+dirx[wpd.path[0]]; - y = md->bl.y+diry[wpd.path[0]]; - if (map_getcell(md->bl.m,x,y,CELL_CHKBASILICA) && !(status_get_mode(&md->bl)&0x20)) { - md->state.change_walk_target=0; - return 1; - } - - memcpy(&md->walkpath,&wpd,sizeof(wpd)); - - md->state.change_walk_target=0; - mob_changestate(md,MS_WALK,0); - clif_movemob(md); - - return 0; -} - -/*========================================== - * mob move start - *------------------------------------------ - */ -int mob_walktoxy(struct mob_data *md,int x,int y,int easy) -{ - struct walkpath_data wpd; - - nullpo_retr(0, md); - - if(md->state.state == MS_WALK && path_search(&wpd,md->bl.m,md->bl.x,md->bl.y,x,y,easy) ) - return 1; - - md->state.walk_easy = easy; - md->to_x=x; - md->to_y=y; - if(md->state.state == MS_WALK) - md->state.change_walk_target=1; - else - return mob_walktoxy_sub(md); - - return 0; -} - -/*========================================== - * mob spawn with delay (timer function) - *------------------------------------------ - */ -static int mob_delayspawn(int tid,unsigned int tick,int m,int n) -{ - mob_spawn(m); - return 0; -} - -/*========================================== - * spawn timing calculation - *------------------------------------------ - */ -int mob_setdelayspawn(int id) -{ - unsigned int spawntime,spawntime1,spawntime2,spawntime3; - struct mob_data *md; - struct block_list *bl; - - if((bl=map_id2bl(id)) == NULL) - return -1; - - if(!bl || !bl->type || bl->type!=BL_MOB) - return -1; - - nullpo_retr(-1, md=(struct mob_data*)bl); - - if(!md || md->bl.type!=BL_MOB) - return -1; - - // Processing of MOB which is not revitalized - if(md->spawndelay1==-1 && md->spawndelay2==-1 && md->n==0){ - map_deliddb(&md->bl); - if(md->lootitem) { - map_freeblock(md->lootitem); - md->lootitem=NULL; - } - map_freeblock(md); // Instead of [ of free ] - return 0; - } - - spawntime1=md->last_spawntime+md->spawndelay1; - spawntime2=md->last_deadtime+md->spawndelay2; - spawntime3=gettick()+5000+rand()%5000; //Lupus - // spawntime = max(spawntime1,spawntime2,spawntime3); - if(DIFF_TICK(spawntime1,spawntime2)>0) - spawntime=spawntime1; - else - spawntime=spawntime2; - - if(DIFF_TICK(spawntime3,spawntime)>0) - spawntime=spawntime3; - - add_timer(spawntime,mob_delayspawn,id,0); - return 0; -} - -/*========================================== - * Mob spawning. Initialization is also variously here. - *------------------------------------------ - */ -int mob_spawn(int id) -{ - int x=0,y=0,i=0,c; - unsigned int tick = gettick(); - struct mob_data *md; - struct block_list *bl; - - //nullpo_retr(-1, bl=map_id2bl(id)); - bl=map_id2bl(id); - - if(!bl || !bl->type || bl->type!=BL_MOB) - return -1; - - nullpo_retr(-1, md=(struct mob_data*)bl); - - if(!md || !md->bl.type || md->bl.type!=BL_MOB) - return -1; - - md->last_spawntime=tick; - if( md->bl.prev!=NULL ){ -// clif_clearchar_area(&md->bl,3); -// skill_unit_move(&md->bl,tick,0); - map_delblock(&md->bl); - } - else - md->class_ = md->base_class; - - md->bl.m =md->m; - do { - if(md->x0==0 && md->y0==0){ - x=rand()%(map[md->bl.m].xs-2)+1; - y=rand()%(map[md->bl.m].ys-2)+1; - } else { - x=md->x0+rand()%(md->xs+1)-md->xs/2; - y=md->y0+rand()%(md->ys+1)-md->ys/2; - } - i++; - } while(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS) && i<50); - - if(i>=50){ -// if(battle_config.error_log==1) -// printf("MOB spawn error %d @ %s\n",id,map[md->bl.m].name); - add_timer(tick+5000,mob_delayspawn,id,0); - return 1; - } - - md->to_x=md->bl.x=x; - md->to_y=md->bl.y=y; - md->dir=0; - md->target_dir=0; - - memset(&md->state,0,sizeof(md->state)); - md->attacked_id = 0; - md->target_id = 0; - md->move_fail_count = 0; - - if(!md->speed) - md->speed = mob_db[md->class_].speed; - md->def_ele = mob_db[md->class_].element; - - if(!md->level) // [Valaris] - md->level=mob_db[md->class_].lv; - - md->master_id=0; - md->master_dist=0; - - md->state.state = MS_IDLE; - md->state.skillstate = MSS_IDLE; - md->timer = -1; - md->last_thinktime = tick; - md->next_walktime = tick+rand()%50+5000; - md->attackabletime = tick; - md->canmove_tick = tick; - - md->guild_id = 0; - if (md->class_ >= 1285 && md->class_ <= 1288) { - struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name); - if(gc) - md->guild_id = gc->guild_id; - } - - md->deletetimer=-1; - - md->skilltimer=-1; - for(i=0,c=tick-1000*3600*10;i<MAX_MOBSKILL;i++) - md->skilldelay[i] = c; - md->skillid=0; - md->skilllv=0; - - memset(md->dmglog,0,sizeof(md->dmglog)); - if(md->lootitem) - memset(md->lootitem,0,sizeof(md->lootitem)); - md->lootitem_count = 0; - - for(i=0;i<MAX_MOBSKILLTIMERSKILL;i++) - md->skilltimerskill[i].timer = -1; - - for(i=0;i<MAX_STATUSCHANGE;i++) { - md->sc_data[i].timer=-1; - md->sc_data[i].val1 = md->sc_data[i].val2 = md->sc_data[i].val3 = md->sc_data[i].val4 =0; - } - md->sc_count=0; - md->opt1=md->opt2=md->opt3=md->option=0; - - memset(md->skillunit,0,sizeof(md->skillunit)); - memset(md->skillunittick,0,sizeof(md->skillunittick)); - - md->hp = status_get_max_hp(&md->bl); - if(md->hp<=0){ - mob_makedummymobdb(md->class_); - md->hp = status_get_max_hp(&md->bl); - } - - map_addblock(&md->bl); - skill_unit_move(&md->bl,tick,1); - - clif_spawnmob(md); - - return 0; -} - -/*========================================== - * Distance calculation between two points - *------------------------------------------ - */ -static int distance(int x0,int y0,int x1,int y1) -{ - int dx,dy; - - dx=abs(x0-x1); - dy=abs(y0-y1); - return dx>dy ? dx : dy; -} - -/*========================================== - * The stop of MOB's attack - *------------------------------------------ - */ -int mob_stopattack(struct mob_data *md) -{ - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - md->attacked_id=0; - return 0; -} -/*========================================== - * The stop of MOB's walking - *------------------------------------------ - */ -int mob_stop_walking(struct mob_data *md,int type) -{ - nullpo_retr(0, md); - - if(md->state.state == MS_WALK || md->state.state == MS_IDLE) { - int dx=0,dy=0; - - md->walkpath.path_len=0; - if(type&4){ - dx=md->to_x-md->bl.x; - if(dx<0) - dx=-1; - else if(dx>0) - dx=1; - dy=md->to_y-md->bl.y; - if(dy<0) - dy=-1; - else if(dy>0) - dy=1; - } - md->to_x=md->bl.x+dx; - md->to_y=md->bl.y+dy; - if(dx!=0 || dy!=0){ - mob_walktoxy_sub(md); - return 0; - } - mob_changestate(md,MS_IDLE,0); - } - if(type&0x01) - clif_fixmobpos(md); - if(type&0x02) { - int delay=status_get_dmotion(&md->bl); - unsigned int tick = gettick(); - if(battle_config.monster_damage_delay && md->canmove_tick < tick) - md->canmove_tick = tick + delay; - } - - return 0; -} - -/*========================================== - * Reachability to a Specification ID existence place - *------------------------------------------ - */ -int mob_can_reach(struct mob_data *md,struct block_list *bl,int range) -{ - int dx,dy; - struct walkpath_data wpd; - int i; - - nullpo_retr(0, md); - nullpo_retr(0, bl); - - dx=abs(bl->x - md->bl.x); - dy=abs(bl->y - md->bl.y); - - if( md->bl.m != bl->m) // 違うャbプ - return 0; - - if( range>0 && range < ((dx>dy)?dx:dy) ) // 遠すぎる - return 0; - - if( md->bl.x==bl->x && md->bl.y==bl->y ) // 同じマス - return 1; - - //=========== guildcastle guardian no search start=========== - //when players are the guild castle member not attack them ! - /*if(md->class_ >= 1285 && md->class_ <= 1287){ - struct map_session_data *sd; - struct guild *g=NULL; - struct guild_castle *gc=guild_mapname2gc(map[bl->m].name); - - if(gc && agit_flag==0) // Guardians will not attack during non-woe time [Valaris] - return 0; // end addition [Valaris] - - if(gc && bl->type == BL_PC){ - nullpo_retr(0, sd=(struct map_session_data *)bl); - if(gc && sd->status.guild_id > 0) { - g=guild_search(sd->status.guild_id); // don't attack guild members [Valaris] - if(g && g->guild_id == gc->guild_id) - return 0; - if(g && gc && guild_isallied(g,gc)) - return 0; - } - } - }*/ - //========== guildcastle guardian no search eof============== - - /*if(bl->type == BL_PC && battle_config.monsters_ignore_gm) { // option to have monsters ignore GMs [Valaris] - struct map_session_data *sd; - if((sd=(struct map_session_data *)bl) != NULL && pc_isGM(sd) >= battle_config.monsters_ignore_gm) - return 0; - }*/ - - // Obstacle judging - wpd.path_len=0; - wpd.path_pos=0; - wpd.path_half=0; - if(path_search(&wpd,md->bl.m,md->bl.x,md->bl.y,bl->x,bl->y,0)!=-1) - return 1; - - if(bl->type!=BL_PC && bl->type!=BL_MOB) - return 0; - - // It judges whether it can adjoin or not. - dx=(dx>0)?1:((dx<0)?-1:0); - dy=(dy>0)?1:((dy<0)?-1:0); - if(path_search(&wpd,md->bl.m,md->bl.x,md->bl.y,bl->x-dx,bl->y-dy,0)!=-1) - return 1; - for(i=0;i<9;i++){ - if(path_search(&wpd,md->bl.m,md->bl.x,md->bl.y,bl->x-1+i/3,bl->y-1+i%3,0)!=-1) - return 1; - } - return 0; -} - -/*========================================== - * Determination for an attack of a monster - *------------------------------------------ - */ -int mob_target(struct mob_data *md,struct block_list *bl,int dist) -{ - struct map_session_data *sd; - struct status_change *sc_data; - short *option; - int mode,race; - - nullpo_retr(0, md); - nullpo_retr(0, bl); - - sc_data = status_get_sc_data(bl); - option = status_get_option(bl); - race=mob_db[md->class_].race; - - if(!md->mode) - mode=mob_db[md->class_].mode; - else - mode=md->mode; - - if(!(mode&0x80)) { - md->target_id = 0; - return 0; - } - // Nothing will be carried out if there is no mind of changing TAGE by TAGE ending. - if( (md->target_id > 0 && md->state.targettype == ATTACKABLE) && (!(mode&0x04) || rand()%100>25) && - // if the monster was provoked ignore the above rule [celest] - !(md->state.provoke_flag && md->state.provoke_flag == bl->id)) - return 0; - - if(mode&0x20 || // Coercion is exerted if it is MVPMOB. - (sc_data && sc_data[SC_TRICKDEAD].timer == -1 && sc_data[SC_BASILICA].timer == -1 && - ( (option && !(*option&0x06) ) || race==4 || race==6) ) ) { - if(bl->type == BL_PC) { - nullpo_retr(0, sd = (struct map_session_data *)bl); - if(sd->invincible_timer != -1 || pc_isinvisible(sd)) - return 0; - if(!(mode&0x20) && race!=4 && race!=6 && sd->state.gangsterparadise) - return 0; - } - - md->target_id = bl->id; // Since there was no disturbance, it locks on to target. - if(bl->type == BL_PC || bl->type == BL_MOB) - md->state.targettype = ATTACKABLE; - else - md->state.targettype = NONE_ATTACKABLE; - if (md->state.provoke_flag) - md->state.provoke_flag = 0; - md->min_chase=dist+13; - if(md->min_chase>26) - md->min_chase=26; - } - return 0; -} - -/*========================================== - * The ?? routine of an active monster - *------------------------------------------ - */ -static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap) -{ - struct map_session_data *tsd=NULL; - struct mob_data *smd,*tmd=NULL; - int mode,race,dist,*pcc; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, smd=va_arg(ap,struct mob_data *)); - nullpo_retr(0, pcc=va_arg(ap,int *)); - - if(bl->type==BL_PC) - tsd=(struct map_session_data *)bl; - else if(bl->type==BL_MOB) - tmd=(struct mob_data *)bl; - else - return 0; - - //敵味方判定 - if(battle_check_target(&smd->bl,bl,BCT_ENEMY)==0) - return 0; - - if(!smd->mode) - mode=mob_db[smd->class_].mode; - else - mode=smd->mode; - - // アクティブでターゲット射程内にいるなら、ロックする - if( mode&0x04 ){ - race=mob_db[smd->class_].race; - //対象がPCの場合 - if(tsd && - !pc_isdead(tsd) && - tsd->bl.m == smd->bl.m && - tsd->invincible_timer == -1 && - !pc_isinvisible(tsd) && - (dist=distance(smd->bl.x,smd->bl.y,tsd->bl.x,tsd->bl.y))<9 - ) - { - if(mode&0x20 || - (tsd->sc_data[SC_TRICKDEAD].timer == -1 && tsd->sc_data[SC_BASILICA].timer == -1 && - ((!pc_ishiding(tsd) && !tsd->state.gangsterparadise) || ((race == 4 || race == 6) && !tsd->perfect_hiding) ))){ // 妨害がないか判定 - if( mob_can_reach(smd,bl,12) && // 到達可能性判定 - rand()%1000<1000/(++(*pcc)) ){ // 範囲内PCで等確率にする - smd->target_id=tsd->bl.id; - smd->state.targettype = ATTACKABLE; - smd->min_chase=13; - } - } - } - //対象がMobの場合 - else if(tmd && - tmd->bl.m == smd->bl.m && - (dist=distance(smd->bl.x,smd->bl.y,tmd->bl.x,tmd->bl.y))<9 - ) - { - if( mob_can_reach(smd,bl,12) && // 到達可能性判定 - rand()%1000<1000/(++(*pcc)) ){ // 範囲内で等確率にする - smd->target_id=bl->id; - smd->state.targettype = ATTACKABLE; - smd->min_chase=13; - } - } - } - return 0; -} - -/*========================================== - * loot monster item search - *------------------------------------------ - */ -static int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap) -{ - struct mob_data* md; - int mode,dist,*itc; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, md=va_arg(ap,struct mob_data *)); - nullpo_retr(0, itc=va_arg(ap,int *)); - - if(!md->mode) - mode=mob_db[md->class_].mode; - else - mode=md->mode; - - - if( !md->target_id && mode&0x02){ - if(!md->lootitem || (battle_config.monster_loot_type == 1 && md->lootitem_count >= LOOTITEM_SIZE) ) - return 0; - if(bl->m == md->bl.m && (dist=distance(md->bl.x,md->bl.y,bl->x,bl->y))<9){ - if( mob_can_reach(md,bl,12) && // Reachability judging - rand()%1000<1000/(++(*itc)) ){ // It is made a probability, such as within the limits PC. - md->target_id=bl->id; - md->state.targettype = NONE_ATTACKABLE; - md->min_chase=13; - } - } - } - return 0; -} - -/*========================================== - * The ?? routine of a link monster - *------------------------------------------ - */ -static int mob_ai_sub_hard_linksearch(struct block_list *bl,va_list ap) -{ - struct mob_data *tmd; - struct mob_data* md; - struct block_list *target; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, tmd=(struct mob_data *)bl); - nullpo_retr(0, md=va_arg(ap,struct mob_data *)); - nullpo_retr(0, target=va_arg(ap,struct block_list *)); - - // same family free in a range at a link monster -- it will be made to lock if MOB is -/* if( (md->target_id > 0 && md->state.targettype == ATTACKABLE) && mob_db[md->class_].mode&0x08){ - if( tmd->class_==md->class_ && (!tmd->target_id || md->state.targettype == NONE_ATTACKABLE) && tmd->bl.m == md->bl.m){ - if( mob_can_reach(tmd,target,12) ){ // Reachability judging - tmd->target_id=md->target_id; - tmd->state.targettype = ATTACKABLE; - tmd->min_chase=13; - } - } - }*/ - if( md->attacked_id > 0 && mob_db[md->class_].mode&0x08){ - if( tmd->class_==md->class_ && tmd->bl.m == md->bl.m && (!tmd->target_id || md->state.targettype == NONE_ATTACKABLE)){ - if( mob_can_reach(tmd,target,12) ){ // Reachability judging - tmd->target_id=md->attacked_id; - tmd->state.targettype = ATTACKABLE; - tmd->min_chase=13; - } - } - } - - return 0; -} -/*========================================== - * Processing of slave monsters - *------------------------------------------ - */ -static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) -{ - struct mob_data *mmd=NULL; - struct block_list *bl; - int mode,race,old_dist; - - nullpo_retr(0, md); - - if((bl=map_id2bl(md->master_id)) != NULL ) - mmd=(struct mob_data *)bl; - - mode=mob_db[md->class_].mode; - - // It is not main monster/leader. - if(!mmd || mmd->bl.type!=BL_MOB || mmd->bl.id!=md->master_id) - return 0; - - // 呼び戻し - if(mmd->recall_flag == 1){ - if (mmd->recallcount < (mmd->recallmob_count+2) ){ - mob_warp(md,-1,mmd->bl.x,mmd->bl.y,3); - mmd->recallcount += 1; - } else{ - mmd->recall_flag = 0; - mmd->recallcount=0; - } - md->state.master_check = 1; - return 0; - } - // Since it is in the map on which the master is not, teleport is carried out and it pursues. - if( mmd->bl.m != md->bl.m ){ - mob_warp(md,mmd->bl.m,mmd->bl.x,mmd->bl.y,3); - md->state.master_check = 1; - return 0; - } - - // Distance with between slave and master is measured. - old_dist=md->master_dist; - md->master_dist=distance(md->bl.x,md->bl.y,mmd->bl.x,mmd->bl.y); - - // Since the master was in near immediately before, teleport is carried out and it pursues. - if( old_dist<10 && md->master_dist>18){ - mob_warp(md,-1,mmd->bl.x,mmd->bl.y,3); - md->state.master_check = 1; - return 0; - } - - // Although there is the master, since it is somewhat far, it approaches. - if((!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mob_can_move(md) && - (md->walkpath.path_pos>=md->walkpath.path_len || md->walkpath.path_len==0) && md->master_dist<15){ - int i=0,dx,dy,ret; - if(md->master_dist>4) { - do { - if(i<=5){ - dx=mmd->bl.x - md->bl.x; - dy=mmd->bl.y - md->bl.y; - if(dx<0) dx+=(rand()%( (dx<-3)?3:-dx )+1); - else if(dx>0) dx-=(rand()%( (dx>3)?3:dx )+1); - if(dy<0) dy+=(rand()%( (dy<-3)?3:-dy )+1); - else if(dy>0) dy-=(rand()%( (dy>3)?3:dy )+1); - }else{ - dx=mmd->bl.x - md->bl.x + rand()%7 - 3; - dy=mmd->bl.y - md->bl.y + rand()%7 - 3; - } - - ret=mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0); - i++; - } while(ret && i<10); - } - else { - do { - dx = rand()%9 - 5; - dy = rand()%9 - 5; - if( dx == 0 && dy == 0) { - dx = (rand()%1)? 1:-1; - dy = (rand()%1)? 1:-1; - } - dx += mmd->bl.x; - dy += mmd->bl.y; - - ret=mob_walktoxy(md,mmd->bl.x+dx,mmd->bl.y+dy,0); - i++; - } while(ret && i<10); - } - - md->next_walktime=tick+500; - md->state.master_check = 1; - } - - // There is the master, the master locks a target and he does not lock. - if( (mmd->target_id>0 && mmd->state.targettype == ATTACKABLE) && (!md->target_id || md->state.targettype == NONE_ATTACKABLE) ){ - struct map_session_data *sd=map_id2sd(mmd->target_id); - if(sd!=NULL && !pc_isdead(sd) && sd->invincible_timer == -1 && !pc_isinvisible(sd)){ - - race=mob_db[md->class_].race; - if(mode&0x20 || - (sd->sc_data[SC_TRICKDEAD].timer == -1 && sd->sc_data[SC_BASILICA].timer == -1 && - ( (!pc_ishiding(sd) && !sd->state.gangsterparadise) || ((race == 4 || race == 6) && !sd->perfect_hiding) ) ) ){ // 妨害がないか判定 - - md->target_id=sd->bl.id; - md->state.targettype = ATTACKABLE; - md->min_chase=5+distance(md->bl.x,md->bl.y,sd->bl.x,sd->bl.y); - md->state.master_check = 1; - } - } - } - - // There is the master, the master locks a target and he does not lock. -/* if( (md->target_id>0 && mmd->state.targettype == ATTACKABLE) && (!mmd->target_id || mmd->state.targettype == NONE_ATTACKABLE) ){ - struct map_session_data *sd=map_id2sd(md->target_id); - if(sd!=NULL && !pc_isdead(sd) && sd->invincible_timer == -1 && !pc_isinvisible(sd)){ - - race=mob_db[mmd->class_].race; - if(mode&0x20 || - (sd->sc_data[SC_TRICKDEAD].timer == -1 && - (!(sd->status.option&0x06) || race==4 || race==6) - ) ){ // It judges whether there is any disturbance. - - mmd->target_id=sd->bl.id; - mmd->state.targettype = ATTACKABLE; - mmd->min_chase=5+distance(mmd->bl.x,mmd->bl.y,sd->bl.x,sd->bl.y); - } - } - }*/ - - return 0; -} - -/*========================================== - * A lock of target is stopped and mob moves to a standby state. - *------------------------------------------ - */ -static int mob_unlocktarget(struct mob_data *md,int tick) -{ - nullpo_retr(0, md); - - md->target_id=0; - md->state.targettype = NONE_ATTACKABLE; - md->state.skillstate=MSS_IDLE; - md->next_walktime=tick+rand()%3000+3000; - return 0; -} -/*========================================== - * Random walk - *------------------------------------------ - */ -static int mob_randomwalk(struct mob_data *md,int tick) -{ - const int retrycount=20; - int speed; - - nullpo_retr(0, md); - - speed=status_get_speed(&md->bl); - if(DIFF_TICK(md->next_walktime,tick)<0){ - int i,x,y,c,d=12-md->move_fail_count; - int mask[8][2] = {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}}; - if(d<5) d=5; - for(i=0;i<retrycount;i++){ // Search of a movable place - int r=rand(); - x=r%(d*2+1)-d; - y=r/(d*2+1)%(d*2+1)-d; - if (md->target_dir){ - if (x<0) x=0-x; - if (y<0) y=0-y; - x *= mask[md->target_dir-1][0]; - y *= mask[md->target_dir-1][1]; - } - x+=md->bl.x; - y+=md->bl.y; - - if((map_getcell(md->bl.m,x,y,CELL_CHKPASS)) && mob_walktoxy(md,x,y,1)==0){ - md->move_fail_count=0; - break; - } - if(i+1>=retrycount){ - md->move_fail_count++; - md->target_dir = 0; - if(md->move_fail_count>1000){ - if(battle_config.error_log) - printf("MOB cant move. random spawn %d, class = %d\n",md->bl.id,md->class_); - md->move_fail_count=0; - mob_spawn(md->bl.id); - } - } - } - for(i=c=0;i<md->walkpath.path_len;i++){ // The next walk start time is calculated. - if(md->walkpath.path[i]&1) - c+=speed*14/10; - else - c+=speed; - } - md->next_walktime = tick+rand()%3000+3000+c; - md->state.skillstate=MSS_WALK; - return 1; - } - return 0; -} - -/*========================================== - * AI of MOB whose is near a Player - *------------------------------------------ - */ -static int mob_ai_sub_hard(struct block_list *bl,va_list ap) -{ - struct mob_data *md,*tmd=NULL; - struct map_session_data *tsd=NULL; - struct block_list *tbl=NULL; - struct flooritem_data *fitem; - unsigned int tick; - int i,dx,dy,ret,dist; - int attack_type=0; - int mode,race; - int search_size = AREA_SIZE*2; - int blind_flag = 0; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, md=(struct mob_data*)bl); - - tick=va_arg(ap,unsigned int); - - if(DIFF_TICK(tick,md->last_thinktime)<MIN_MOBTHINKTIME) - return 0; - md->last_thinktime=tick; - - if( md->skilltimer!=-1 || md->bl.prev==NULL ){ // Under a skill aria and death - if(DIFF_TICK(tick,md->next_walktime)>MIN_MOBTHINKTIME) - md->next_walktime=tick; - return 0; - } - - if(!md->mode) - mode=mob_db[md->class_].mode; - else - mode=md->mode; - - race=mob_db[md->class_].race; - - // Abnormalities - if((md->opt1 > 0 && md->opt1 != 6) || md->state.state==MS_DELAY || md->sc_data[SC_BLADESTOP].timer != -1) - return 0; - - if (md->sc_data && md->sc_data[SC_BLIND].timer != -1) - blind_flag = 1; - - if(!(mode&0x80) && md->target_id > 0) - md->target_id = 0; - - if(md->attacked_id > 0 && mode&0x08){ // Link monster - struct map_session_data *asd=map_id2sd(md->attacked_id); - if(asd){ - if(asd->invincible_timer == -1 && !pc_isinvisible(asd)){ - map_foreachinarea(mob_ai_sub_hard_linksearch,md->bl.m, - md->bl.x-13,md->bl.y-13, - md->bl.x+13,md->bl.y+13, - BL_MOB,md,&asd->bl); - } - } - } - - // It checks to see it was attacked first (if active, it is target change at 25% of probability). - if( mode>0 && md->attacked_id>0 && (!md->target_id || md->state.targettype == NONE_ATTACKABLE - || (mode&0x04 && rand()%100<25 ) ) ){ - struct block_list *abl=map_id2bl(md->attacked_id); - struct map_session_data *asd=NULL; - if(abl){ - if(abl->type==BL_PC) - asd=(struct map_session_data *)abl; - if(asd==NULL || md->bl.m != abl->m || abl->prev == NULL || asd->invincible_timer != -1 || pc_isinvisible(asd) || - (dist=distance(md->bl.x,md->bl.y,abl->x,abl->y))>=32 || battle_check_target(bl,abl,BCT_ENEMY)==0 || - (blind_flag && dist>3)) - md->attacked_id=0; - else { - //距離が遠い場合はタゲを変更しない - - if (!md->target_id || (distance(md->bl.x,md->bl.y,abl->x,abl->y)<3)) { - md->target_id=md->attacked_id; // set target - md->state.targettype = ATTACKABLE; - attack_type = 1; - md->attacked_id=0; - md->min_chase=dist+13; - if(md->min_chase>26) - md->min_chase=26; - } - } - } - } - - md->state.master_check = 0; - // Processing of slave monster - if( md->master_id > 0 && md->state.special_mob_ai==0) - mob_ai_sub_hard_slavemob(md,tick); - - // アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster) - if( (!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mode&0x04 && !md->state.master_check && - battle_config.monster_active_enable){ - i=0; - search_size = (blind_flag) ? 3 : AREA_SIZE*2; - if(md->state.special_mob_ai){ - map_foreachinarea(mob_ai_sub_hard_activesearch,md->bl.m, - md->bl.x-search_size,md->bl.y-search_size, - md->bl.x+search_size,md->bl.y+search_size, - 0,md,&i); - }else{ - map_foreachinarea(mob_ai_sub_hard_activesearch,md->bl.m, - md->bl.x-search_size,md->bl.y-search_size, - md->bl.x+search_size,md->bl.y+search_size, - BL_PC,md,&i); - } - } - - // The item search of a route monster - if( !md->target_id && mode&0x02 && !md->state.master_check){ - i=0; - search_size = (blind_flag) ? 3 : AREA_SIZE*2; - map_foreachinarea(mob_ai_sub_hard_lootsearch,md->bl.m, - md->bl.x-search_size,md->bl.y-search_size, - md->bl.x+search_size,md->bl.y+search_size, - BL_ITEM,md,&i); - } - - // It will attack, if the candidate for an attack is. - if(md->target_id > 0){ - if((tbl=map_id2bl(md->target_id))){ - if(tbl->type==BL_PC) - tsd=(struct map_session_data *)tbl; - else if(tbl->type==BL_MOB) - tmd=(struct mob_data *)tbl; - if(tsd || tmd) { - if(tbl->m != md->bl.m || tbl->prev == NULL || (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y)) >= search_size || (blind_flag && dist>3)) - mob_unlocktarget(md,tick); // 別マップか、視界外 - else if( tsd && !(mode&0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 || tsd->sc_data[SC_BASILICA].timer != -1 || - ((pc_ishiding(tsd) || tsd->state.gangsterparadise) && - !((race == 4 || race == 6) && !tsd->perfect_hiding) )) ) - mob_unlocktarget(md,tick); // スキルなどによる策敵妨害 - else if(!battle_check_range(&md->bl,tbl,mob_db[md->class_].range)){ - // 攻撃範囲外なので移動 - if(!(mode&1)){ // 移動しないモード - mob_unlocktarget(md,tick); - return 0; - } - if( !mob_can_move(md) ) // 動けない状態にある - return 0; - md->state.skillstate=MSS_CHASE; // 突撃時スキル - mobskill_use(md,tick,-1); -// if(md->timer != -1 && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tsd->bl.x,tsd->bl.y)<2) ) - if(md->timer != -1 && md->state.state!=MS_ATTACK && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tbl->x,tbl->y)<2) ) - return 0; // 既に移動中 - search_size = (blind_flag) ? 3 : - ((md->min_chase > 13) ? md->min_chase : 13); - if(!mob_can_reach(md,tbl, search_size)) - mob_unlocktarget(md,tick); // 移動できないのでタゲ解除(IWとか?) - else { - // 追跡 - md->next_walktime=tick+500; - i=0; - do { - if(i==0){ // 最初はAEGISと同じ方法で検索 - dx=tbl->x - md->bl.x; - dy=tbl->y - md->bl.y; - if(dx<0) dx++; - else if(dx>0) dx--; - if(dy<0) dy++; - else if(dy>0) dy--; - }else{ // だめならAthena式(ランダム) - dx=tbl->x - md->bl.x + rand()%3 - 1; - dy=tbl->y - md->bl.y + rand()%3 - 1; - } - /* if(path_search(&md->walkpath,md->bl.m,md->bl.x,md->bl.y,md->bl.x+dx,md->bl.y+dy,0)){ - dx=tsd->bl.x - md->bl.x; - dy=tsd->bl.y - md->bl.y; - if(dx<0) dx--; - else if(dx>0) dx++; - if(dy<0) dy--; - else if(dy>0) dy++; - }*/ - ret=mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0); - i++; - } while(ret && i<5); - - if(ret){ // 移動不可能な所からの攻撃なら2歩下る - if(dx<0) dx=2; - else if(dx>0) dx=-2; - if(dy<0) dy=2; - else if(dy>0) dy=-2; - mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0); - } - } - } else { // 攻撃射程範囲内 - md->state.skillstate=MSS_ATTACK; - if(md->state.state==MS_WALK) - mob_stop_walking(md,1); // 歩行中なら停止 - if(md->state.state==MS_ATTACK) - return 0; // 既に攻撃中 - mob_changestate(md,MS_ATTACK,attack_type); - } - return 0; - } else { // ルートモンスター処理 - if(tbl == NULL || tbl->type != BL_ITEM ||tbl->m != md->bl.m || - (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase || !md->lootitem | - (blind_flag && dist>=4)){ - // 遠すぎるかアイテムがなくなった - mob_unlocktarget(md,tick); - if(md->state.state==MS_WALK) - mob_stop_walking(md,1); // 歩行中なら停止 - } else if(dist) { - if(!(mode&1)){ // 移動しないモード - mob_unlocktarget(md,tick); - return 0; - } - if( !mob_can_move(md) ) // 動けない状態にある - return 0; - md->state.skillstate=MSS_LOOT; // ルート時スキル使用 - mobskill_use(md,tick,-1); -// if(md->timer != -1 && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tbl->x,tbl->y)<2) ) - if(md->timer != -1 && md->state.state!=MS_ATTACK && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tbl->x,tbl->y) <= 0)) - return 0; // 既に移動中 - md->next_walktime=tick+500; - dx=tbl->x - md->bl.x; - dy=tbl->y - md->bl.y; -/* if(path_search(&md->walkpath,md->bl.m,md->bl.x,md->bl.y,md->bl.x+dx,md->bl.y+dy,0)){ - dx=tbl->x - md->bl.x; - dy=tbl->y - md->bl.y; - }*/ - ret=mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0); - if(ret) - mob_unlocktarget(md,tick);// 移動できないのでタゲ解除(IWとか?) - }else{ // アイテムまでたどり着いた - if(md->state.state==MS_ATTACK) - return 0; // 攻撃中 - if(md->state.state==MS_WALK) - mob_stop_walking(md,1); // 歩行中なら停止 - fitem = (struct flooritem_data *)tbl; - if(md->lootitem_count < LOOTITEM_SIZE) - memcpy(&md->lootitem[md->lootitem_count++],&fitem->item_data,sizeof(md->lootitem[0])); - else if(battle_config.monster_loot_type == 1 && md->lootitem_count >= LOOTITEM_SIZE) { - mob_unlocktarget(md,tick); - return 0; - } - else { - if(md->lootitem[0].card[0] == (short)0xff00) - intif_delete_petdata(*((long *)(&md->lootitem[0].card[1]))); - for(i=0;i<LOOTITEM_SIZE-1;i++) - memcpy(&md->lootitem[i],&md->lootitem[i+1],sizeof(md->lootitem[0])); - memcpy(&md->lootitem[LOOTITEM_SIZE-1],&fitem->item_data,sizeof(md->lootitem[0])); - } - map_clearflooritem(tbl->id); - mob_unlocktarget(md,tick); - } - return 0; - } - }else{ - mob_unlocktarget(md,tick); - if(md->state.state==MS_WALK) - mob_stop_walking(md,4); // 歩行中なら停止 - return 0; - } - } - - // It is skill use at the time of /standby at the time of a walk. - if( mobskill_use(md,tick,-1) ) - return 0; - - // 歩行処理 - if( mode&1 && mob_can_move(md) && // 移動可能MOB&動ける状態にある - (md->master_id==0 || md->state.special_mob_ai || md->master_dist>10) ){ //取り巻きMOBじゃない - - if( DIFF_TICK(md->next_walktime,tick) > + 7000 && - (md->walkpath.path_len==0 || md->walkpath.path_pos>=md->walkpath.path_len) ){ - md->next_walktime = tick + 3000*rand()%2000; - } - - // Random movement - if( mob_randomwalk(md,tick) ) - return 0; - } - - // Since he has finished walking, it stands by. - if( md->walkpath.path_len==0 || md->walkpath.path_pos>=md->walkpath.path_len ) - md->state.skillstate=MSS_IDLE; - return 0; -} - -/*========================================== - * Serious processing for mob in PC field of view (foreachclient) - *------------------------------------------ - */ -static int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) -{ - unsigned int tick; - nullpo_retr(0, sd); - nullpo_retr(0, ap); - - tick=va_arg(ap,unsigned int); - map_foreachinarea(mob_ai_sub_hard,sd->bl.m, - sd->bl.x-AREA_SIZE*2,sd->bl.y-AREA_SIZE*2, - sd->bl.x+AREA_SIZE*2,sd->bl.y+AREA_SIZE*2, - BL_MOB,tick); - - return 0; -} - -/*========================================== - * Serious processing for mob in PC field of view (interval timer function) - *------------------------------------------ - */ -static int mob_ai_hard(int tid,unsigned int tick,int id,int data) -{ - clif_foreachclient(mob_ai_sub_foreachclient,tick); - - return 0; -} - -/*========================================== - * Negligent mode MOB AI (PC is not in near) - *------------------------------------------ - */ -static int mob_ai_sub_lazy(void * key,void * data,va_list app) -{ - struct mob_data *md=(struct mob_data *)data; - struct mob_data *mmd=NULL; - unsigned int tick; - va_list ap; - - nullpo_retr(0, md); - nullpo_retr(0, app); - nullpo_retr(0, ap=va_arg(app,va_list)); - - if(md->bl.type!=BL_MOB) - return 0; - - if (md->master_id > 0) { - mmd = (struct mob_data *)map_id2bl(md->master_id); //自分のBOSSの情報 - } - - tick=va_arg(ap,unsigned int); - - if(DIFF_TICK(tick,md->last_thinktime)<MIN_MOBTHINKTIME*10) - return 0; - md->last_thinktime=tick; - - if(md->bl.prev==NULL || md->skilltimer!=-1){ - if(DIFF_TICK(tick,md->next_walktime)>MIN_MOBTHINKTIME*10) - md->next_walktime=tick; - return 0; - } - - // 取り巻きモンスターの処理(呼び戻しされた時) - if(mmd && md->state.special_mob_ai == 0 && mmd->recall_flag == 1) { - mob_ai_sub_hard_slavemob (md,tick); - return 0; - } - - if(DIFF_TICK(md->next_walktime,tick)<0 && - (mob_db[md->class_].mode&1) && mob_can_move(md) ){ - - if( map[md->bl.m].users>0 ){ - // Since PC is in the same map, somewhat better negligent processing is carried out. - - // It sometimes moves. - if(rand()%1000<MOB_LAZYMOVEPERC) - mob_randomwalk(md,tick); - - // MOB which is not not the summons MOB but BOSS, either sometimes reboils. - else if( rand()%1000<MOB_LAZYWARPPERC && md->x0<=0 && md->master_id!=0 && - mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode & 0x20)) - mob_spawn(md->bl.id); - - }else{ - // Since PC is not even in the same map, suitable processing is carried out even if it takes. - - // MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping - if( rand()%1000<MOB_LAZYWARPPERC && md->x0<=0 && md->master_id!=0 && - mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode & 0x20)) - mob_warp(md,-1,-1,-1,-1); - } - - md->next_walktime = tick+rand()%10000+5000; - } - return 0; -} - -/*========================================== - * Negligent processing for mob outside PC field of view (interval timer function) - *------------------------------------------ - */ -static int mob_ai_lazy(int tid,unsigned int tick,int id,int data) -{ - map_foreachiddb(mob_ai_sub_lazy,tick); - - return 0; -} - - -/*========================================== - * The structure object for item drop with delay - * Since it is only two being able to pass [ int ] a timer function - * Data is put in and passed to this structure object. - *------------------------------------------ - */ -struct delay_item_drop { - int m,x,y; - int nameid,amount; - struct map_session_data *first_sd,*second_sd,*third_sd; -}; - -struct delay_item_drop2 { - int m,x,y; - struct item item_data; - struct map_session_data *first_sd,*second_sd,*third_sd; -}; - -/*========================================== - * item drop with delay (timer function) - *------------------------------------------ - */ -static int mob_delay_item_drop(int tid,unsigned int tick,int id,int data) -{ - struct delay_item_drop *ditem; - struct item temp_item; - int flag, drop_flag = 1; - - nullpo_retr(0, ditem=(struct delay_item_drop *)id); - - memset(&temp_item,0,sizeof(temp_item)); - temp_item.nameid = ditem->nameid; - temp_item.amount = ditem->amount; - temp_item.identify = !itemdb_isequip3(temp_item.nameid); - - if (ditem->first_sd){ - #if 0 - if (ditem->first_sd->status.party_id > 0){ - struct party *p; - if((p=party_search(ditem->first_sd->status.party_id)) && p->item){ - struct map_session_data *sd = NULL; - int i; - for (i = p->itemc + 1; i!=p->itemc; i++) { // initialise counter and loop through the party - if (i >= MAX_PARTY) - i = 0; // reset counter to 1st person in party so it'll stop when it reaches "itemc" - if ((sd=p->member[i].sd)!=NULL && sd->bl.m == ditem->first_sd->bl.m) - break; - } - if (sd){ // if an appropiate party member was found - drop_flag = 0; - if ((p->itemc++) >= MAX_PARTY) - p->itemc = 0; - if ((flag = pc_additem(ditem->first_sd,&temp_item,ditem->amount))) { - clif_additem(ditem->first_sd,0,0,flag); - drop_flag = 1; - } - } - } - } else - #endif - if(battle_config.item_auto_get || ditem->first_sd->autoloot){//Autoloot added by Upa-Kun - drop_flag = 0; - if((flag = pc_additem(ditem->first_sd,&temp_item,ditem->amount))){ - clif_additem(ditem->first_sd,0,0,flag); - drop_flag = 1; - } - } - } - - if (drop_flag) { - map_addflooritem(&temp_item,1,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0); - } - - aFree(ditem); - return 0; -} - -/*========================================== - * item drop (timer function)-lootitem with delay - *------------------------------------------ - */ -static int mob_delay_item_drop2(int tid,unsigned int tick,int id,int data) -{ - struct delay_item_drop2 *ditem; - int flag, drop_flag = 1; - - nullpo_retr(0, ditem=(struct delay_item_drop2 *)id); - - if (ditem->first_sd){ - #if 0 - if (ditem->first_sd->status.party_id > 0){ - struct party *p; - if((p=party_search(ditem->first_sd->status.party_id)) && p->item){ - struct map_session_data *sd = NULL; - int i; - for (i = p->itemc + 1; i!=p->itemc; i++) { // initialise counter and loop through the party - if (i >= MAX_PARTY) - i = 0; // reset counter to 1st person in party so it'll stop when it reaches "itemc" - if ((sd=p->member[i].sd)!=NULL && sd->bl.m == ditem->first_sd->bl.m) - break; - } - if (sd){ // if an appropiate party member was found - drop_flag = 0; - if ((p->itemc++) >= MAX_PARTY) - p->itemc = 0; - if((flag = pc_additem(ditem->first_sd,&ditem->item_data,ditem->item_data.amount))){ - clif_additem(ditem->first_sd,0,0,flag); - drop_flag = 1; - } - } - } - } else - #endif - if(battle_config.item_auto_get || ditem->first_sd->autoloot){//Autoloot added by Upa-Kun - drop_flag = 0; - if((flag = pc_additem(ditem->first_sd,&ditem->item_data,ditem->item_data.amount))){ - clif_additem(ditem->first_sd,0,0,flag); - drop_flag = 1; - } - } - } - - if (drop_flag) { - map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0); - } - - aFree(ditem); - return 0; -} - -/*========================================== - * mob data is erased. - *------------------------------------------ - */ -void mob_unload(struct mob_data *md) -{ - nullpo_retv(md); - mob_remove_map(md, 0); - map_deliddb(&md->bl); - aFree(md); - md = NULL; -} -int mob_remove_map(struct mob_data *md, int type) -{ - nullpo_retr(1, md); - - if(md->bl.prev == NULL) - return 1; - mob_changestate(md,MS_DEAD,0); - clif_clearchar_area(&md->bl,type); - map_delblock(&md->bl); - if (md->lootitem){ - aFree(md->lootitem); - md->lootitem = NULL; - } - - return 0; -} -int mob_delete(struct mob_data *md) -{ - nullpo_retr(1, md); - - mob_remove_map(md, 1); - if (mob_get_viewclass(md->class_) <= 1000) - clif_clearchar_delay(gettick()+3000,&md->bl,0); - mob_deleteslave(md); - mob_setdelayspawn(md->bl.id); - return 0; -} -int mob_timer_delete(int tid, unsigned int tick, int id, int data) -{ - struct mob_data *md=(struct mob_data *)map_id2bl(id); - nullpo_retr(0, md); - -//for Alchemist CANNIBALIZE [Lupus] - mob_remove_map(md, 3); - mob_setdelayspawn(md->bl.id); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int mob_deleteslave_sub(struct block_list *bl,va_list ap) -{ - struct mob_data *md; - int id; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, md = (struct mob_data *)bl); - - id=va_arg(ap,int); - if(md->master_id > 0 && md->master_id == id ) - mob_damage(NULL,md,md->hp,1); - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int mob_deleteslave(struct mob_data *md) -{ - nullpo_retr(0, md); - - map_foreachinarea(mob_deleteslave_sub, md->bl.m, - 0,0,map[md->bl.m].xs,map[md->bl.m].ys, - BL_MOB,md->bl.id); - return 0; -} - -/*========================================== - * It is the damage of sd to damage to md. - *------------------------------------------ - */ -int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) -{ - int i,count,minpos,mindmg; - struct map_session_data *sd = NULL,*tmpsd[DAMAGELOG_SIZE]; - struct { - struct party *p; - int id,base_exp,job_exp,zeny; - } pt[DAMAGELOG_SIZE]; - int pnum=0; - int mvp_damage,max_hp; - unsigned int tick = gettick(); - struct map_session_data *mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL; - struct block_list *master = NULL; - double tdmg,temp; - struct item item; - int ret; - int drop_rate; - int race; - - nullpo_retr(0, md); //srcはNULLで呼ばれる場合もあるので、他でチェック - - max_hp = status_get_max_hp(&md->bl); - race = status_get_race(&md->bl); - - if(src && src->type == BL_PC) { - sd = (struct map_session_data *)src; - mvp_sd = sd; - } - -// if(battle_config.battle_log) -// printf("mob_damage %d %d %d\n",md->hp,max_hp,damage); - if(md->bl.prev==NULL){ - if(battle_config.error_log==1) - printf("mob_damage : BlockError!!\n"); - return 0; - } - - if(md->state.state==MS_DEAD || md->hp<=0) { - if(md->bl.prev != NULL) { - mob_changestate(md,MS_DEAD,0); - mobskill_use(md,tick,-1); // It is skill at the time of death. - clif_clearchar_area(&md->bl,1); - map_delblock(&md->bl); - mob_setdelayspawn(md->bl.id); - } - return 0; - } - - if(battle_config.monster_damage_delay && md->sc_data[SC_ENDURE].timer == -1) - mob_stop_walking(md,3); - if(damage > max_hp>>2) - skill_stop_dancing(&md->bl,0); - - if(md->hp > max_hp) - md->hp = max_hp; - - // The amount of overkill rounds to hp. - if(damage>md->hp) - damage=md->hp; - - if(!(type&2)) { - if(sd!=NULL){ - for(i=0,minpos=0,mindmg=0x7fffffff;i<DAMAGELOG_SIZE;i++){ - //if(md->dmglog[i].id==sd->bl.id) - if(md->dmglog[i].id==sd->status.char_id) - break; - if(md->dmglog[i].id==0){ - minpos=i; - mindmg=0; - } - else if(md->dmglog[i].dmg<mindmg){ - minpos=i; - mindmg=md->dmglog[i].dmg; - } - } - if(i<DAMAGELOG_SIZE) - md->dmglog[i].dmg+=damage; - else { - //md->dmglog[minpos].id=sd->bl.id; - md->dmglog[minpos].id=sd->status.char_id; - md->dmglog[minpos].dmg=damage; - } - - if(md->attacked_id <= 0 && md->state.special_mob_ai==0) - md->attacked_id = sd->bl.id; - } - if(src && src->type == BL_PET && battle_config.pet_attack_exp_to_master==1) { - struct pet_data *pd = (struct pet_data *)src; - nullpo_retr(0, pd); - for(i=0,minpos=0,mindmg=0x7fffffff;i<DAMAGELOG_SIZE;i++){ - //if(md->dmglog[i].id==pd->msd->bl.id) - if(md->dmglog[i].id==pd->msd->status.char_id) - break; - if(md->dmglog[i].id==0){ - minpos=i; - mindmg=0; - } - else if(md->dmglog[i].dmg<mindmg){ - minpos=i; - mindmg=md->dmglog[i].dmg; - } - } - if(i<DAMAGELOG_SIZE) - md->dmglog[i].dmg+=(damage*battle_config.pet_attack_exp_rate)/100; - else { - //md->dmglog[minpos].id=pd->msd->bl.id; - md->dmglog[minpos].id=pd->msd->status.char_id; - md->dmglog[minpos].dmg=(damage*battle_config.pet_attack_exp_rate)/100; - } - } - if(src && src->type == BL_MOB && ((struct mob_data*)src)->state.special_mob_ai){ - struct mob_data *md2 = (struct mob_data *)src; - nullpo_retr(0, md2); - for(i=0,minpos=0,mindmg=0x7fffffff;i<DAMAGELOG_SIZE;i++){ - if(md->dmglog[i].id==md2->master_id) - break; - if(md->dmglog[i].id==0){ - minpos=i; - mindmg=0; - } - else if(md->dmglog[i].dmg<mindmg){ - minpos=i; - mindmg=md->dmglog[i].dmg; - } - } - if(i<DAMAGELOG_SIZE) - md->dmglog[i].dmg+=damage; - else { - md->dmglog[minpos].id=md2->master_id; - md->dmglog[minpos].dmg=damage; - - if(md->attacked_id <= 0 && md->state.special_mob_ai==0) - md->attacked_id = md2->master_id; - } - } - - } - - md->hp-=damage; - - if(md->class_ >= 1285 && md->class_ <=1287) { // guardian hp update [Valaris] - struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name); - if(gc) { - - if(md->bl.id==gc->GID0) { - gc->Ghp0=md->hp; - if(gc->Ghp0<=0) { - guild_castledatasave(gc->castle_id,10,0); - guild_castledatasave(gc->castle_id,18,0); - } - } - if(md->bl.id==gc->GID1) { - gc->Ghp1=md->hp; - if(gc->Ghp1<=0) { - guild_castledatasave(gc->castle_id,11,0); - guild_castledatasave(gc->castle_id,19,0); - } - } - if(md->bl.id==gc->GID2) { - gc->Ghp2=md->hp; - if(gc->Ghp2<=0) { - guild_castledatasave(gc->castle_id,12,0); - guild_castledatasave(gc->castle_id,20,0); - } - } - if(md->bl.id==gc->GID3) { - gc->Ghp3=md->hp; - if(gc->Ghp3<=0) { - guild_castledatasave(gc->castle_id,13,0); - guild_castledatasave(gc->castle_id,21,0); - } - } - if(md->bl.id==gc->GID4) { - gc->Ghp4=md->hp; - if(gc->Ghp4<=0) { - guild_castledatasave(gc->castle_id,14,0); - guild_castledatasave(gc->castle_id,22,0); - } - } - if(md->bl.id==gc->GID5) { - gc->Ghp5=md->hp; - if(gc->Ghp5<=0) { - guild_castledatasave(gc->castle_id,15,0); - guild_castledatasave(gc->castle_id,23,0); - } - } - if(md->bl.id==gc->GID6) { - gc->Ghp6=md->hp; - if(gc->Ghp6<=0) { - guild_castledatasave(gc->castle_id,16,0); - guild_castledatasave(gc->castle_id,24,0); - } - } - if(md->bl.id==gc->GID7) { - gc->Ghp7=md->hp; - if(gc->Ghp7<=0) { - guild_castledatasave(gc->castle_id,17,0); - guild_castledatasave(gc->castle_id,25,0); - - } - } - } - } // end addition [Valaris] - - if(md->option&2 ) - status_change_end(&md->bl, SC_HIDING, -1); - if(md->option&4 ) - status_change_end(&md->bl, SC_CLOAKING, -1); - - if(md->state.special_mob_ai == 2){//スフィアーマイン - int skillidx=0; - - if((skillidx=mob_skillid2skillidx(md->class_,NPC_SELFDESTRUCTION2))>=0){ - md->mode |= 0x1; - md->next_walktime=tick; - mobskill_use_id(md,&md->bl,skillidx);//自爆詠唱開始 - md->state.special_mob_ai++; - } - if (src && md->master_id==src->id) - md->target_dir=map_calc_dir(src,md->bl.x,md->bl.y)+1; - } - - if(md->hp>0){ - if (battle_config.show_mob_hp) - clif_update_mobhp (md); - return 0; - } - - // ----- ここから死亡処理 ----- - - map_freeblock_lock(); - mob_changestate(md,MS_DEAD,0); - mobskill_use(md,tick,-1); // 死亡時スキル - - memset(tmpsd,0,sizeof(tmpsd)); - memset(pt,0,sizeof(pt)); - - max_hp = status_get_max_hp(&md->bl); - - if(src && src->type == BL_MOB) - mob_unlocktarget((struct mob_data *)src,tick); - - - if(sd) { - int sp = 0, hp = 0; - if (sd->state.attack_type == BF_MAGIC && (i=pc_checkskill(sd,HW_SOULDRAIN))>0){ /* ソウルドレイン */ - clif_skill_nodamage(src,&md->bl,HW_SOULDRAIN,i,1); - sp += (status_get_lv(&md->bl))*(65+15*i)/100; - } - sp += sd->sp_gain_value; - sp += sd->sp_gain_race[race]; - hp += sd->hp_gain_value; - if (sp > 0) { - if(sd->status.sp + sp > sd->status.max_sp) - sp = sd->status.max_sp - sd->status.sp; - sd->status.sp += sp; - clif_heal(sd->fd,SP_SP,sp); - } - if (hp > 0) { - if(sd->status.hp + hp > sd->status.max_hp) - hp = sd->status.max_hp - sd->status.hp; - sd->status.hp += hp; - clif_heal(sd->fd,SP_HP,hp); - } - } - - // map外に消えた人は計算から除くので - // overkill分は無いけどsumはmax_hpとは違う - - tdmg = 0; - for(i=0,count=0,mvp_damage=0;i<DAMAGELOG_SIZE;i++){ - if(md->dmglog[i].id==0) - continue; - // Will this slow things down too much? - tmpsd[i] = map_charid2sd(md->dmglog[i].id); - // try finding again - if(tmpsd[i] == NULL) - tmpsd[i] = map_id2sd(md->dmglog[i].id); - // if we still can't find the player - if(tmpsd[i] == NULL) - continue; - count++; - if(tmpsd[i]->bl.m != md->bl.m || pc_isdead(tmpsd[i])) - continue; - - tdmg += (double)md->dmglog[i].dmg; - if(mvp_damage<md->dmglog[i].dmg){ - third_sd = second_sd; - second_sd = mvp_sd; - mvp_sd=tmpsd[i]; - mvp_damage=md->dmglog[i].dmg; - } - } - - // [MouseJstr] - if((map[md->bl.m].flag.pvp == 0) || (battle_config.pvp_exp == 1)) { - - // 経験値の分配 - for(i=0;i<DAMAGELOG_SIZE;i++){ - int pid,base_exp,job_exp,flag=1,zeny=0; - double per; - struct party *p; - if(tmpsd[i]==NULL || tmpsd[i]->bl.m != md->bl.m || pc_isdead(tmpsd[i])) - continue; - - if (battle_config.exp_calc_type == 0) { - // jAthena's exp formula - per = ((double)md->dmglog[i].dmg)*(9.+(double)((count > 6)? 6:count))/10./tdmg; - temp = (double)mob_db[md->class_].base_exp * per; - base_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp; - if(mob_db[md->class_].base_exp > 0 && base_exp < 1) base_exp = 1; - if(base_exp < 0) base_exp = 0; - temp = (double)mob_db[md->class_].job_exp * per; - job_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp; - if(mob_db[md->class_].job_exp > 0 && job_exp < 1) job_exp = 1; - if(job_exp < 0) job_exp = 0; - } - else if (battle_config.exp_calc_type == 1) { - //eAthena's exp formula rather than jAthena's - per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/(double)max_hp; - if(per>512) per=512; - if(per<1) per=1; - base_exp=(int) (mob_db[md->class_].base_exp*per/256); - if(base_exp < 1) base_exp = 1; - job_exp=(int) (mob_db[md->class_].job_exp*per/256); - if(job_exp < 1) job_exp = 1; - } - else { - //eAthena's exp formula rather than jAthena's, but based on total damage dealt - per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/tdmg; - if(per>512) per=512; - if(per<1) per=1; - base_exp=(int) (mob_db[md->class_].base_exp*per/256); - if(base_exp < 1) base_exp = 1; - job_exp=(int) (mob_db[md->class_].job_exp*per/256); - if(job_exp < 1) job_exp = 1; - } - - if(sd) { - int rate; - if ((rate = sd->expaddrace[race]) > 0) { - base_exp = (100+rate)*base_exp/100; - job_exp = (100+rate)*job_exp/100; - } - if (battle_config.pk_mode && (mob_db[md->class_].lv - sd->status.base_level >= 20)) { - base_exp = (int) (base_exp *1.15); // pk_mode additional exp if monster >20 levels [Valaris] - job_exp = (int) (job_exp * 1.15); - } - } - if(md->master_id) { - if(((master = map_id2bl(md->master_id)) && status_get_mode(master)&0x20) || // check if its master is a boss (MVP's and minibosses) - (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) { // for summoned creatures [Valaris] - base_exp = 0; - job_exp = 0; - } - } else { - if(battle_config.zeny_from_mobs) { - if(md->level > 0) zeny=(int) ((md->level+rand()%md->level)*per/256); // zeny calculation moblv + random moblv [Valaris] - if(mob_db[md->class_].mexp > 0) - zeny*=rand()%250; - } - if(battle_config.mobs_level_up && md->level > mob_db[md->class_].lv) { // [Valaris] - job_exp+=(int) (((md->level-mob_db[md->class_].lv)*mob_db[md->class_].job_exp*.03)*per/256); - base_exp+=(int) (((md->level-mob_db[md->class_].lv)*mob_db[md->class_].base_exp*.03)*per/256); - } - } - - if((pid=tmpsd[i]->status.party_id)>0){ // パーティに入っている - int j; - for(j=0;j<pnum;j++) // 公平パーティリストにいるかどうか - if(pt[j].id==pid) - break; - if(j==pnum){ // いないときは公平かどうか確認 - if((p=party_search(pid))!=NULL && p->exp!=0){ - pt[pnum].id=pid; - pt[pnum].p=p; - pt[pnum].base_exp=base_exp; - pt[pnum].job_exp=job_exp; - if(battle_config.zeny_from_mobs) - pt[pnum].zeny=zeny; // zeny share [Valaris] - pnum++; - flag=0; - } - }else{ // いるときは公平 - pt[j].base_exp+=base_exp; - pt[j].job_exp+=job_exp; - if(battle_config.zeny_from_mobs) - pt[j].zeny+=zeny; // zeny share [Valaris] - flag=0; - } - } - if(flag) { // added zeny from mobs [Valaris] - if(base_exp > 0 || job_exp > 0) - pc_gainexp(tmpsd[i],base_exp,job_exp); - if (battle_config.zeny_from_mobs && zeny > 0) { - pc_getzeny(tmpsd[i],zeny); // zeny from mobs [Valaris] - } - } - - } - // 公平分配 - for(i=0;i<pnum;i++) - party_exp_share(pt[i].p,md->bl.m,pt[i].base_exp,pt[i].job_exp,pt[i].zeny); - - // item drop - if(!(type&1)) { - int log_item[10] = {0}; //8 -> 10 Lupus - int drop_ore = -1,drop_items=0; //slot N for DROP LOG, number of dropped items - for(i=0;i<10;i++){ // 8 -> 10 Lupus - struct delay_item_drop *ditem; - int drop_rate; - - if((master && status_get_mode(master)&0x20) || // check if its master is a boss (MVP's and minibosses) - (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) // Added [Valaris] - break; // End - - if(mob_db[md->class_].dropitem[i].nameid <= 0) - continue; - drop_rate = mob_db[md->class_].dropitem[i].p; - if(drop_rate <= 0 && !battle_config.drop_rate0item) - drop_rate = 1; - if(battle_config.drops_by_luk>0 && sd && md) drop_rate+=(sd->status.luk*battle_config.drops_by_luk)/100; // drops affected by luk [Valaris] - if(sd && md && battle_config.pk_mode==1 && (mob_db[md->class_].lv - sd->status.base_level >= 20)) drop_rate = (int) (drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris] - if(drop_rate < rand() % 10000 + 1) { //fixed 0.01% impossible drops bug [Lupus] - drop_ore = i; //we remember an empty slot to put there ORE DISCOVERY drop later. - continue; - } - drop_items++; //we count if there were any drops - - ditem=(struct delay_item_drop *)aCalloc(1,sizeof(struct delay_item_drop)); - ditem->nameid = mob_db[md->class_].dropitem[i].nameid; - log_item[i] = ditem->nameid; - ditem->amount = 1; - ditem->m = md->bl.m; - ditem->x = md->bl.x; - ditem->y = md->bl.y; - ditem->first_sd = mvp_sd; - ditem->second_sd = second_sd; - ditem->third_sd = third_sd; - add_timer(tick+500+i,mob_delay_item_drop,(int)ditem,0); - } - - // Ore Discovery [Celest] - if (sd == mvp_sd && pc_checkskill(sd,BS_FINDINGORE)>0 && battle_config.finding_ore_rate/100 >= rand()%1000) { - struct delay_item_drop *ditem; - ditem=(struct delay_item_drop *)aCalloc(1,sizeof(struct delay_item_drop)); - ditem->nameid = itemdb_searchrandomid(6); - if (drop_ore<0) i=8; //we have only 10 slots in LOG, there's a check to not overflow (9th item usually a card, so we use 8th slot) - log_item[i] = ditem->nameid; //it's for logging only - drop_items++; //we count if there were any drops - ditem->amount = 1; - ditem->m = md->bl.m; - ditem->x = md->bl.x; - ditem->y = md->bl.y; - ditem->first_sd = mvp_sd; - ditem->second_sd = second_sd; - ditem->third_sd = third_sd; - add_timer(tick+500+i,mob_delay_item_drop,(int)ditem,0); - } - - //this drop log contains ALL dropped items + ORE (if there was ORE Recovery) [Lupus] - if(sd && log_config.drop > 0 && drop_items) //we check were there any drops.. and if not - don't write the log - log_drop(sd, md->class_, log_item); //mvp_sd - - if(sd && sd->state.attack_type == BF_WEAPON) { - for(i=0;i<sd->monster_drop_item_count;i++) { - struct delay_item_drop *ditem; - if(sd->monster_drop_itemid[i] <= 0) - continue; - if(sd->monster_drop_race[i] & (1<<race) || - (mob_db[md->class_].mode & 0x20 && sd->monster_drop_race[i] & 1<<10) || - (!(mob_db[md->class_].mode & 0x20) && sd->monster_drop_race[i] & 1<<11) ) { - if(sd->monster_drop_itemrate[i] <= rand()%10000) - continue; - - ditem=(struct delay_item_drop *)aCalloc(1,sizeof(struct delay_item_drop)); - ditem->nameid = sd->monster_drop_itemid[i]; - ditem->amount = 1; - ditem->m = md->bl.m; - ditem->x = md->bl.x; - ditem->y = md->bl.y; - ditem->first_sd = mvp_sd; - ditem->second_sd = second_sd; - ditem->third_sd = third_sd; - add_timer(tick+520+i,mob_delay_item_drop,(int)ditem,0); - } - } - if(sd->get_zeny_num > 0) - pc_getzeny(sd,mob_db[md->class_].lv*10 + rand()%(sd->get_zeny_num+1)); - } - if(md->lootitem) { - for(i=0;i<md->lootitem_count;i++) { - struct delay_item_drop2 *ditem; - - ditem=(struct delay_item_drop2 *)aCalloc(1,sizeof(struct delay_item_drop2)); - memcpy(&ditem->item_data,&md->lootitem[i],sizeof(md->lootitem[0])); - ditem->m = md->bl.m; - ditem->x = md->bl.x; - ditem->y = md->bl.y; - ditem->first_sd = mvp_sd; - ditem->second_sd = second_sd; - ditem->third_sd = third_sd; - add_timer(tick+540+i,mob_delay_item_drop2,(int)ditem,0); - } - } - } - - // mvp処理 - if(mvp_sd && mob_db[md->class_].mexp > 0 ){ - int log_mvp[2] = {0}; - int j; - int mexp; - temp = ((double)mob_db[md->class_].mexp * (9.+(double)count)/10.); //[Gengar] - mexp = (temp > 2147483647.)? 0x7fffffff:(int)temp; - if(mexp < 1) mexp = 1; - clif_mvp_effect(mvp_sd); // エフェクト - clif_mvp_exp(mvp_sd,mexp); - pc_gainexp(mvp_sd,mexp,0); - log_mvp[1] = mexp; - for(j=0;j<3;j++){ - i = rand() % 3; - if(mob_db[md->class_].mvpitem[i].nameid <= 0) - continue; - drop_rate = mob_db[md->class_].mvpitem[i].p; - if(drop_rate <= 0 && !battle_config.drop_rate0item) - drop_rate = 1; -/* if(drop_rate < battle_config.item_drop_mvp_min) - drop_rate = battle_config.item_drop_mvp_min; - else if(drop_rate > battle_config.item_drop_mvp_max) //fixed - drop_rate = battle_config.item_drop_mvp_max; -*/ - if(drop_rate <= rand()%10000+1) //if ==0, then it doesn't drop - continue; - memset(&item,0,sizeof(item)); - item.nameid=mob_db[md->class_].mvpitem[i].nameid; - item.identify=!itemdb_isequip3(item.nameid); - clif_mvp_item(mvp_sd,item.nameid); - log_mvp[0] = item.nameid; - if(mvp_sd->weight*2 > mvp_sd->max_weight) - map_addflooritem(&item,1,mvp_sd->bl.m,mvp_sd->bl.x,mvp_sd->bl.y,mvp_sd,second_sd,third_sd,1); - else if((ret = pc_additem(mvp_sd,&item,1))) { - clif_additem(sd,0,0,ret); - map_addflooritem(&item,1,mvp_sd->bl.m,mvp_sd->bl.x,mvp_sd->bl.y,mvp_sd,second_sd,third_sd,1); - } - break; - } - - if(log_config.mvpdrop > 0) - log_mvpdrop(mvp_sd, md->class_, log_mvp); - } - - } // [MouseJstr] - - // <Agit> NPC Event [OnAgitBreak] - if(md->npc_event[0] && strcmp(((md->npc_event)+strlen(md->npc_event)-13),"::OnAgitBreak") == 0) { - printf("MOB.C: Run NPC_Event[OnAgitBreak].\n"); - if (agit_flag == 1) //Call to Run NPC_Event[OnAgitBreak] - guild_agit_break(md); - } - - // SCRIPT実行 - if(md->npc_event[0]){ -// if(battle_config.battle_log) -// printf("mob_damage : run event : %s\n",md->npc_event); - if(src && src->type == BL_PET) - sd = ((struct pet_data *)src)->msd; - if(sd == NULL) { - if(mvp_sd != NULL) - sd = mvp_sd; - else { - struct map_session_data *tmpsd; - int i; - for(i=0;i<fd_max;i++){ - if(session[i] && (tmpsd= (struct map_session_data *) session[i]->session_data) && tmpsd->state.auth) { - if(md->bl.m == tmpsd->bl.m) { - sd = tmpsd; - break; - } - } - } - } - } - if(sd) - npc_event(sd,md->npc_event,0); - } - - clif_clearchar_area(&md->bl,1); - if(md->level) md->level=0; - map_delblock(&md->bl); - if(mob_get_viewclass(md->class_) <= 1000) - clif_clearchar_delay(tick+3000,&md->bl,0); - mob_deleteslave(md); - mob_setdelayspawn(md->bl.id); - map_freeblock_unlock(); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int mob_class_change(struct mob_data *md,int *value) -{ - unsigned int tick = gettick(); - int i,c,hp_rate,max_hp,class_,count = 0; - - nullpo_retr(0, md); - nullpo_retr(0, value); - - if(value[0]<=1000 || value[0]>MAX_MOB_DB) - return 0; - if(md->bl.prev == NULL) return 0; - - while(count < 5 && value[count] > 1000 && value[count] <= MAX_MOB_DB) count++; - if(count < 1) return 0; - - class_ = value[rand()%count]; - if(class_<=1000 || class_>MAX_MOB_DB) return 0; - - max_hp = status_get_max_hp(&md->bl); - hp_rate = md->hp*100/max_hp; - clif_mob_class_change(md,class_); - md->class_ = class_; - max_hp = status_get_max_hp(&md->bl); - if(battle_config.monster_class_change_full_recover==1) { - md->hp = max_hp; - memset(md->dmglog,0,sizeof(md->dmglog)); - } - else - md->hp = max_hp*hp_rate/100; - if(md->hp > max_hp) md->hp = max_hp; - else if(md->hp < 1) md->hp = 1; - - memcpy(md->name,mob_db[class_].jname,24); - memset(&md->state,0,sizeof(md->state)); - md->attacked_id = 0; - md->target_id = 0; - md->move_fail_count = 0; - - md->speed = mob_db[md->class_].speed; - md->def_ele = mob_db[md->class_].element; - - mob_changestate(md,MS_IDLE,0); - skill_castcancel(&md->bl,0); - md->state.skillstate = MSS_IDLE; - md->last_thinktime = tick; - md->next_walktime = tick+rand()%50+5000; - md->attackabletime = tick; - md->canmove_tick = tick; - - for(i=0,c=tick-1000*3600*10;i<MAX_MOBSKILL;i++) - md->skilldelay[i] = c; - md->skillid=0; - md->skilllv=0; - - if(md->lootitem == NULL && mob_db[class_].mode&0x02) - md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item)); - - skill_clear_unitgroup(&md->bl); - skill_cleartimerskill(&md->bl); - - clif_clearchar_area(&md->bl,0); - clif_spawnmob(md); - - return 0; -} - -/*========================================== - * mob回復 - *------------------------------------------ - */ -int mob_heal(struct mob_data *md,int heal) -{ - int max_hp; - - nullpo_retr(0, md); - max_hp = status_get_max_hp(&md->bl); - - md->hp += heal; - if( max_hp < md->hp ) - md->hp = max_hp; - - if(md->class_ >= 1285 && md->class_ <=1287) { // guardian hp update [Valaris] - struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name); - if(gc) { - if(md->bl.id==gc->GID0) gc->Ghp0=md->hp; - if(md->bl.id==gc->GID1) gc->Ghp1=md->hp; - if(md->bl.id==gc->GID2) gc->Ghp2=md->hp; - if(md->bl.id==gc->GID3) gc->Ghp3=md->hp; - if(md->bl.id==gc->GID4) gc->Ghp4=md->hp; - if(md->bl.id==gc->GID5) gc->Ghp5=md->hp; - if(md->bl.id==gc->GID6) gc->Ghp6=md->hp; - if(md->bl.id==gc->GID7) gc->Ghp7=md->hp; - } - } // end addition [Valaris] - - if (battle_config.show_mob_hp) - clif_update_mobhp(md); - - return 0; -} - - -/*========================================== - * Added by RoVeRT - *------------------------------------------ - */ -int mob_warpslave_sub(struct block_list *bl,va_list ap) -{ - struct mob_data *md=(struct mob_data *)bl; - int id,x,y; - id=va_arg(ap,int); - x=va_arg(ap,int); - y=va_arg(ap,int); - if( md->master_id==id ) { - mob_warp(md,-1,x,y,2); - } - return 0; -} - -/*========================================== - * Added by RoVeRT - *------------------------------------------ - */ -int mob_warpslave(struct mob_data *md,int x, int y) -{ -//printf("warp slave\n"); - map_foreachinarea(mob_warpslave_sub, md->bl.m, - x-AREA_SIZE,y-AREA_SIZE, - x+AREA_SIZE,y+AREA_SIZE,BL_MOB, - md->bl.id, md->bl.x, md->bl.y ); - return 0; -} - -/*========================================== - * mobワープ - *------------------------------------------ - */ -int mob_warp(struct mob_data *md,int m,int x,int y,int type) -{ - int i=0,xs=0,ys=0,bx=x,by=y; - int tick = gettick(); - - nullpo_retr(0, md); - - if( md->bl.prev==NULL ) - return 0; - - if( m<0 ) m=md->bl.m; - - if(type >= 0) { - if(map[md->bl.m].flag.monster_noteleport) - return 0; - clif_clearchar_area(&md->bl,type); - } - skill_unit_move(&md->bl,tick,0); - map_delblock(&md->bl); - - if(bx>0 && by>0){ // 位置指定の場合周囲9セルを探索 - xs=ys=9; - } - - while( ( x<0 || y<0 || map_getcell(m,x,y,CELL_CHKNOPASS)) && (i++)<1000 ){ - if( xs>0 && ys>0 && i<250 ){ // 指定位置付近の探索 - x=bx+rand()%xs-xs/2; - y=by+rand()%ys-ys/2; - }else{ // 完全ランダム探索 - x=rand()%(map[m].xs-2)+1; - y=rand()%(map[m].ys-2)+1; - } - } - md->dir=0; - if(i<1000){ - md->bl.x=md->to_x=x; - md->bl.y=md->to_y=y; - md->bl.m=m; - }else { - m=md->bl.m; - if(battle_config.error_log==1) - printf("MOB %d warp failed, class = %d\n",md->bl.id,md->class_); - } - - md->target_id=0; // タゲを解除する - md->state.targettype=NONE_ATTACKABLE; - md->attacked_id=0; - md->state.skillstate=MSS_IDLE; - mob_changestate(md,MS_IDLE,0); - - if(type>0 && i==1000) { - if(battle_config.battle_log) - printf("MOB %d warp to (%d,%d), class = %d\n",md->bl.id,x,y,md->class_); - } - - map_addblock(&md->bl); - skill_unit_move(&md->bl,tick,1); - if(type>0) - { - clif_spawnmob(md); - mob_warpslave(md,md->bl.x,md->bl.y); - } - - return 0; -} - -/*========================================== - * 画面内の取り巻きの数計算用(foreachinarea) - *------------------------------------------ - */ -int mob_countslave_sub(struct block_list *bl,va_list ap) -{ - int id,*c; - struct mob_data *md; - - id=va_arg(ap,int); - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, c=va_arg(ap,int *)); - nullpo_retr(0, md = (struct mob_data *)bl); - - if( md->master_id==id ) - (*c)++; - return 0; -} -/*========================================== - * 画面内の取り巻きの数計算 - *------------------------------------------ - */ -int mob_countslave(struct mob_data *md) -{ - int c=0; - - nullpo_retr(0, md); - - map_foreachinarea(mob_countslave_sub, md->bl.m, - 0,0,map[md->bl.m].xs-1,map[md->bl.m].ys-1, - BL_MOB,md->bl.id,&c); - return c; -} -/*========================================== - * 手下MOB召喚 - *------------------------------------------ - */ -int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag) -{ - struct mob_data *md; - int bx,by,m,count = 0,class_,k,a = amount; - - nullpo_retr(0, md2); - nullpo_retr(0, value); - - bx=md2->bl.x; - by=md2->bl.y; - m=md2->bl.m; - - if(value[0]<=1000 || value[0]>MAX_MOB_DB) // 値が異常なら召喚を止める - return 0; - while(count < 21 && value[count] > 1000 && value[count] <= 2000) count++; - if(count < 1) return 0; - - for(k=0;k<count;k++) { - amount = a; - class_ = value[k]; - if(class_<=1000 || class_>MAX_MOB_DB) continue; - for(;amount>0;amount--){ - int x=0,y=0,i=0; - md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data)); - if(mob_db[class_].mode&0x02) - md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item)); - else - md->lootitem=NULL; - - while((x<=0 || y<=0 || map_getcell(m,x,y,CELL_CHKNOPASS)) && (i++)<100){ - x=rand()%9-4+bx; - y=rand()%9-4+by; - } - if(i>=100){ - x=bx; - y=by; - } - - mob_spawn_dataset(md,"--ja--",class_); - md->bl.m=m; - md->bl.x=x; - md->bl.y=y; - - md->m =m; - md->x0=x; - md->y0=y; - md->xs=0; - md->ys=0; - md->speed=md2->speed; - md->spawndelay1=-1; // 一度のみフラグ - md->spawndelay2=-1; // 一度のみフラグ - - memset(md->npc_event,0,sizeof(md->npc_event)); - md->bl.type=BL_MOB; - map_addiddb(&md->bl); - mob_spawn(md->bl.id); - clif_skill_nodamage(&md->bl,&md->bl,(flag)? NPC_SUMMONSLAVE:NPC_SUMMONMONSTER,a,1); - - if(flag) - md->master_id=md2->bl.id; - } - } - return 0; -} - -/*========================================== - * 自分をロックしているPCの数を数える(foreachclient) - *------------------------------------------ - */ -static int mob_counttargeted_sub(struct block_list *bl,va_list ap) -{ - int id,*c,target_lv; - struct block_list *src; - - id=va_arg(ap,int); - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, c=va_arg(ap,int *)); - - src=va_arg(ap,struct block_list *); - target_lv=va_arg(ap,int); - if(id == bl->id || (src && id == src->id)) return 0; - if(bl->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)bl; - if(sd && sd->attacktarget == id && sd->attacktimer != -1 && sd->attacktarget_lv >= target_lv) - (*c)++; - } - else if(bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)bl; - if(md && md->target_id == id && md->timer != -1 && md->state.state == MS_ATTACK && md->target_lv >= target_lv) - (*c)++; - } - else if(bl->type == BL_PET) { - struct pet_data *pd = (struct pet_data *)bl; - if(pd->target_id == id && pd->timer != -1 && pd->state.state == MS_ATTACK && pd->target_lv >= target_lv) - (*c)++; - } - return 0; -} -/*========================================== - * 自分をロックしているPCの数を数える - *------------------------------------------ - */ -int mob_counttargeted(struct mob_data *md,struct block_list *src,int target_lv) -{ - int c=0; - - nullpo_retr(0, md); - - map_foreachinarea(mob_counttargeted_sub, md->bl.m, - md->bl.x-AREA_SIZE,md->bl.y-AREA_SIZE, - md->bl.x+AREA_SIZE,md->bl.y+AREA_SIZE,0,md->bl.id,&c,src,target_lv); - return c; -} - -/*========================================== - *MOBskillから該当skillidのskillidxを返す - *------------------------------------------ - */ -int mob_skillid2skillidx(int class_,int skillid) -{ - int i; - struct mob_skill *ms=mob_db[class_].skill; - - if(ms==NULL) - return -1; - - for(i=0;i<mob_db[class_].maxskill;i++){ - if(ms[i].skill_id == skillid) - return i; - } - return -1; - -} - -// -// MOBスキル -// - -/*========================================== - * スキル使用(詠唱完了、ID指定) - *------------------------------------------ - */ -int mobskill_castend_id( int tid, unsigned int tick, int id,int data ) -{ - struct mob_data* md=NULL; - struct block_list *bl; - struct block_list *mbl; - int range; - - if((mbl = map_id2bl(id)) == NULL ) //詠唱したMobがもういないというのは良くある正常処理 - return 0; - if((md=(struct mob_data *)mbl) == NULL ){ - printf("mobskill_castend_id nullpo mbl->id:%d\n",mbl->id); - return 0; - } - - if( md->bl.type!=BL_MOB || md->bl.prev==NULL ) - return 0; - - if( md->skilltimer != tid ) // タイマIDの確認 - return 0; - - md->skilltimer=-1; - //沈黙や状態異常など - if(md->sc_data){ - if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || - (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) || - md->sc_data[SC_STEELBODY].timer != -1) - return 0; - if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //オートカウンター - return 0; - if(md->sc_data[SC_BLADESTOP].timer != -1) //白刃取り - return 0; - if(md->sc_data[SC_BERSERK].timer != -1) //バーサーク - return 0; - } - if(md->skillid != NPC_EMOTION) - md->last_thinktime=tick + status_get_adelay(&md->bl); - - if((bl = map_id2bl(md->skilltarget)) == NULL || bl->prev==NULL){ //スキルターゲットが存在しない - //printf("mobskill_castend_id nullpo\n");//ターゲットがいないときはnullpoじゃなくて普通に終了 - return 0; - } - if(md->bl.m != bl->m) - return 0; - - if(md->skillid == PR_LEXAETERNA) { - struct status_change *sc_data = status_get_sc_data(bl); - if(sc_data && (sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))) - return 0; - } - else if(md->skillid == RG_BACKSTAP) { - int dir = map_calc_dir(&md->bl,bl->x,bl->y),t_dir = status_get_dir(bl); - int dist = distance(md->bl.x,md->bl.y,bl->x,bl->y); - if(bl->type != BL_SKILL && (dist == 0 || map_check_dir(dir,t_dir))) - return 0; - } - if( ( (skill_get_inf(md->skillid)&1) || (skill_get_inf2(md->skillid)&4) ) && // 彼我敵対関係チェック - battle_check_target(&md->bl,bl, BCT_ENEMY)<=0 ) - return 0; - range = skill_get_range(md->skillid,md->skilllv); - if(range < 0) - range = status_get_range(&md->bl) - (range + 1); - if(range + battle_config.mob_skill_add_range < distance(md->bl.x,md->bl.y,bl->x,bl->y)) - return 0; - - md->skilldelay[md->skillidx]=tick; - - if(battle_config.mob_skill_log) - printf("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class_); -// mob_stop_walking(md,0); - - switch( skill_get_nk(md->skillid) ) - { - // 攻撃系/吹き飛ばし系 - case 0: case 2: - skill_castend_damage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0); - break; - case 1:// 支援系 - if(!mob_db[md->class_].skill[md->skillidx].val[0] && - (md->skillid==AL_HEAL || (md->skillid==ALL_RESURRECTION && bl->type != BL_PC)) && battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ) - skill_castend_damage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0); - else - skill_castend_nodamage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0); - break; - } - - - return 0; -} - -/*========================================== - * スキル使用(詠唱完了、場所指定) - *------------------------------------------ - */ -int mobskill_castend_pos( int tid, unsigned int tick, int id,int data ) -{ - struct mob_data* md=NULL; - int range,maxcount; - - nullpo_retr(0, md=(struct mob_data *)map_id2bl(id)); - - if( md->bl.type!=BL_MOB || md->bl.prev==NULL ) - return 0; - - if( md->skilltimer != tid ) // タイマIDの確認 - return 0; - - md->skilltimer=-1; - if(md->sc_data){ - if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || - (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) || - md->sc_data[SC_STEELBODY].timer != -1) - return 0; - if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //オートカウンター - return 0; - if(md->sc_data[SC_BLADESTOP].timer != -1) //白刃取り - return 0; - if(md->sc_data[SC_BERSERK].timer != -1) //バーサーク - return 0; - } - - if (!battle_config.monster_skill_reiteration && - skill_get_unit_flag (md->skillid) & UF_NOREITERATION && - skill_check_unit_range (md->bl.m, md->skillx, md->skilly, md->skillid, md->skilllv)) - return 0; - - if(battle_config.monster_skill_nofootset && - skill_get_unit_flag (md->skillid) & UF_NOFOOTSET && - skill_check_unit_range2(&md->bl, md->bl.m, md->skillx, md->skilly, md->skillid, md->skilllv)) - return 0; - - - if(battle_config.monster_land_skill_limit) { - maxcount = skill_get_maxcount(md->skillid); - if(maxcount > 0) { - int i,c; - for(i=c=0;i<MAX_MOBSKILLUNITGROUP;i++) { - if(md->skillunit[i].alive_count > 0 && md->skillunit[i].skill_id == md->skillid) - c++; - } - if(c >= maxcount) - return 0; - } - } - - range = skill_get_range(md->skillid,md->skilllv); - if(range < 0) - range = status_get_range(&md->bl) - (range + 1); - if(range + battle_config.mob_skill_add_range < distance(md->bl.x,md->bl.y,md->skillx,md->skilly)) - return 0; - md->skilldelay[md->skillidx]=tick; - - if(battle_config.mob_skill_log) - printf("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class_); -// mob_stop_walking(md,0); - - skill_castend_pos2(&md->bl,md->skillx,md->skilly,md->skillid,md->skilllv,tick,0); - - return 0; -} - - -/*========================================== - * Skill use (an aria start, ID specification) - *------------------------------------------ - */ -int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx) -{ - int casttime,range; - struct mob_skill *ms; - int skill_id, skill_lv, forcecast = 0; - - nullpo_retr(0, md); - nullpo_retr(0, ms=&mob_db[md->class_].skill[skill_idx]); - - if( target==NULL && (target=map_id2bl(md->target_id))==NULL ) - return 0; - - if( target->prev==NULL || md->bl.prev==NULL ) - return 0; - - skill_id=ms->skill_id; - skill_lv=ms->skill_lv; - - // 沈黙や異常 - if(md->sc_data){ - if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || - (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) || - md->sc_data[SC_STEELBODY].timer != -1) - return 0; - if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //オートカウンター - return 0; - if(md->sc_data[SC_BLADESTOP].timer != -1) //白刃取り - return 0; - if(md->sc_data[SC_BERSERK].timer != -1) //バーサーク - return 0; - } - - if(md->option&4 && skill_id==TF_HIDING) - return 0; - if(md->option&2 && skill_id!=TF_HIDING && skill_id!=AS_GRIMTOOTH && skill_id!=RG_BACKSTAP && skill_id!=RG_RAID) - return 0; - - if(map[md->bl.m].flag.gvg && skill_db[skill_id].nocast & 4) - return 0; - if(skill_get_inf2(skill_id)&0x200 && md->bl.id == target->id) - return 0; - - // 射程と障害物チェック - range = skill_get_range(skill_id,skill_lv); - if(range < 0) - range = status_get_range(&md->bl) - (range + 1); - if(!battle_check_range(&md->bl,target,range)) - return 0; - -// delay=skill_delayfix(&md->bl, skill_get_delay( skill_id,skill_lv) ); - - casttime=skill_castfix(&md->bl,ms->casttime); - md->state.skillcastcancel=ms->cancel; - md->skilldelay[skill_idx]=gettick(); - - switch(skill_id){ /* 何か特殊な処理が必要 */ - case ALL_RESURRECTION: /* リザレクション */ - if(target->type != BL_PC && battle_check_undead(status_get_race(target),status_get_elem_type(target))){ /* 敵がアンデッドなら */ - forcecast=1; /* ターンアンデットと同じ詠唱時間 */ - casttime=skill_castfix(&md->bl, skill_get_cast(PR_TURNUNDEAD,skill_lv) ); - } - break; - case MO_EXTREMITYFIST: /*阿修羅覇鳳拳*/ - case SA_MAGICROD: - case SA_SPELLBREAKER: - forcecast=1; - break; - case NPC_SUMMONSLAVE: - case NPC_SUMMONMONSTER: - if(md->master_id!=0) - return 0; - break; - } - - if(battle_config.mob_skill_log) - printf("MOB skill use target_id=%d skill=%d lv=%d cast=%d, class = %d\n",target->id,skill_id,skill_lv,casttime,md->class_); - - if(casttime>0 || forcecast){ // 詠唱が必要 -// struct mob_data *md2; - mob_stop_walking(md,0); // 歩行停止 - clif_skillcasting( &md->bl, - md->bl.id, target->id, 0,0, skill_id,casttime); - - // 詠唱反応モンスター - // future homunculus support? -/* if(md->master_id && target->type==BL_MOB && (md2=(struct mob_data *)target) && - mob_db[md2->class_].mode&0x10 && md2->state.state!=MS_ATTACK){ - md2->target_id=md->bl.id; - md->state.targettype = ATTACKABLE; - md2->min_chase=13; - }*/ - } - - if( casttime<=0 ) // 詠唱の無いものはキャンセルされない - md->state.skillcastcancel=0; - - md->skilltarget = target->id; - md->skillx = 0; - md->skilly = 0; - md->skillid = skill_id; - md->skilllv = skill_lv; - md->skillidx = skill_idx; - - if(!(battle_config.monster_cloak_check_type&2) && md->sc_data[SC_CLOAKING].timer != -1 && md->skillid != AS_CLOAKING) - status_change_end(&md->bl,SC_CLOAKING,-1); - - if( casttime>0 ){ - md->skilltimer = - add_timer( gettick()+casttime, mobskill_castend_id, md->bl.id, 0 ); - }else{ - md->skilltimer = -1; - mobskill_castend_id(md->skilltimer,gettick(),md->bl.id, 0); - } - - return 1; -} -/*========================================== - * スキル使用(場所指定) - *------------------------------------------ - */ -int mobskill_use_pos( struct mob_data *md, - int skill_x, int skill_y, int skill_idx) -{ - int casttime=0,range; - struct mob_skill *ms; - struct block_list bl; - int skill_id, skill_lv; - - nullpo_retr(0, md); - nullpo_retr(0, ms=&mob_db[md->class_].skill[skill_idx]); - - if( md->bl.prev==NULL ) - return 0; - - skill_id=ms->skill_id; - skill_lv=ms->skill_lv; - - //沈黙や状態異常など - if(md->sc_data){ - if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || - (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) || - md->sc_data[SC_STEELBODY].timer != -1) - return 0; - if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //オートカウンター - return 0; - if(md->sc_data[SC_BLADESTOP].timer != -1) //白刃取り - return 0; - if(md->sc_data[SC_BERSERK].timer != -1) //バーサーク - return 0; - } - - if(md->option&2) - return 0; - - if(map[md->bl.m].flag.gvg && (skill_id == SM_ENDURE || skill_id == AL_TELEPORT || skill_id == AL_WARP || - skill_id == WZ_ICEWALL || skill_id == TF_BACKSLIDING)) - return 0; - - // 射程と障害物チェック - bl.type = BL_NUL; - bl.m = md->bl.m; - bl.x = skill_x; - bl.y = skill_y; - range = skill_get_range(skill_id,skill_lv); - if(range < 0) - range = status_get_range(&md->bl) - (range + 1); - if(!battle_check_range(&md->bl,&bl,range)) - return 0; - -// delay=skill_delayfix(&sd->bl, skill_get_delay( skill_id,skill_lv) ); - casttime=skill_castfix(&md->bl,ms->casttime); - md->skilldelay[skill_idx]=gettick(); - md->state.skillcastcancel=ms->cancel; - - if(battle_config.mob_skill_log) - printf("MOB skill use target_pos=(%d,%d) skill=%d lv=%d cast=%d, class = %d\n", - skill_x,skill_y,skill_id,skill_lv,casttime,md->class_); - - if( casttime>0 ) { // A cast time is required. - mob_stop_walking(md,0); // 歩行停止 - clif_skillcasting( &md->bl, - md->bl.id, 0, skill_x,skill_y, skill_id,casttime); - } - - if( casttime<=0 ) // A skill without a cast time wont be cancelled. - md->state.skillcastcancel=0; - - - md->skillx = skill_x; - md->skilly = skill_y; - md->skilltarget = 0; - md->skillid = skill_id; - md->skilllv = skill_lv; - md->skillidx = skill_idx; - if(!(battle_config.monster_cloak_check_type&2) && md->sc_data[SC_CLOAKING].timer != -1) - status_change_end(&md->bl,SC_CLOAKING,-1); - if( casttime>0 ){ - md->skilltimer = - add_timer( gettick()+casttime, mobskill_castend_pos, md->bl.id, 0 ); - }else{ - md->skilltimer = -1; - mobskill_castend_pos(md->skilltimer,gettick(),md->bl.id, 0); - } - - return 1; -} - - -/*========================================== - * Friendly Mob whose HP is decreasing by a nearby MOB is looked for. - *------------------------------------------ - */ -int mob_getfriendhpltmaxrate_sub(struct block_list *bl,va_list ap) -{ - int rate; - struct mob_data **fr, *md, *mmd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, mmd=va_arg(ap,struct mob_data *)); - - md=(struct mob_data *)bl; - - if( mmd->bl.id == bl->id ) - return 0; - rate=va_arg(ap,int); - fr=va_arg(ap,struct mob_data **); - if( md->hp < mob_db[md->class_].max_hp*rate/100 ) - (*fr)=md; - return 0; -} -struct mob_data *mob_getfriendhpltmaxrate(struct mob_data *md,int rate) -{ - struct mob_data *fr=NULL; - const int r=8; - - nullpo_retr(NULL, md); - - map_foreachinarea(mob_getfriendhpltmaxrate_sub, md->bl.m, - md->bl.x-r ,md->bl.y-r, md->bl.x+r, md->bl.y+r, - BL_MOB,md,rate,&fr); - return fr; -} -/*========================================== - * What a status state suits by nearby MOB is looked for. - *------------------------------------------ - */ -int mob_getfriendstatus_sub(struct block_list *bl,va_list ap) -{ - int cond1,cond2; - struct mob_data **fr, *md, *mmd; - int flag=0; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, md=(struct mob_data *)bl); - nullpo_retr(0, mmd=va_arg(ap,struct mob_data *)); - - if( mmd->bl.id == bl->id ) - return 0; - cond1=va_arg(ap,int); - cond2=va_arg(ap,int); - fr=va_arg(ap,struct mob_data **); - if( cond2==-1 ){ - int j; - for(j=SC_STONE;j<=SC_BLIND && !flag;j++){ - flag=(md->sc_data[j].timer!=-1 ); - } - }else - flag=( md->sc_data[cond2].timer!=-1 ); - if( flag^( cond1==MSC_FRIENDSTATUSOFF ) ) - (*fr)=md; - - return 0; -} -struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2) -{ - struct mob_data *fr=NULL; - const int r=8; - - nullpo_retr(0, md); - - map_foreachinarea(mob_getfriendstatus_sub, md->bl.m, - md->bl.x-r ,md->bl.y-r, md->bl.x+r, md->bl.y+r, - BL_MOB,md,cond1,cond2,&fr); - return fr; -} - -/*========================================== - * Skill use judging - *------------------------------------------ - */ -int mobskill_use(struct mob_data *md,unsigned int tick,int event) -{ - struct mob_skill *ms; -// struct block_list *target=NULL; - int i,max_hp; - - nullpo_retr(0, md); - nullpo_retr(0, ms = mob_db[md->class_].skill); - - max_hp = status_get_max_hp(&md->bl); - - if(battle_config.mob_skill_use == 0 || md->skilltimer != -1) - return 0; - - if(md->state.special_mob_ai) - return 0; - - if(md->sc_data[SC_SELFDESTRUCTION].timer!=-1) //自爆中はスキルを使わない - return 0; - - for(i=0;i<mob_db[md->class_].maxskill;i++){ - int c2=ms[i].cond2,flag=0; - struct mob_data *fmd=NULL; - - // ディレイ中 - if( DIFF_TICK(tick,md->skilldelay[i])<ms[i].delay ) - continue; - - // 状態判定 - if( ms[i].state>=0 && ms[i].state!=md->state.skillstate ) - continue; - - // 条件判定 - flag=(event==ms[i].cond1); - if(!flag){ - switch( ms[i].cond1 ){ - case MSC_ALWAYS: - flag=1; break; - case MSC_MYHPLTMAXRATE: // HP< maxhp% - flag=( md->hp < max_hp*c2/100 ); break; - case MSC_MYSTATUSON: // status[num] on - case MSC_MYSTATUSOFF: // status[num] off - if( ms[i].cond2==-1 ){ - int j; - for(j=SC_STONE;j<=SC_BLIND && !flag;j++){ - flag=(md->sc_data[j].timer!=-1 ); - } - }else - flag=( md->sc_data[ms[i].cond2].timer!=-1 ); - flag^=( ms[i].cond1==MSC_MYSTATUSOFF ); break; - case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp% - flag=(( fmd=mob_getfriendhpltmaxrate(md,ms[i].cond2) )!=NULL ); break; - case MSC_FRIENDSTATUSON: // friend status[num] on - case MSC_FRIENDSTATUSOFF: // friend status[num] off - flag=(( fmd=mob_getfriendstatus(md,ms[i].cond1,ms[i].cond2) )!=NULL ); break; - case MSC_SLAVELT: // slave < num - flag=( mob_countslave(md) < c2 ); break; - case MSC_ATTACKPCGT: // attack pc > num - flag=( mob_counttargeted(md,NULL,0) > c2 ); break; - case MSC_SLAVELE: // slave <= num - flag=( mob_countslave(md) <= c2 ); break; - case MSC_ATTACKPCGE: // attack pc >= num - flag=( mob_counttargeted(md,NULL,0) >= c2 ); break; - case MSC_SKILLUSED: // specificated skill used - flag=( (event&0xffff)==MSC_SKILLUSED && ((event>>16)==c2 || c2==0)); break; - } - } - - // 確率判定 - if( flag && rand()%10000 < ms[i].permillage ){ - - if( skill_get_inf(ms[i].skill_id)&2 ){ - // 場所指定 - struct block_list *bl = NULL; - int x=0,y=0; - if( ms[i].target<=MST_AROUND ){ - bl= ((ms[i].target==MST_TARGET || ms[i].target==MST_AROUND5)? map_id2bl(md->target_id): - (ms[i].target==MST_FRIEND)? &fmd->bl : &md->bl); - if(bl!=NULL){ - x=bl->x; y=bl->y; - } - } - if( x<=0 || y<=0 ) - continue; - // 自分の周囲 - if( ms[i].target>=MST_AROUND1 ){ - int bx=x, by=y, i=0, m=bl->m, r=ms[i].target-MST_AROUND1; - do{ - bx=x + rand()%(r*2+3) - r; - by=y + rand()%(r*2+3) - r; - }while( ( bx<=0 || by<=0 || bx>=map[m].xs || by>=map[m].ys || - map_getcell(m,bx,by,CELL_CHKNOPASS)) && (i++)<1000); - if(i<1000){ - x=bx; y=by; - } - } - // 相手の周囲 - if( ms[i].target>=MST_AROUND5 ){ - int bx=x, by=y, i=0,m=bl->m, r=(ms[i].target-MST_AROUND5)+1; - do{ - bx=x + rand()%(r*2+1) - r; - by=y + rand()%(r*2+1) - r; - }while( ( bx<=0 || by<=0 || bx>=map[m].xs || by>=map[m].ys || - map_getcell(m,bx,by,CELL_CHKNOPASS)) && (i++)<1000); - if(i<1000){ - x=bx; y=by; - } - } - if(!mobskill_use_pos(md,x,y,i)) - return 0; - - }else{ - // ID指定 - if( ms[i].target<=MST_FRIEND ){ - struct block_list *bl = NULL; - bl= ((ms[i].target==MST_TARGET)? map_id2bl(md->target_id): - (ms[i].target==MST_FRIEND)? &fmd->bl : &md->bl); - if(bl && !mobskill_use_id(md,bl,i)) - return 0; - } - } - if(ms[i].emotion >= 0) - clif_emotion(&md->bl,ms[i].emotion); - return 1; - } - } - - return 0; -} -/*========================================== - * Skill use event processing - *------------------------------------------ - */ -int mobskill_event(struct mob_data *md,int flag) -{ - nullpo_retr(0, md); - - if(flag==-1 && mobskill_use(md,gettick(),MSC_CASTTARGETED)) - return 1; - if( (flag&BF_SHORT) && mobskill_use(md,gettick(),MSC_CLOSEDATTACKED)) - return 1; - if( (flag&BF_LONG) && mobskill_use(md,gettick(),MSC_LONGRANGEATTACKED)) - return 1; - return 0; -} -/*========================================== - * Mobがエンペリウムなどの場合の判定 - *------------------------------------------ - */ -int mob_gvmobcheck(struct map_session_data *sd, struct block_list *bl) -{ - struct mob_data *md=NULL; - - nullpo_retr(0,sd); - nullpo_retr(0,bl); - - if(bl->type==BL_MOB && (md=(struct mob_data *)bl) && - (md->class_ == 1288 || md->class_ == 1287 || md->class_ == 1286 || md->class_ == 1285)) - { - struct guild_castle *gc=guild_mapname2gc(map[sd->bl.m].name); - struct guild *g=guild_search(sd->status.guild_id); - - if(g == NULL && md->class_ == 1288) - return 0;//ギルド未加入ならダメージ無し - else if(gc != NULL && !map[sd->bl.m].flag.gvg) - return 0;//砦内でGvじゃないときはダメージなし - else if(g) { - if (gc != NULL && g->guild_id == gc->guild_id) - return 0;//自占領ギルドのエンペならダメージ無し - else if(guild_checkskill(g,GD_APPROVAL) <= 0 && md->class_ == 1288) - return 0;//正規ギルド承認がないとダメージ無し - else if (gc && guild_check_alliance(gc->guild_id, g->guild_id, 0) == 1) - return 0; // 同盟ならダメージ無し - } - } - - return 1; -} -/*========================================== - * スキル用タイマー削除 - *------------------------------------------ - */ -int mobskill_deltimer(struct mob_data *md ) -{ - nullpo_retr(0, md); - - if( md->skilltimer!=-1 ){ - if( skill_get_inf( md->skillid )&2 ) - delete_timer( md->skilltimer, mobskill_castend_pos ); - else - delete_timer( md->skilltimer, mobskill_castend_id ); - md->skilltimer=-1; - } - return 0; -} -// -// 初期化 -// -/*========================================== - * Since un-setting [ mob ] up was used, it is an initial provisional value setup. - *------------------------------------------ - */ -static int mob_makedummymobdb(int class_) -{ - int i; - - sprintf(mob_db[class_].name,"mob%d",class_); - sprintf(mob_db[class_].jname,"mob%d",class_); - mob_db[class_].lv=1; - mob_db[class_].max_hp=1000; - mob_db[class_].max_sp=1; - mob_db[class_].base_exp=2; - mob_db[class_].job_exp=1; - mob_db[class_].range=1; - mob_db[class_].atk1=7; - mob_db[class_].atk2=10; - mob_db[class_].def=0; - mob_db[class_].mdef=0; - mob_db[class_].str=1; - mob_db[class_].agi=1; - mob_db[class_].vit=1; - mob_db[class_].int_=1; - mob_db[class_].dex=6; - mob_db[class_].luk=2; - mob_db[class_].range2=10; - mob_db[class_].range3=10; - mob_db[class_].size=0; - mob_db[class_].race=0; - mob_db[class_].element=0; - mob_db[class_].mode=0; - mob_db[class_].speed=300; - mob_db[class_].adelay=1000; - mob_db[class_].amotion=500; - mob_db[class_].dmotion=500; - //mob_db[class_].dropitem[0].nameid=909; // Jellopy - //mob_db[class_].dropitem[0].p=1000; - for(i=1;i<10;i++){ // 8-> 10 Lupus - mob_db[class_].dropitem[i].nameid=0; - mob_db[class_].dropitem[i].p=0; - } - // Item1,Item2 - mob_db[class_].mexp=0; - mob_db[class_].mexpper=0; - for(i=0;i<3;i++){ - mob_db[class_].mvpitem[i].nameid=0; - mob_db[class_].mvpitem[i].p=0; - } - for(i=0;i<MAX_RANDOMMONSTER;i++) - mob_db[class_].summonper[i]=0; - return 0; -} - -/*========================================== - * db/mob_db.txt reading - *------------------------------------------ - */ -static int mob_readdb(void) -{ - FILE *fp; - char line[1024]; - char *filename[]={ "db/mob_db.txt","db/mob_db2.txt" }; - int i; - - memset(mob_db,0,sizeof(mob_db)); - - for(i=0;i<2;i++){ - - fp=fopen(filename[i],"r"); - if(fp==NULL){ - if(i>0) - continue; - return -1; - } - while(fgets(line,1020,fp)){ - int class_,i; - char *str[60],*p,*np; // 55->60 Lupus - - if(line[0] == '/' && line[1] == '/') - continue; - - for(i=0,p=line;i<60;i++){ - if((np=strchr(p,','))!=NULL){ - str[i]=p; - *np=0; - p=np+1; - } else - str[i]=p; - } - - class_=atoi(str[0]); - if(class_<=1000 || class_>MAX_MOB_DB) - continue; - - mob_db[class_].view_class=class_; - memcpy(mob_db[class_].name,str[1],24); - memcpy(mob_db[class_].jname,str[2],24); - mob_db[class_].lv=atoi(str[3]); - mob_db[class_].max_hp=atoi(str[4]); - mob_db[class_].max_sp=atoi(str[5]); - - mob_db[class_].base_exp = atoi(str[6]); - if (mob_db[class_].base_exp <= 0) - mob_db[class_].base_exp = 0; - else if (mob_db[class_].base_exp * battle_config.base_exp_rate / 100 > 1000000000 || - mob_db[class_].base_exp * battle_config.base_exp_rate / 100 < 0) - mob_db[class_].base_exp = 1000000000; - else { - mob_db[class_].base_exp = mob_db[class_].base_exp * battle_config.base_exp_rate / 100; - if (mob_db[class_].base_exp < 1) - mob_db[class_].base_exp = 1; - } - - mob_db[class_].job_exp = atoi(str[7]); - if (mob_db[class_].job_exp <= 0) - mob_db[class_].job_exp = 0; - else if (mob_db[class_].job_exp * battle_config.job_exp_rate / 100 > 1000000000 || - mob_db[class_].job_exp * battle_config.job_exp_rate / 100 < 0) - mob_db[class_].job_exp = 1000000000; - else { - mob_db[class_].job_exp = mob_db[class_].job_exp * battle_config.job_exp_rate / 100; - if (mob_db[class_].job_exp < 1) - mob_db[class_].job_exp = 1; - } - - mob_db[class_].range=atoi(str[8]); - mob_db[class_].atk1=atoi(str[9]); - mob_db[class_].atk2=atoi(str[10]); - mob_db[class_].def=atoi(str[11]); - mob_db[class_].mdef=atoi(str[12]); - mob_db[class_].str=atoi(str[13]); - mob_db[class_].agi=atoi(str[14]); - mob_db[class_].vit=atoi(str[15]); - mob_db[class_].int_=atoi(str[16]); - mob_db[class_].dex=atoi(str[17]); - mob_db[class_].luk=atoi(str[18]); - mob_db[class_].range2=atoi(str[19]); - mob_db[class_].range3=atoi(str[20]); - mob_db[class_].size=atoi(str[21]); - mob_db[class_].race=atoi(str[22]); - mob_db[class_].element=atoi(str[23]); - mob_db[class_].mode=atoi(str[24]); - mob_db[class_].speed=atoi(str[25]); - mob_db[class_].adelay=atoi(str[26]); - mob_db[class_].amotion=atoi(str[27]); - mob_db[class_].dmotion=atoi(str[28]); - - for(i=0;i<10;i++){ // 8 -> 10 Lupus - int rate = 0,type,ratemin,ratemax; - mob_db[class_].dropitem[i].nameid=atoi(str[29+i*2]); - type = itemdb_type(mob_db[class_].dropitem[i].nameid); - if (type == 0) { - rate = battle_config.item_rate_heal * atoi(str[30+i*2]) / 100; //fix by Yor - ratemin = battle_config.item_drop_heal_min; - ratemax = battle_config.item_drop_heal_max; - } - else if (type == 2) { - rate = battle_config.item_rate_use * atoi(str[30+i*2]) / 100; //fix by Yor - ratemin = battle_config.item_drop_use_min; - ratemax = battle_config.item_drop_use_max; // End - } - else if (type == 4 || type == 5 || type == 8) { // Changed to include Pet Equip - rate = battle_config.item_rate_equip * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_equip_min; - ratemax = battle_config.item_drop_equip_max; - } - else if (type == 6) { - rate = battle_config.item_rate_card * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_card_min; - ratemax = battle_config.item_drop_card_max; - } - else { - rate = battle_config.item_rate_common * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_common_min; - ratemax = battle_config.item_drop_common_max; - } - mob_db[class_].dropitem[i].p = (rate < ratemin) ? ratemin : (rate > ratemax) ? ratemax: rate; - } - // MVP EXP Bonus, Chance: MEXP,ExpPer - mob_db[class_].mexp=atoi(str[49])*battle_config.mvp_exp_rate/100; - mob_db[class_].mexpper=atoi(str[50]); - // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per - for(i=0;i<3;i++){ - int rate=atoi(str[52+i*2])*battle_config.mvp_item_rate/100; //idea of the fix from Freya - mob_db[class_].mvpitem[i].nameid=atoi(str[51+i*2]); - mob_db[class_].mvpitem[i].p= (rate < battle_config.item_drop_mvp_min) - ? battle_config.item_drop_mvp_min : (rate > battle_config.item_drop_mvp_max) - ? battle_config.item_drop_mvp_max : rate; - } - for(i=0;i<MAX_RANDOMMONSTER;i++) - mob_db[class_].summonper[i]=0; - mob_db[class_].maxskill=0; - - mob_db[class_].sex=0; - mob_db[class_].hair=0; - mob_db[class_].hair_color=0; - mob_db[class_].weapon=0; - mob_db[class_].shield=0; - mob_db[class_].head_top=0; - mob_db[class_].head_mid=0; - mob_db[class_].head_buttom=0; - mob_db[class_].clothes_color=0; //Add for player monster dye - Valaris - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",filename[i]); - ShowStatus(tmp_output); - } - return 0; -} - -/*========================================== - * MOB display graphic change data reading - *------------------------------------------ - */ -static int mob_readdb_mobavail(void) -{ - FILE *fp; - char line[1024]; - int ln=0; - int class_,j,k; - char *str[20],*p,*np; - - if( (fp=fopen("db/mob_avail.txt","r"))==NULL ){ - printf("can't read db/mob_avail.txt\n"); - return -1; - } - - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - - for(j=0,p=line;j<12;j++){ - if((np=strchr(p,','))!=NULL){ - str[j]=p; - *np=0; - p=np+1; - } else - str[j]=p; - } - - if(str[0]==NULL) - continue; - - class_=atoi(str[0]); - if(class_<=1000 || class_>MAX_MOB_DB) // 値が異常なら処理しない。 - continue; - - k=atoi(str[1]); - if(k < 0) - continue; - if (j > 3 && k > 23 && k < 69) - k += 3977; // advanced job/baby class - mob_db[class_].view_class=k; - - if((k < 24) || (k > 4000)) { - mob_db[class_].sex=atoi(str[2]); - mob_db[class_].hair=atoi(str[3]); - mob_db[class_].hair_color=atoi(str[4]); - mob_db[class_].weapon=atoi(str[5]); - mob_db[class_].shield=atoi(str[6]); - mob_db[class_].head_top=atoi(str[7]); - mob_db[class_].head_mid=atoi(str[8]); - mob_db[class_].head_buttom=atoi(str[9]); - mob_db[class_].option=atoi(str[10])&~0x46; - mob_db[class_].clothes_color=atoi(str[11]); // Monster player dye option - Valaris - } - else if(atoi(str[2]) > 0) mob_db[class_].equip=atoi(str[2]); // mob equipment [Valaris] - - ln++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/mob_avail.txt"); - ShowStatus(tmp_output); - return 0; -} - -/*========================================== - * Reading of random monster data - *------------------------------------------ - */ -static int mob_read_randommonster(void) -{ - FILE *fp; - char line[1024]; - char *str[10],*p; - int i,j; - - const char* mobfile[] = { - "db/mob_branch.txt", - "db/mob_poring.txt", - "db/mob_boss.txt" }; - - for(i=0;i<MAX_RANDOMMONSTER;i++){ - mob_db[0].summonper[i] = 1002; // 設定し忘れた場合はポリンが出るようにしておく - fp=fopen(mobfile[i],"r"); - if(fp==NULL){ - printf("can't read %s\n",mobfile[i]); - return -1; - } - while(fgets(line,1020,fp)){ - int class_,per; - if(line[0] == '/' && line[1] == '/') - continue; - memset(str,0,sizeof(str)); - for(j=0,p=line;j<3 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - - if(str[0]==NULL || str[2]==NULL) - continue; - - class_ = atoi(str[0]); - per=atoi(str[2]); - if((class_>1000 && class_<=MAX_MOB_DB) || class_==0) - mob_db[class_].summonper[i]=per; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",mobfile[i]); - ShowStatus(tmp_output); - } - return 0; -} -/*========================================== - * db/mob_skill_db.txt reading - *------------------------------------------ - */ -static int mob_readskilldb(void) -{ - FILE *fp; - char line[1024]; - int i; - - const struct { - char str[32]; - int id; - } cond1[] = { - { "always", MSC_ALWAYS }, - { "myhpltmaxrate", MSC_MYHPLTMAXRATE }, - { "friendhpltmaxrate",MSC_FRIENDHPLTMAXRATE }, - { "mystatuson", MSC_MYSTATUSON }, - { "mystatusoff", MSC_MYSTATUSOFF }, - { "friendstatuson", MSC_FRIENDSTATUSON }, - { "friendstatusoff", MSC_FRIENDSTATUSOFF }, - { "attackpcgt", MSC_ATTACKPCGT }, - { "attackpcge", MSC_ATTACKPCGE }, - { "slavelt", MSC_SLAVELT }, - { "slavele", MSC_SLAVELE }, - { "closedattacked", MSC_CLOSEDATTACKED }, - { "longrangeattacked",MSC_LONGRANGEATTACKED }, - { "skillused", MSC_SKILLUSED }, - { "casttargeted", MSC_CASTTARGETED }, - }, cond2[] ={ - { "anybad", -1 }, - { "stone", SC_STONE }, - { "freeze", SC_FREEZE }, - { "stan", SC_STAN }, - { "sleep", SC_SLEEP }, - { "poison", SC_POISON }, - { "curse", SC_CURSE }, - { "silence", SC_SILENCE }, - { "confusion", SC_CONFUSION }, - { "blind", SC_BLIND }, - { "hiding", SC_HIDING }, - { "sight", SC_SIGHT }, - }, state[] = { - { "any", -1 }, - { "idle", MSS_IDLE }, - { "walk", MSS_WALK }, - { "attack", MSS_ATTACK }, - { "dead", MSS_DEAD }, - { "loot", MSS_LOOT }, - { "chase", MSS_CHASE }, - }, target[] = { - { "target", MST_TARGET }, - { "self", MST_SELF }, - { "friend", MST_FRIEND }, - { "around5", MST_AROUND5 }, - { "around6", MST_AROUND6 }, - { "around7", MST_AROUND7 }, - { "around8", MST_AROUND8 }, - { "around1", MST_AROUND1 }, - { "around2", MST_AROUND2 }, - { "around3", MST_AROUND3 }, - { "around4", MST_AROUND4 }, - { "around", MST_AROUND }, - }; - - int x; - char *filename[]={ "db/mob_skill_db.txt","db/mob_skill_db2.txt" }; - - for(x=0;x<2;x++){ - - fp=fopen(filename[x],"r"); - if(fp==NULL){ - if(x==0) - printf("can't read %s\n",filename[x]); - continue; - } - while(fgets(line,1020,fp)){ - char *sp[20],*p; - int mob_id; - struct mob_skill *ms; - int j=0; - - if(line[0] == '/' && line[1] == '/') - continue; - - memset(sp,0,sizeof(sp)); - for(i=0,p=line;i<18 && p;i++){ - sp[i]=p; - if((p=strchr(p,','))!=NULL) - *p++=0; - } - if( (mob_id=atoi(sp[0]))<=0 ) - continue; - - if( strcmp(sp[1],"clear")==0 ){ - memset(mob_db[mob_id].skill,0,sizeof(mob_db[mob_id].skill)); - mob_db[mob_id].maxskill=0; - continue; - } - - for(i=0;i<MAX_MOBSKILL;i++) - if( (ms=&mob_db[mob_id].skill[i])->skill_id == 0) - break; - if(i==MAX_MOBSKILL){ - printf("mob_skill: readdb: too many skill ! [%s] in %d[%s]\n", - sp[1],mob_id,mob_db[mob_id].jname); - continue; - } - - ms->state=atoi(sp[2]); - for(j=0;j<sizeof(state)/sizeof(state[0]);j++){ - if( strcmp(sp[2],state[j].str)==0) - ms->state=state[j].id; - } - ms->skill_id=atoi(sp[3]); - j=atoi(sp[4]); - if (j<=0 || j>MAX_SKILL_DB) - continue; - ms->skill_lv=j; - ms->permillage=atoi(sp[5]); - ms->casttime=atoi(sp[6]); - ms->delay=atoi(sp[7]); - ms->cancel=atoi(sp[8]); - if( strcmp(sp[8],"yes")==0 ) ms->cancel=1; - ms->target=atoi(sp[9]); - for(j=0;j<sizeof(target)/sizeof(target[0]);j++){ - if( strcmp(sp[9],target[j].str)==0) - ms->target=target[j].id; - } - ms->cond1=-1; - for(j=0;j<sizeof(cond1)/sizeof(cond1[0]);j++){ - if( strcmp(sp[10],cond1[j].str)==0) - ms->cond1=cond1[j].id; - } - ms->cond2=atoi(sp[11]); - for(j=0;j<sizeof(cond2)/sizeof(cond2[0]);j++){ - if( strcmp(sp[11],cond2[j].str)==0) - ms->cond2=cond2[j].id; - } - ms->val[0]=atoi(sp[12]); - ms->val[1]=atoi(sp[13]); - ms->val[2]=atoi(sp[14]); - ms->val[3]=atoi(sp[15]); - ms->val[4]=atoi(sp[16]); - if(sp[17] != NULL && strlen(sp[17])>2) - ms->emotion=atoi(sp[17]); - else - ms->emotion=-1; - mob_db[mob_id].maxskill=i+1; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",filename[x]); - ShowStatus(tmp_output); - } - return 0; -} -/*========================================== - * db/mob_race_db.txt reading - *------------------------------------------ - */ -static int mob_readdb_race(void) -{ - FILE *fp; - char line[1024]; - int race,j,k; - char *str[20],*p,*np; - - if( (fp=fopen("db/mob_race2_db.txt","r"))==NULL ){ - printf("can't read db/mob_race2_db.txt\n"); - return -1; - } - - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - - for(j=0,p=line;j<12;j++){ - if((np=strchr(p,','))!=NULL){ - str[j]=p; - *np=0; - p=np+1; - } else - str[j]=p; - } - if(str[0]==NULL) - continue; - - race=atoi(str[0]); - if (race < 0 || race >= MAX_MOB_RACE_DB) - continue; - - for (j=1; j<20; j++) { - if (!str[j]) - break; - k=atoi(str[j]); - if (k < 1000 || k > MAX_MOB_DB) - continue; - mob_db[k].race2 = race; - //mob_race_db[race][j] = k; - } - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/mob_race2_db.txt"); - ShowStatus(tmp_output); - return 0; -} - -#ifndef TXT_ONLY -/*========================================== - * SQL reading - *------------------------------------------ - */ -static int mob_read_sqldb(void) -{ - char line[1024]; - int i,class_; - long unsigned int ln=0; - char *str[60],*p,*np; // 55->60 Lupus - - memset(mob_db,0,sizeof(mob_db)); - - sprintf (tmp_sql, "SELECT * FROM `%s`",mob_db_db); - if(mysql_query(&mmysql_handle, tmp_sql) ) { - printf("DB server Error (select %s to Memory)- %s\n",mob_db_db,mysql_error(&mmysql_handle) ); - } - sql_res = mysql_store_result(&mmysql_handle); - if (sql_res) { - while((sql_row = mysql_fetch_row(sql_res))){ - sprintf(line,"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", - sql_row[0],sql_row[1],sql_row[2],sql_row[3],sql_row[4], - sql_row[5],sql_row[6],sql_row[7],sql_row[8],sql_row[9], - sql_row[10],sql_row[11],sql_row[12],sql_row[13],sql_row[14], - sql_row[15],sql_row[16],sql_row[17],sql_row[18],sql_row[19], - sql_row[20],sql_row[21],sql_row[22],sql_row[23],sql_row[24], - sql_row[25],sql_row[26],sql_row[27],sql_row[28],sql_row[29], - sql_row[30],sql_row[31],sql_row[32],sql_row[33],sql_row[34], - sql_row[35],sql_row[36],sql_row[37],sql_row[38],sql_row[39], - sql_row[40],sql_row[41],sql_row[42],sql_row[43],sql_row[44], - sql_row[45],sql_row[46],sql_row[47],sql_row[48],sql_row[49], - sql_row[50],sql_row[51],sql_row[52],sql_row[53],sql_row[54], - sql_row[55],sql_row[56]); - - for(i=0,p=line;i<57;i++){ - if((np=strchr(p,','))!=NULL){ - str[i]=p; - *np=0; - p=np+1; - } else - str[i]=p; - } - - class_=atoi(str[0]); - if(class_<=1000 || class_>MAX_MOB_DB) - continue; - - ln++; - - mob_db[class_].view_class=class_; - memcpy(mob_db[class_].name,str[1],24); - memcpy(mob_db[class_].jname,str[2],24); - mob_db[class_].lv=atoi(str[3]); - mob_db[class_].max_hp=atoi(str[4]); - mob_db[class_].max_sp=atoi(str[5]); - - mob_db[class_].base_exp = atoi(str[6]); - if (mob_db[class_].base_exp <= 0) - mob_db[class_].base_exp = 0; - else if (mob_db[class_].base_exp * battle_config.base_exp_rate / 100 > 1000000000 || - mob_db[class_].base_exp * battle_config.base_exp_rate / 100 < 0) - mob_db[class_].base_exp = 1000000000; - else { - mob_db[class_].base_exp = mob_db[class_].base_exp * battle_config.base_exp_rate / 100; - if (mob_db[class_].base_exp < 1) - mob_db[class_].base_exp = 1; - } - mob_db[class_].job_exp = atoi(str[7]); - if (mob_db[class_].job_exp <= 0) - mob_db[class_].job_exp = 0; - else if (mob_db[class_].job_exp * battle_config.job_exp_rate / 100 > 1000000000 || - mob_db[class_].job_exp * battle_config.job_exp_rate / 100 < 0) - mob_db[class_].job_exp = 1000000000; - else { - mob_db[class_].job_exp = mob_db[class_].job_exp * battle_config.job_exp_rate / 100; - if (mob_db[class_].job_exp < 1) - mob_db[class_].job_exp = 1; - } - - mob_db[class_].range=atoi(str[8]); - mob_db[class_].atk1=atoi(str[9]); - mob_db[class_].atk2=atoi(str[10]); - mob_db[class_].def=atoi(str[11]); - mob_db[class_].mdef=atoi(str[12]); - mob_db[class_].str=atoi(str[13]); - mob_db[class_].agi=atoi(str[14]); - mob_db[class_].vit=atoi(str[15]); - mob_db[class_].int_=atoi(str[16]); - mob_db[class_].dex=atoi(str[17]); - mob_db[class_].luk=atoi(str[18]); - mob_db[class_].range2=atoi(str[19]); - mob_db[class_].range3=atoi(str[20]); - mob_db[class_].size=atoi(str[21]); - mob_db[class_].race=atoi(str[22]); - mob_db[class_].element=atoi(str[23]); - mob_db[class_].mode=atoi(str[24]); - mob_db[class_].speed=atoi(str[25]); - mob_db[class_].adelay=atoi(str[26]); - mob_db[class_].amotion=atoi(str[27]); - mob_db[class_].dmotion=atoi(str[28]); - - for(i=0;i<10;i++){ // 8 -> 10 Lupus - int rate = 0,type,ratemin,ratemax; - mob_db[class_].dropitem[i].nameid=atoi(str[29+i*2]); - type = itemdb_type(mob_db[class_].dropitem[i].nameid); - if (type == 0) { // Added by Valaris - rate = battle_config.item_rate_heal * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_heal_min; - ratemax = battle_config.item_drop_heal_max; - } - else if (type == 2) { - rate = battle_config.item_rate_use * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_use_min; - ratemax = battle_config.item_drop_use_max; // End - } - else if (type == 4 || type == 5 || type == 8) { // Changed to include Pet Equip - rate = battle_config.item_rate_equip * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_equip_min; - ratemax = battle_config.item_drop_equip_max; - } - else if (type == 6) { - rate = battle_config.item_rate_card * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_card_min; - ratemax = battle_config.item_drop_card_max; - } - else { - rate = battle_config.item_rate_common * atoi(str[30+i*2]) / 100; - ratemin = battle_config.item_drop_common_min; - ratemax = battle_config.item_drop_common_max; - } - - mob_db[class_].dropitem[i].p = (rate < ratemin) ? ratemin : (rate > ratemax) ? ratemax: rate; - } - // MVP EXP Bonus, Chance: MEXP,ExpPer - mob_db[class_].mexp=atoi(str[49])*battle_config.mvp_exp_rate/100; - mob_db[class_].mexpper=atoi(str[50]); - // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per - for(i=0;i<3;i++){ - mob_db[class_].mvpitem[i].nameid=atoi(str[51+i*2]); - mob_db[class_].mvpitem[i].p=atoi(str[52+i*2])*battle_config.mvp_item_rate/100; - } - for(i=0;i<MAX_RANDOMMONSTER;i++) - mob_db[class_].summonper[i]=0; - mob_db[class_].maxskill=0; - - mob_db[class_].sex=0; - mob_db[class_].hair=0; - mob_db[class_].hair_color=0; - mob_db[class_].weapon=0; - mob_db[class_].shield=0; - mob_db[class_].head_top=0; - mob_db[class_].head_mid=0; - mob_db[class_].head_buttom=0; - } - mysql_free_result(sql_res); - sprintf(tmp_output,"Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,mob_db_db); - ShowStatus(tmp_output); - } - return 0; -} -#endif /* not TXT_ONLY */ - -void mob_reload(void) -{ -#ifndef TXT_ONLY - if(db_use_sqldbs) - mob_read_sqldb(); - else -#endif /* TXT_ONLY */ - mob_readdb(); - - mob_readdb_mobavail(); - mob_read_randommonster(); - mob_readskilldb(); - mob_readdb_race(); -} - -/*========================================== - * Circumference initialization of mob - *------------------------------------------ - */ -int do_init_mob(void) -{ -#ifndef TXT_ONLY - if(db_use_sqldbs) - mob_read_sqldb(); - else -#endif /* TXT_ONLY */ - mob_readdb(); - - mob_readdb_mobavail(); - mob_read_randommonster(); - mob_readskilldb(); - mob_readdb_race(); - - add_timer_func_list(mob_timer,"mob_timer"); - add_timer_func_list(mob_delayspawn,"mob_delayspawn"); - add_timer_func_list(mob_delay_item_drop,"mob_delay_item_drop"); - add_timer_func_list(mob_delay_item_drop2,"mob_delay_item_drop2"); - add_timer_func_list(mob_ai_hard,"mob_ai_hard"); - add_timer_func_list(mob_ai_lazy,"mob_ai_lazy"); - add_timer_func_list(mobskill_castend_id,"mobskill_castend_id"); - add_timer_func_list(mobskill_castend_pos,"mobskill_castend_pos"); - add_timer_func_list(mob_timer_delete,"mob_timer_delete"); - add_timer_interval(gettick()+MIN_MOBTHINKTIME,mob_ai_hard,0,0,MIN_MOBTHINKTIME); - add_timer_interval(gettick()+MIN_MOBTHINKTIME*10,mob_ai_lazy,0,0,MIN_MOBTHINKTIME*10); - - return 0; -} diff --git a/src/map/mob.h b/src/map/mob.h deleted file mode 100644 index 6613c5b6b..000000000 --- a/src/map/mob.h +++ /dev/null @@ -1,149 +0,0 @@ -// $Id: mob.h,v 1.4 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _MOB_H_ -#define _MOB_H_ - -#define MAX_RANDOMMONSTER 3 -#define MAX_MOB_RACE_DB 6 -#define MAX_MOB_DB 2000 /* Change this to increase the table size in your mob_db to accomodate - numbers more than 2000 for mobs if you want to (and know what you're doing). - Be sure to note that 4001 to 4047 are for advanced classes. */ - -struct mob_skill { - short state; - short skill_id,skill_lv; - short permillage; - int casttime,delay; - short cancel; - short cond1,cond2; - short target; - int val[5]; - short emotion; -}; - -struct mob_db { - char name[24],jname[24]; - int lv; - int max_hp,max_sp; - int base_exp,job_exp; - int atk1,atk2; - int def,mdef; - int str,agi,vit,int_,dex,luk; - int range,range2,range3; - int size,race,element,mode; - short race2; // celest - int speed,adelay,amotion,dmotion; - int mexp,mexpper; - struct { int nameid,p; } dropitem[10]; //8 -> 10 Lupus - struct { int nameid,p; } mvpitem[3]; - int view_class,sex; - short hair,hair_color,weapon,shield,head_top,head_mid,head_buttom,option,clothes_color; // [Valaris] - int equip; // [Valaris] - int summonper[MAX_RANDOMMONSTER]; - int maxskill; - struct mob_skill skill[MAX_MOBSKILL]; -}; -extern struct mob_db mob_db[]; - -enum { - MST_TARGET = 0, - MST_SELF = 1, - MST_FRIEND = 2, - MST_AROUND5 = 3, - MST_AROUND6 = 4, - MST_AROUND7 = 5, - MST_AROUND8 = 6, - MST_AROUND1 = 7, - MST_AROUND2 = 8, - MST_AROUND3 = 9, - MST_AROUND4 = 10, - MST_AROUND = MST_AROUND4, - - MSC_ALWAYS = 0x0000, - MSC_MYHPLTMAXRATE = 0x0001, - MSC_FRIENDHPLTMAXRATE= 0x0010, - MSC_MYSTATUSON = 0x0020, - MSC_MYSTATUSOFF = 0x0021, - MSC_FRIENDSTATUSON = 0x0030, - MSC_FRIENDSTATUSOFF = 0x0031, - - MSC_ATTACKPCGT = 0x0100, - MSC_ATTACKPCGE = 0x0101, - MSC_SLAVELT = 0x0110, - MSC_SLAVELE = 0x0111, - MSC_CLOSEDATTACKED = 0x1000, - MSC_LONGRANGEATTACKED= 0x1001, - MSC_SKILLUSED = 0x1010, - MSC_CASTTARGETED = 0x1011, -}; - -enum { - MSS_IDLE, // ?@ - MSS_WALK, // ? - MSS_ATTACK, // U - MSS_DEAD, // S - MSS_LOOT, // [g - MSS_CHASE, // ? -}; - -int mobdb_searchname(const char *str); -int mobdb_checkid(const int id); -int mob_once_spawn(struct map_session_data *sd,char *mapname, - int x,int y,const char *mobname,int class_,int amount,const char *event); -int mob_once_spawn_area(struct map_session_data *sd,char *mapname, - int x0,int y0,int x1,int y1, - const char *mobname,int class_,int amount,const char *event); - -int mob_spawn_guardian(struct map_session_data *sd,char *mapname, // Spawning Guardians [Valaris] - int x,int y,const char *mobname,int class_,int amount,const char *event,int guardian); // Spawning Guardians [Valaris] - - -int mob_walktoxy(struct mob_data *md,int x,int y,int easy); -//int mob_randomwalk(struct mob_data *md,int tick); -//int mob_can_move(struct mob_data *md); - -int mob_target(struct mob_data *md,struct block_list *bl,int dist); -int mob_stop_walking(struct mob_data *md,int type); -int mob_stopattack(struct mob_data *); -int mob_spawn(int); -int mob_setdelayspawn(int); -int mob_damage(struct block_list *,struct mob_data*,int,int); -int mob_changestate(struct mob_data *md,int state,int type); -int mob_heal(struct mob_data*,int); -int mob_exclusion_add(struct mob_data *md,int type,int id); -int mob_exclusion_check(struct mob_data *md,struct map_session_data *sd); -int mob_get_viewclass(int); -int mob_get_sex(int); -short mob_get_hair(int); -short mob_get_hair_color(int); -short mob_get_weapon(int); -short mob_get_shield(int); -short mob_get_head_top(int); -short mob_get_head_mid(int); -short mob_get_head_buttom(int); -short mob_get_clothes_color(int); //player mob dye [Valaris] -int mob_get_equip(int); // mob equip [Valaris] -int do_init_mob(void); - -void mob_unload(struct mob_data *md); -int mob_remove_map(struct mob_data *md, int type); -int mob_delete(struct mob_data *md); -int mob_timer_delete(int tid, unsigned int tick, int id, int data); - -int mob_deleteslave(struct mob_data *md); - -int mob_counttargeted(struct mob_data *md,struct block_list *src,int target_lv); - -int mob_class_change(struct mob_data *md,int *value); -int mob_warp(struct mob_data *md,int m,int x,int y,int type); - -int mobskill_use(struct mob_data *md,unsigned int tick,int event); -int mobskill_event(struct mob_data *md,int flag); -int mobskill_castend_id( int tid, unsigned int tick, int id,int data ); -int mobskill_castend_pos( int tid, unsigned int tick, int id,int data ); -int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag); -int mob_countslave(struct mob_data *md); - -int mob_gvmobcheck(struct map_session_data *sd, struct block_list *bl); -void mob_reload(void); - -#endif diff --git a/src/map/npc.c b/src/map/npc.c deleted file mode 100644 index 069597f83..000000000 --- a/src/map/npc.c +++ /dev/null @@ -1,2574 +0,0 @@ -// $Id: npc.c,v 1.5 2004/09/25 05:32:18 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include <math.h> -#include <time.h> - -#include "db.h" -#include "timer.h" -#include "nullpo.h" -#include "malloc.h" -#include "map.h" -#include "npc.h" -#include "clif.h" -#include "intif.h" -#include "pc.h" -#include "status.h" -#include "itemdb.h" -#include "script.h" -#include "mob.h" -#include "pet.h" -#include "battle.h" -#include "skill.h" -#include "grfio.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#ifdef _WIN32 -#undef isspace -#define isspace(x) (x == ' ' || x == '\t') -#endif - -struct npc_src_list { - struct npc_src_list * next; -// struct npc_src_list * prev; //[Shinomori] - char name[4]; -}; - -static struct npc_src_list *npc_src_first=NULL; -static struct npc_src_list *npc_src_last=NULL; -static int npc_id=START_NPC_NUM; -static int npc_warp=0; -static int npc_shop=0; -static int npc_script=0; -static int npc_mob=0; -char *current_file = NULL; -int npc_get_new_npc_id(void){ return npc_id++; } - -static struct dbt *ev_db; -static struct dbt *npcname_db; - -struct event_data { - struct npc_data *nd; - int pos; -}; -static struct tm ev_tm_b; // 時計イベント用 - -static int npc_walktimer(int,unsigned int,int,int); // [Valaris] -static int npc_walktoxy_sub(struct npc_data *nd); // [Valaris] - -/*========================================== - * NPCの無効化/有効化 - * npc_enable - * npc_enable_sub 有効時にOnTouchイベントを実行 - *------------------------------------------ - */ -int npc_enable_sub( struct block_list *bl, va_list ap ) -{ - struct map_session_data *sd; - struct npc_data *nd; - //char *name=(char *)aCallocA(50,sizeof(char)); // fixed [Shinomori] - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, nd=va_arg(ap,struct npc_data *)); - if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){ - char name[50]; // need 24 + 9 for the "::OnTouch" - - if (nd->flag&1) // 無効化されている - return 1; - - if(sd->areanpc_id==nd->bl.id) - return 1; - sd->areanpc_id=nd->bl.id; - - sprintf(name,"%s::OnTouch", nd->name); - npc_event(sd,name,0); - } - //aFree(name); - return 0; -} -int npc_enable(const char *name,int flag) -{ - struct npc_data *nd= (struct npc_data *) strdb_search(npcname_db,name); - if (nd==NULL) - return 0; - - if (flag&1) { // 有効化 - nd->flag&=~1; - clif_spawnnpc(nd); - }else if (flag&2){ - nd->flag&=~1; - nd->option = 0x0000; - clif_changeoption(&nd->bl); - }else if (flag&4){ - nd->flag|=1; - nd->option = 0x0002; - clif_changeoption(&nd->bl); - }else{ // 無効化 - nd->flag|=1; - clif_clearchar(&nd->bl,0); - } - if(flag&3 && (nd->u.scr.xs > 0 || nd->u.scr.ys >0)) - map_foreachinarea( npc_enable_sub,nd->bl.m,nd->bl.x-nd->u.scr.xs,nd->bl.y-nd->u.scr.ys,nd->bl.x+nd->u.scr.xs,nd->bl.y+nd->u.scr.ys,BL_PC,nd); - - return 0; -} - -/*========================================== - * NPCを名前で探す - *------------------------------------------ - */ -struct npc_data* npc_name2id(const char *name) -{ - return (struct npc_data *) strdb_search(npcname_db,name); -} - -void ev_release(struct dbn *db, int which) -{ - if (which & 0x1) - aFree(db->key); - if (which & 0x2) - aFree(db->data); -} - -/*========================================== - * イベントキューのイベント処理 - *------------------------------------------ - */ -int npc_event_dequeue(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - sd->npc_id=0; - if (sd->eventqueue[0][0]) { // キューのイベント処理 - size_t ev; - - // find an empty place in eventtimer list - for(ev=0;ev<MAX_EVENTTIMER;ev++) - if( sd->eventtimer[ev]==-1 ) - break; - if(ev<MAX_EVENTTIMER) - { // generate and insert the timer - int i; - // copy the first event name - char *name=(char *)aMalloc(50*sizeof(char)); - memcpy(name,sd->eventqueue[0],50); - // shift queued events down by one - for(i=1;i<MAX_EVENTQUEUE;i++) - memcpy(sd->eventqueue[i-1],sd->eventqueue[i],50); - // clear the last event - sd->eventqueue[MAX_EVENTQUEUE-1][0]=0; - // add the timer - sd->eventtimer[ev]=add_timer(gettick()+100,pc_eventtimer,sd->bl.id,(int)name);//!!todo!! - - }else - printf("npc_event_dequeue: event timer is full !\n"); - } - return 0; -} - -/*========================================== - * イベントの遅延実行 - *------------------------------------------ - */ -int npc_event_timer(int tid,unsigned int tick,int id,int data) -{ - char *eventname = (char *)data; - struct event_data *ev = (struct event_data *)strdb_search(ev_db,eventname); - struct npc_data *nd; - struct map_session_data *sd=map_id2sd(id); - size_t i; - - if((ev==NULL || (nd=ev->nd)==NULL)) - { - if(battle_config.error_log) - printf("npc_event: event not found [%s]\n",eventname); - } - else - { - for(i=0;i<MAX_EVENTTIMER;i++) { - if( nd->eventtimer[i]==tid ) { - nd->eventtimer[i]=-1; - npc_event(sd,eventname,0); // sd NULL check is within - break; - } - } - if(i==MAX_EVENTTIMER && battle_config.error_log) - printf("npc_event_timer: event timer not found [%s]!\n",eventname); - } - - aFree(eventname); - return 0; -} - -int npc_timer_event(const char *eventname) // Added by RoVeRT -{ - struct event_data *ev=(struct event_data *) strdb_search(ev_db,eventname); - struct npc_data *nd; -// int xs,ys; - - if((ev==NULL || (nd=ev->nd)==NULL)){ - printf("npc_event: event not found [%s]\n",eventname); - return 0; - } - - run_script(nd->u.scr.script,ev->pos,nd->bl.id,nd->bl.id); - - return 0; -} -/* -int npc_timer_sub_sub(void *key,void *data,va_list ap) // Added by RoVeRT -{ - char *p=(char *)key; - struct event_data *ev=(struct event_data *)data; - int *c=va_arg(ap,int *); - int tick=0,ctick=gettick(); - char temp[10]; - char event[100]; - - if(ev->nd->bl.id==(int)*c && (p=strchr(p,':')) && p && strncasecmp("::OnTimer",p,8)==0 ){ - sscanf(&p[9],"%s",temp); - tick=atoi(temp); - - strcpy( event, ev->nd->name); - strcat( event, p); - - if (ctick >= ev->nd->lastaction && ctick - ev->nd->timer >= tick) { - npc_timer_event(event); - ev->nd->lastaction = ctick; - } - } - return 0; -} - -int npc_timer_sub(void *key,void *data,va_list ap) // Added by RoVeRT -{ - struct npc_data *nd=(struct npc_data*)data; - - if(nd->timer == -1) - return 0; - - strdb_foreach(ev_db,npc_timer_sub_sub,&nd->bl.id); - - return 0; -} - -int npc_timer(int tid,unsigned int tick,int id,int data) // Added by RoVeRT -{ - strdb_foreach(npcname_db,npc_timer_sub); - - aFree((void*)data); - return 0; -}*/ -/*========================================== - * イベント用ラベルのエクスポート - * npc_parse_script->strdb_foreachから呼ばれる - *------------------------------------------ - */ -int npc_event_export(void *key,void *data,va_list ap) -{ - char *lname=(char *)key; - int pos=(int)data; - struct npc_data *nd=va_arg(ap,struct npc_data *); - - if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) { - struct event_data *ev; - char *buf; - char *p=strchr(lname,':'); - // エクスポートされる - ev=(struct event_data *) aCalloc(sizeof(struct event_data), 1); - buf=(char *) aCallocA(50, 1); - if (ev==NULL || buf==NULL) { - printf("npc_event_export: out of memory !\n"); - exit(1); - }else if (p==NULL || (p-lname)>24) { - printf("npc_event_export: label name error !\n"); - exit(1); - }else{ - ev->nd=nd; - ev->pos=pos; - *p='\0'; - sprintf(buf,"%s::%s",nd->exname,lname); - *p=':'; - strdb_insert(ev_db,buf,ev); -// if (battle_config.etc_log) -// printf("npc_event_export: export [%s]\n",buf); - } - } - return 0; -} - -/*========================================== - * 全てのNPCのOn*イベント実行 - *------------------------------------------ - */ -int npc_event_doall_sub(void *key,void *data,va_list ap) -{ - char *p=(char *)key; - struct event_data *ev; - int *c; - int rid; - const char *name; - - nullpo_retr(0, ev=(struct event_data *)data); - nullpo_retr(0, ap); - nullpo_retr(0, c=va_arg(ap,int *)); - name=va_arg(ap,const char *); - rid=va_arg(ap, int); - - if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 ){ - run_script(ev->nd->u.scr.script,ev->pos,rid,ev->nd->bl.id); - (*c)++; - } - - return 0; -} -int npc_event_doall(const char *name) -{ - int c=0; - char buf[64]="::"; - - strncpy(buf+2,name,62); - strdb_foreach(ev_db,npc_event_doall_sub,&c,buf,0); - return c; -} -int npc_event_doall_id(const char *name, int rid) -{ - int c=0; - char buf[64]="::"; - - strncpy(buf+2,name,62); - strdb_foreach(ev_db,npc_event_doall_sub,&c,buf,rid); - return c; -} - -int npc_event_do_sub(void *key,void *data,va_list ap) -{ - char *p=(char *)key; - struct event_data *ev; - int *c; - const char *name; - - nullpo_retr(0, ev=(struct event_data *)data); - nullpo_retr(0, ap); - nullpo_retr(0, c=va_arg(ap,int *)); - - name=va_arg(ap,const char *); - - if (p && strcmpi(name,p)==0 ) { - run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id); - (*c)++; - } - - return 0; -} -int npc_event_do(const char *name) -{ - int c=0; - - if (*name==':' && name[1]==':') { - return npc_event_doall(name+2); - } - - strdb_foreach(ev_db,npc_event_do_sub,&c,name); - return c; -} - -/*========================================== - * 時計イベント実行 - *------------------------------------------ - */ -int npc_event_do_clock(int tid,unsigned int tick,int id,int data) -{ - time_t timer; - struct tm *t; - char buf[64]; - char *day=""; - int c=0; - - time(&timer); - t=localtime(&timer); - - switch (t->tm_wday) { - case 0: day = "Sun"; break; - case 1: day = "Mon"; break; - case 2: day = "Tue"; break; - case 3: day = "Wed"; break; - case 4: day = "Thu"; break; - case 5: day = "Fri"; break; - case 6: day = "Sat"; break; - } - - if (t->tm_min != ev_tm_b.tm_min ) { - sprintf(buf,"OnMinute%02d",t->tm_min); - c+=npc_event_doall(buf); - sprintf(buf,"OnClock%02d%02d",t->tm_hour,t->tm_min); - c+=npc_event_doall(buf); - sprintf(buf,"On%s%02d%02d",day,t->tm_hour,t->tm_min); - c+=npc_event_doall(buf); - } - if (t->tm_hour!= ev_tm_b.tm_hour) { - sprintf(buf,"OnHour%02d",t->tm_hour); - c+=npc_event_doall(buf); - } - if (t->tm_mday!= ev_tm_b.tm_mday) { - sprintf(buf,"OnDay%02d%02d",t->tm_mon+1,t->tm_mday); - c+=npc_event_doall(buf); - } - memcpy(&ev_tm_b,t,sizeof(ev_tm_b)); - return c; -} -/*========================================== - * OnInitイベント実行(&時計イベント開始) - *------------------------------------------ - */ -int npc_event_do_oninit(void) -{ -// int c = npc_event_doall("OnInit"); - sprintf(tmp_output,"Event '"CL_WHITE"OnInit"CL_RESET"' executed with '" - CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit")); - ShowStatus(tmp_output); - - add_timer_interval(gettick()+100, - npc_event_do_clock,0,0,1000); - - return 0; -} -/*========================================== - * OnTimer NPC event - by RoVeRT - *------------------------------------------ - */ -int npc_addeventtimer(struct npc_data *nd,int tick,const char *name) -{ - int i; - for(i=0;i<MAX_EVENTTIMER;i++) - if( nd->eventtimer[i]==-1 ) - break; - if(i<MAX_EVENTTIMER){ - char *evname=(char *) aMallocA(24); - if(evname==NULL){ - printf("npc_addeventtimer: out of memory !\n");exit(1); - } - memcpy(evname,name,24); - nd->eventtimer[i]=add_timer(gettick()+tick, - npc_event_timer,nd->bl.id,(int)evname); - }else - printf("npc_addtimer: event timer is full !\n"); - - return 0; -} - -int npc_deleventtimer(struct npc_data *nd,const char *name) -{ - int i; - for(i=0;i<MAX_EVENTTIMER;i++) - if( nd->eventtimer[i]!=-1 && strcmp( - (char *)(get_timer(nd->eventtimer[i])->data), name)==0 ){ - delete_timer(nd->eventtimer[i],npc_event_timer); - nd->eventtimer[i]=-1; - break; - } - - return 0; -} - -int npc_cleareventtimer(struct npc_data *nd) -{ - int i; - for(i=0;i<MAX_EVENTTIMER;i++) - if( nd->eventtimer[i]!=-1 ){ - delete_timer(nd->eventtimer[i],npc_event_timer); - nd->eventtimer[i]=-1; - } - - return 0; -} - -int npc_do_ontimer_sub(void *key,void *data,va_list ap) -{ - char *p = (char *)key; - struct event_data *ev = (struct event_data *)data; - int *c = va_arg(ap,int *); -// struct map_session_data *sd=va_arg(ap,struct map_session_data *); - int option = va_arg(ap,int); - int tick = 0; - char temp[10]; - char event[50]; - - if(ev->nd->bl.id == (int)*c && (p = strchr(p,':')) && strnicmp("::OnTimer",p,8) == 0){ - sscanf(&p[9], "%s", temp); - tick = atoi(temp); - - strcpy(event, ev->nd->name); - strcat(event, p); - - if (option!=0) { - npc_addeventtimer(ev->nd, tick, event); - } else { - npc_deleventtimer(ev->nd, event); - } - } - return 0; -} -int npc_do_ontimer(int npc_id, int option) -{ - strdb_foreach(ev_db, npc_do_ontimer_sub, &npc_id, option); - return 0; -} -/*========================================== - * タイマーイベント用ラベルの取り込み - * npc_parse_script->strdb_foreachから呼ばれる - *------------------------------------------ - */ -int npc_timerevent_import(void *key,void *data,va_list ap) -{ - char *lname=(char *)key; - int pos=(int)data; - struct npc_data *nd=va_arg(ap,struct npc_data *); - int t=0,i=0; - - if(sscanf(lname,"OnTimer%d%n",&t,&i)==1 && lname[i]==':') { - // タイマーイベント - struct npc_timerevent_list *te=nd->u.scr.timer_event; - int j,i=nd->u.scr.timeramount; - if(te==NULL) te=(struct npc_timerevent_list*)aMallocA(sizeof(struct npc_timerevent_list)); - else te= (struct npc_timerevent_list*)aRealloc( te, sizeof(struct npc_timerevent_list) * (i+1) ); - if(te==NULL){ - printf("npc_timerevent_import: out of memory !\n"); - exit(1); - } - for(j=0;j<i;j++){ - if(te[j].timer>t){ - memmove(te+j+1,te+j,sizeof(struct npc_timerevent_list)*(i-j)); - break; - } - } - te[j].timer=t; - te[j].pos=pos; - nd->u.scr.timer_event=te; - nd->u.scr.timeramount=i+1; - } - return 0; -} -/*========================================== - * タイマーイベント実行 - *------------------------------------------ - */ -int npc_timerevent(int tid,unsigned int tick,int id,int data) -{ - int next,t; - struct npc_data* nd=(struct npc_data *)map_id2bl(id); - struct npc_timerevent_list *te; - if( nd==NULL || nd->u.scr.nexttimer<0 ){ - printf("npc_timerevent: ??\n"); - return 0; - } - nd->u.scr.timertick=tick; - te=nd->u.scr.timer_event+ nd->u.scr.nexttimer; - nd->u.scr.timerid = -1; - - t = nd->u.scr.timer+=data; - nd->u.scr.nexttimer++; - if( nd->u.scr.timeramount>nd->u.scr.nexttimer ){ - next= nd->u.scr.timer_event[ nd->u.scr.nexttimer ].timer - t; - nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,next); - } - - run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id); - return 0; -} -/*========================================== - * タイマーイベント開始 - *------------------------------------------ - */ -int npc_timerevent_start(struct npc_data *nd, int rid) -{ - int j,n, next; - - nullpo_retr(0, nd); - - n=nd->u.scr.timeramount; - if( nd->u.scr.nexttimer>=0 || n==0 ) - return 0; - - for(j=0;j<n;j++){ - if( nd->u.scr.timer_event[j].timer > nd->u.scr.timer ) - break; - } - if(j>=n) // check if there is a timer to use !!BEFORE!! you write stuff to the structures [Shinomori] - return 0; - - nd->u.scr.nexttimer=j; - nd->u.scr.timertick=gettick(); - if (rid >= 0) nd->u.scr.rid=rid; // changed to: attaching to given rid by default [Shinomori] - // if rid is less than 0 leave it unchanged [celest] - - next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer; - nd->u.scr.timerid = add_timer(gettick()+next,npc_timerevent,nd->bl.id,next); - return 0; -} -/*========================================== - * タイマーイベント終了 - *------------------------------------------ - */ -int npc_timerevent_stop(struct npc_data *nd) -{ - nullpo_retr(0, nd); - - if( nd->u.scr.nexttimer>=0 ){ - nd->u.scr.nexttimer = -1; - nd->u.scr.timer += (int)(gettick() - nd->u.scr.timertick); - if(nd->u.scr.timerid!=-1) - delete_timer(nd->u.scr.timerid,npc_timerevent); - nd->u.scr.timerid = -1; - nd->u.scr.rid = 0; - } - return 0; -} -/*========================================== - * タイマー値の所得 - *------------------------------------------ - */ -int npc_gettimerevent_tick(struct npc_data *nd) -{ - int tick; - - nullpo_retr(0, nd); - - tick=nd->u.scr.timer; - - if( nd->u.scr.nexttimer>=0 ) - tick += (int)(gettick() - nd->u.scr.timertick); - return tick; -} -/*========================================== - * タイマー値の設定 - *------------------------------------------ - */ -int npc_settimerevent_tick(struct npc_data *nd,int newtimer) -{ - int flag; - - nullpo_retr(0, nd); - - flag= nd->u.scr.nexttimer; - - npc_timerevent_stop(nd); - nd->u.scr.timer=newtimer; - if(flag>=0) - npc_timerevent_start(nd, -1); - return 0; -} - -/*========================================== - * イベント型のNPC処理 - *------------------------------------------ - */ -int npc_event(struct map_session_data *sd,const char *eventname,int mob_kill) -{ - struct event_data *ev=(struct event_data *) strdb_search(ev_db,eventname); - struct npc_data *nd; - int xs,ys; - char mobevent[100]; - - if( sd == NULL ){ - printf("npc_event nullpo?\n"); - } - - if(ev==NULL && eventname && strcmp(((eventname)+strlen(eventname)-9),"::OnTouch") == 0) - return 1; - - if(ev==NULL || (nd=ev->nd)==NULL){ - if(mob_kill && (ev==NULL || (nd=ev->nd)==NULL)){ - strcpy( mobevent, eventname); - strcat( mobevent, "::OnMyMobDead"); - ev= (struct event_data *) strdb_search(ev_db,mobevent); - if (ev==NULL || (nd=ev->nd)==NULL) { - if (strnicmp(eventname,"GM_MONSTER",10)!=0) - printf("npc_event: event not found [%s]\n",mobevent); - return 0; - } - } - else { - if(battle_config.error_log) - printf("npc_event: event not found [%s]\n",eventname); - return 0; - } - } - - xs=nd->u.scr.xs; - ys=nd->u.scr.ys; - if (xs>=0 && ys>=0 ) { - if (nd->bl.m != sd->bl.m ) - return 1; - if ( xs>0 && (sd->bl.x<nd->bl.x-xs/2 || nd->bl.x+xs/2<sd->bl.x) ) - return 1; - if ( ys>0 && (sd->bl.y<nd->bl.y-ys/2 || nd->bl.y+ys/2<sd->bl.y) ) - return 1; - } - - if ( sd->npc_id!=0) { -// if (battle_config.error_log) -// printf("npc_event: npc_id != 0\n"); - int i; - for(i=0;i<MAX_EVENTQUEUE;i++) - if (!sd->eventqueue[i][0]) - break; - if (i==MAX_EVENTQUEUE) { - if (battle_config.error_log) - printf("npc_event: event queue is full !\n"); - }else{ -// if (battle_config.etc_log) -// printf("npc_event: enqueue\n"); - memcpy(sd->eventqueue[i],eventname,50); - } - return 1; - } - if (nd->flag&1) { // 無効化されている - npc_event_dequeue(sd); - return 0; - } - - sd->npc_id=nd->bl.id; - sd->npc_pos=run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id); - return 0; -} - - -int npc_command_sub(void *key,void *data,va_list ap) -{ - char *p=(char *)key; - struct event_data *ev=(struct event_data *)data; - char *npcname=va_arg(ap,char *); - char *command=va_arg(ap,char *); - char temp[100]; - - if(strcmp(ev->nd->name,npcname)==0 && (p=strchr(p,':')) && p && strnicmp("::OnCommand",p,10)==0 ){ - sscanf(&p[11],"%s",temp); - - if (strcmp(command,temp)==0) - run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id); - } - - return 0; -} - -int npc_command(struct map_session_data *sd,char *npcname,char *command) -{ - strdb_foreach(ev_db,npc_command_sub,npcname,command); - - return 0; -} -/*========================================== - * 接触型のNPC処理 - *------------------------------------------ - */ -int npc_touch_areanpc(struct map_session_data *sd,int m,int x,int y) -{ - int i,f=1; - int xs,ys; - - nullpo_retr(1, sd); - - if(sd->npc_id) - return 1; - - for(i=0;i<map[m].npc_num;i++) { - if (map[m].npc[i]->flag&1) { // 無効化されている - f=0; - continue; - } - - switch(map[m].npc[i]->bl.subtype) { - case WARP: - xs=map[m].npc[i]->u.warp.xs; - ys=map[m].npc[i]->u.warp.ys; - break; - case SCRIPT: - xs=map[m].npc[i]->u.scr.xs; - ys=map[m].npc[i]->u.scr.ys; - break; - default: - continue; - } - if (x >= map[m].npc[i]->bl.x-xs/2 && x < map[m].npc[i]->bl.x-xs/2+xs && - y >= map[m].npc[i]->bl.y-ys/2 && y < map[m].npc[i]->bl.y-ys/2+ys) - break; - } - if (i==map[m].npc_num) { - if (f) { - if (battle_config.error_log) - printf("npc_touch_areanpc : some bug \n"); - } - return 1; - } - switch(map[m].npc[i]->bl.subtype) { - case WARP: - skill_stop_dancing(&sd->bl,0); - pc_setpos(sd,map[m].npc[i]->u.warp.name,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,0); - break; - case SCRIPT: - { - //char *name=(char *)aCallocA(50,sizeof(char)); // fixed [Shinomori] - char name[50]; // need 24 max + 9 for "::OnTouch" - - if(sd->areanpc_id == map[m].npc[i]->bl.id) - return 1; - sd->areanpc_id = map[m].npc[i]->bl.id; - - sprintf(name,"%s::OnTouch", map[m].npc[i]->name); - - if( npc_event(sd,name,0)>0 ) - npc_click(sd,map[m].npc[i]->bl.id); - //aFree(name); - break; - } - } - return 0; -} - -/*========================================== - * 近くかどうかの判定 - *------------------------------------------ - */ -int npc_checknear(struct map_session_data *sd,int id) -{ - struct npc_data *nd; - - nullpo_retr(0, sd); - - nd=(struct npc_data *)map_id2bl(id); - if (nd==NULL || nd->bl.type!=BL_NPC) { - if (battle_config.error_log) - printf("no such npc : %d\n",id); - return 1; - } - - if (nd->class_<0) // イベント系は常にOK - return 0; - - // エリア判定 - if (nd->bl.m!=sd->bl.m || - nd->bl.x<sd->bl.x-AREA_SIZE-1 || nd->bl.x>sd->bl.x+AREA_SIZE+1 || - nd->bl.y<sd->bl.y-AREA_SIZE-1 || nd->bl.y>sd->bl.y+AREA_SIZE+1) - return 1; - - return 0; -} - -/*========================================== - * NPCのオープンチャット発言 - *------------------------------------------ - */ -int npc_globalmessage(const char *name,char *mes) -{ - struct npc_data *nd=(struct npc_data *) strdb_search(npcname_db,name); - char temp[100]; - char ntemp[50]; - char *ltemp; - - if(nd==NULL) return 0; - if(name==NULL) return 0; - - ltemp=strchr(name,'#'); - if(ltemp!=NULL) { - strncpy(ntemp,name,ltemp - name); // 123#456 の # から後ろを削除する - ntemp[ltemp - name]=0x00; // strncpy のバグ?使い方間違ってる? - } - - snprintf(temp, sizeof temp ,"%s : %s",ntemp,mes); - clif_GlobalMessage(&nd->bl,temp); - - return 0; -} - -/*========================================== - * クリック時のNPC処理 - *------------------------------------------ - */ -int npc_click(struct map_session_data *sd,int id) -{ - struct npc_data *nd; - - nullpo_retr(1, sd); - - if (sd->npc_id != 0) { - if (battle_config.error_log) - printf("npc_click: npc_id != 0\n"); - return 1; - } - - if (npc_checknear(sd,id)) - return 1; - - nd=(struct npc_data *)map_id2bl(id); - - if (nd->flag&1) // 無効化されている - return 1; - - sd->npc_id=id; - switch(nd->bl.subtype) { - case SHOP: - clif_npcbuysell(sd,id); - npc_event_dequeue(sd); - break; - case SCRIPT: - sd->npc_pos=run_script(nd->u.scr.script,0,sd->bl.id,id); - break; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int npc_scriptcont(struct map_session_data *sd,int id) -{ - struct npc_data *nd; - - nullpo_retr(1, sd); - - if (id!=sd->npc_id) - return 1; - if (npc_checknear(sd,id)) - return 1; - - nd=(struct npc_data *)map_id2bl(id); - - sd->npc_pos=run_script(nd->u.scr.script,sd->npc_pos,sd->bl.id,id); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int npc_buysellsel(struct map_session_data *sd,int id,int type) -{ - struct npc_data *nd; - - nullpo_retr(1, sd); - - if (npc_checknear(sd,id)) - return 1; - - nd=(struct npc_data *)map_id2bl(id); - if (nd->bl.subtype!=SHOP) { - if (battle_config.error_log) - printf("no such shop npc : %d\n",id); - sd->npc_id=0; - return 1; - } - if (nd->flag&1) // 無効化されている - return 1; - - sd->npc_shopid=id; - if (type==0) { - clif_buylist(sd,nd); - } else { - clif_selllist(sd); - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list) -{ - struct npc_data *nd; - double z; - int i,j,w,skill,itemamount=0,new_=0; - - nullpo_retr(3, sd); - nullpo_retr(3, item_list); - - if (npc_checknear(sd,sd->npc_shopid)) - return 3; - - nd=(struct npc_data*)map_id2bl(sd->npc_shopid); - if (nd->bl.subtype!=SHOP) - return 3; - - for(i=0,w=0,z=0;i<n;i++) { - for(j=0;nd->u.shop_item[j].nameid;j++) { - if (nd->u.shop_item[j].nameid==item_list[i*2+1]) - break; - } - if (nd->u.shop_item[j].nameid==0) - return 3; - - if (itemdb_value_notdc(nd->u.shop_item[j].nameid)) - z+=(double)nd->u.shop_item[j].value * item_list[i*2]; - else - z+=(double)pc_modifybuyvalue(sd,nd->u.shop_item[j].value) * item_list[i*2]; - itemamount+=item_list[i*2]; - - switch(pc_checkadditem(sd,item_list[i*2+1],item_list[i*2])) { - case ADDITEM_EXIST: - break; - case ADDITEM_NEW: - new_++; - break; - case ADDITEM_OVERAMOUNT: - return 2; - } - - w+=itemdb_weight(item_list[i*2+1]) * item_list[i*2]; - } - if (z > (double)sd->status.zeny) - return 1; // zeny不足 - if (w+sd->weight > sd->max_weight) - return 2; // 重量超過 - if (pc_inventoryblank(sd)<new_) - return 3; // 種類数超過 - - pc_payzeny(sd,(int)z); - for(i=0;i<n;i++) { - struct item item_tmp; - - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = item_list[i*2+1]; - item_tmp.identify = 1; // npc販売アイテムは鑑定済み - - pc_additem(sd,&item_tmp,item_list[i*2]); - } - - //商人経験値 -/* if ((sd->status.class_ == 5) || (sd->status.class_ == 10) || (sd->status.class_ == 18)) { - z = z * pc_checkskill(sd,MC_DISCOUNT) / ((1 + 300 / itemamount) * 4000) * battle_config.shop_exp; - pc_gainexp(sd,0,z); - }*/ - if (battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0) { - if (sd->status.skill[MC_DISCOUNT].flag != 0) - skill = sd->status.skill[MC_DISCOUNT].flag - 2; - if (skill > 0) { - z = z * (double)skill * (double)battle_config.shop_exp/10000.; - if (z < 1) - z = 1; - pc_gainexp(sd,0,(int)z); - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int npc_selllist(struct map_session_data *sd,int n,unsigned short *item_list) -{ - double z; - int i,skill,itemamount=0; - - nullpo_retr(1, sd); - nullpo_retr(1, item_list); - - if (npc_checknear(sd,sd->npc_shopid)) - return 1; - for(i=0,z=0;i<n;i++) { - int nameid; - if (item_list[i*2]-2 <0 || item_list[i*2]-2 >=MAX_INVENTORY) - return 1; - nameid=sd->status.inventory[item_list[i*2]-2].nameid; - if (nameid == 0 || - sd->status.inventory[item_list[i*2]-2].amount < item_list[i*2+1]) - return 1; - if (itemdb_value_notoc(nameid)) - z+=(double)itemdb_value_sell(nameid) * item_list[i*2+1]; - else - z+=(double)pc_modifysellvalue(sd,itemdb_value_sell(nameid)) * item_list[i*2+1]; - itemamount+=item_list[i*2+1]; - } - - if (z > MAX_ZENY) z = MAX_ZENY; - pc_getzeny(sd,(int)z); - for(i=0;i<n;i++) { - int item_id=item_list[i*2]-2; - if( sd->status.inventory[item_id].nameid>0 && sd->inventory_data[item_id] != NULL && - sd->inventory_data[item_id]->type==7 && sd->status.inventory[item_id].amount>0 && - sd->status.inventory[item_id].card[0] == (short)0xff00) - if(search_petDB_index(sd->status.inventory[item_id].nameid, PET_EGG) >= 0) - intif_delete_petdata((*(long *)(&sd->status.inventory[item_id].card[1]))); - pc_delitem(sd,item_id,item_list[i*2+1],0); - } - - //商人経験値 -/* if ((sd->status.class_ == 5) || (sd->status.class_ == 10) || (sd->status.class_ == 18)) { - z = z * pc_checkskill(sd,MC_OVERCHARGE) / ((1 + 500 / itemamount) * 4000) * battle_config.shop_exp ; - pc_gainexp(sd,0,z); - }*/ - if (battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_OVERCHARGE)) > 0) { - if (sd->status.skill[MC_OVERCHARGE].flag != 0) - skill = sd->status.skill[MC_OVERCHARGE].flag - 2; - if (skill > 0) { - z = z * (double)skill * (double)battle_config.shop_exp/10000.; - if (z < 1) - z = 1; - pc_gainexp(sd,0,(int)z); - } - } - - return 0; - -} - -// [Valaris] NPC Walking - -/*========================================== - * Time calculation concerning one step next to npc - *------------------------------------------ - */ -static int calc_next_walk_step(struct npc_data *nd) -{ - nullpo_retr(0, nd); - - if(nd->walkpath.path_pos>=nd->walkpath.path_len) - return -1; - if(nd->walkpath.path[nd->walkpath.path_pos]&1) - return status_get_speed(&nd->bl)*14/10; - return status_get_speed(&nd->bl); -} - - -/*========================================== - * npc Walk processing - *------------------------------------------ - */ -static int npc_walk(struct npc_data *nd,unsigned int tick,int data) -{ - int moveblock; - int i; - static int dirx[8]={0,-1,-1,-1,0,1,1,1}; - static int diry[8]={1,1,0,-1,-1,-1,0,1}; - int x,y,dx,dy; - - nullpo_retr(0, nd); - - nd->state.state=MS_IDLE; - if(nd->walkpath.path_pos>=nd->walkpath.path_len || nd->walkpath.path_pos!=data) - return 0; - - nd->walkpath.path_half ^= 1; - if(nd->walkpath.path_half==0){ - nd->walkpath.path_pos++; - if(nd->state.change_walk_target){ - npc_walktoxy_sub(nd); - return 0; - } - } - else { - if(nd->walkpath.path[nd->walkpath.path_pos]>=8) - return 1; - - x = nd->bl.x; - y = nd->bl.y; - if(map_getcell(nd->bl.m,x,y,CELL_CHKNOPASS)) { - npc_stop_walking(nd,1); - return 0; - } - nd->dir=nd->walkpath.path[nd->walkpath.path_pos]; - dx = dirx[nd->dir]; - dy = diry[nd->dir]; - - if(map_getcell(nd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) { - npc_walktoxy_sub(nd); - return 0; - } - - moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE); - - nd->state.state=MS_WALK; - map_foreachinmovearea(clif_npcoutsight,nd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,nd); - - x += dx; - y += dy; - - if(moveblock) map_delblock(&nd->bl); - nd->bl.x = x; - nd->bl.y = y; - if(moveblock) map_addblock(&nd->bl); - - map_foreachinmovearea(clif_npcinsight,nd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,nd); - nd->state.state=MS_IDLE; - } - if((i=calc_next_walk_step(nd))>0){ - i = i>>1; - if(i < 1 && nd->walkpath.path_half == 0) - i = 1; - nd->walktimer=add_timer(tick+i,npc_walktimer,nd->bl.id,nd->walkpath.path_pos); - nd->state.state=MS_WALK; - - if(nd->walkpath.path_pos>=nd->walkpath.path_len) - clif_fixnpcpos(nd); // When npc stops, retransmission current of a position. - - } - return 0; -} - -int npc_changestate(struct npc_data *nd,int state,int type) -{ - int i; - - nullpo_retr(0, nd); - - if(nd->walktimer != -1) - delete_timer(nd->walktimer,npc_walktimer); - nd->walktimer=-1; - nd->state.state=state; - - switch(state){ - case MS_WALK: - if((i=calc_next_walk_step(nd))>0){ - i = i>>2; - nd->walktimer=add_timer(gettick()+i,npc_walktimer,nd->bl.id,0); - } - else - nd->state.state=MS_IDLE; - break; - case MS_DELAY: - nd->walktimer=add_timer(gettick()+type,npc_walktimer,nd->bl.id,0); - break; - - } - - return 0; -} - -static int npc_walktimer(int tid,unsigned int tick,int id,int data) -{ - struct npc_data *nd; - - nd=(struct npc_data*)map_id2bl(id); - if(nd == NULL || nd->bl.type != BL_NPC) - return 1; - - if(nd->walktimer != tid){ - return 0; - } - - nd->walktimer=-1; - - if(nd->bl.prev == NULL) - return 1; - - switch(nd->state.state){ - case MS_WALK: - npc_walk(nd,tick,data); - break; - case MS_DELAY: - npc_changestate(nd,MS_IDLE,0); - break; - default: - break; - } - return 0; -} - - -static int npc_walktoxy_sub(struct npc_data *nd) -{ - struct walkpath_data wpd; - - nullpo_retr(0, nd); - - if(path_search(&wpd,nd->bl.m,nd->bl.x,nd->bl.y,nd->to_x,nd->to_y,nd->state.walk_easy)) - return 1; - memcpy(&nd->walkpath,&wpd,sizeof(wpd)); - - nd->state.change_walk_target=0; - npc_changestate(nd,MS_WALK,0); - - clif_movenpc(nd); - - return 0; -} - -int npc_walktoxy(struct npc_data *nd,int x,int y,int easy) -{ - struct walkpath_data wpd; - - nullpo_retr(0, nd); - - if(nd->state.state == MS_WALK && path_search(&wpd,nd->bl.m,nd->bl.x,nd->bl.y,x,y,0) ) - return 1; - - nd->state.walk_easy = easy; - nd->to_x=x; - nd->to_y=y; - if(nd->state.state == MS_WALK) { - nd->state.change_walk_target=1; - } else { - return npc_walktoxy_sub(nd); - } - - return 0; -} - -int npc_stop_walking(struct npc_data *nd,int type) -{ - nullpo_retr(0, nd); - - if(nd->state.state == MS_WALK || nd->state.state == MS_IDLE) { - int dx=0,dy=0; - - nd->walkpath.path_len=0; - if(type&4){ - dx=nd->to_x-nd->bl.x; - if(dx<0) - dx=-1; - else if(dx>0) - dx=1; - dy=nd->to_y-nd->bl.y; - if(dy<0) - dy=-1; - else if(dy>0) - dy=1; - } - nd->to_x=nd->bl.x+dx; - nd->to_y=nd->bl.y+dy; - if(dx!=0 || dy!=0){ - npc_walktoxy_sub(nd); - return 0; - } - npc_changestate(nd,MS_IDLE,0); - } - if(type&0x01) - clif_fixnpcpos(nd); - if(type&0x02) { - int delay=status_get_dmotion(&nd->bl); - unsigned int tick = gettick(); - if(nd->canmove_tick < tick) - nd->canmove_tick = tick + delay; - } - - return 0; -} - -int npc_remove_map (struct npc_data *nd) -{ - nullpo_retr(1, nd); - - if(nd->bl.prev == NULL) - return 1; - -#ifdef PCRE_SUPPORT - npc_chat_finalize(nd); -#endif - clif_clearchar_area(&nd->bl,2); - strdb_erase(npcname_db, nd->name); - map_delblock(&nd->bl); - map_deliddb(&nd->bl); - - return 0; -} - -int npc_unload(struct npc_data *nd) -{ - nullpo_retr (0, nd); - - if (nd->chat_id) { - struct chat_data *cd = (struct chat_data*)map_id2bl(nd->chat_id); - if (cd) aFree (cd); - cd = NULL; - } - if (nd->bl.subtype == SCRIPT) { - if (nd->u.scr.timerid != -1) - delete_timer(nd->u.scr.timerid, npc_timerevent); - npc_cleareventtimer (nd); - if (nd->u.scr.timer_event) - aFree(nd->u.scr.timer_event); - if (nd->u.scr.src_id == 0) { - if(nd->u.scr.script) { - aFree(nd->u.scr.script); - nd->u.scr.script = NULL; - } - if (nd->u.scr.label_list) { - aFree(nd->u.scr.label_list); - nd->u.scr.label_list = NULL; - } - } - } - npc_remove_map (nd); - aFree(nd); - nd = NULL; - - return 0; -} - -// -// 初期化関係 -// - -/*========================================== - * 読み込むnpcファイルのクリア - *------------------------------------------ - */ -void npc_clearsrcfile() -{ - struct npc_src_list *p=npc_src_first; - - while( p ) { - struct npc_src_list *p2=p; - p=p->next; - aFree(p2); - } - npc_src_first=NULL; - npc_src_last=NULL; -} -/*========================================== - * 読み込むnpcファイルの追加 - *------------------------------------------ - */ -void npc_addsrcfile(char *name) -{ - struct npc_src_list *new_; - size_t len; - - if ( strcmpi(name,"clear")==0 ) { - npc_clearsrcfile(); - return; - } - - { - // prevent multiple insert of source files - struct npc_src_list *p=npc_src_first; - while( p ) - { // found the file, no need to insert it again - if( 0==strcmp(name,p->name) ) - return; - p=p->next; - } - } - - len = sizeof(*new_) + strlen(name); - new_=(struct npc_src_list *)aCalloc(1,len); - new_->next = NULL; - strncpy(new_->name,name,strlen(name)+1); - if (npc_src_first==NULL) - npc_src_first = new_; - if (npc_src_last) - npc_src_last->next = new_; - - npc_src_last=new_; -} -/*========================================== - * 読み込むnpcファイルの削除 - *------------------------------------------ - */ -void npc_delsrcfile(char *name) -{ - struct npc_src_list *p=npc_src_first,*pp=NULL,**lp=&npc_src_first; - - if ( strcmpi(name,"all")==0 ) { - npc_clearsrcfile(); - return; - } - - for( ; p; lp=&p->next,pp=p,p=p->next ) { - if ( strcmp(p->name,name)==0 ) { - *lp=p->next; - if ( npc_src_last==p ) - npc_src_last=pp; - aFree(p); - break; - } - } -} - -/*========================================== - * warp行解析 - *------------------------------------------ - */ -int npc_parse_warp(char *w1,char *w2,char *w3,char *w4) -{ - int x,y,xs,ys,to_x,to_y,m; - int i,j; - char mapname[24],to_mapname[24]; - struct npc_data *nd; - - // 引数の個数チェック - if (sscanf(w1,"%[^,],%d,%d",mapname,&x,&y) != 3 || - sscanf(w4,"%d,%d,%[^,],%d,%d",&xs,&ys,to_mapname,&to_x,&to_y) != 5) { - printf("bad warp line : %s\n",w3); - return 1; - } - - m=map_mapname2mapid(mapname); - - nd=(struct npc_data *)aCalloc(1,sizeof(struct npc_data)); - nd->bl.id=npc_get_new_npc_id(); - nd->n=map_addnpc(m,nd); - - nd->bl.prev = nd->bl.next = NULL; - nd->bl.m=m; - nd->bl.x=x; - nd->bl.y=y; - nd->dir=0; - nd->flag=0; - memcpy(nd->name,w3,24); - memcpy(nd->exname,w3,24); - - nd->chat_id=0; - if (!battle_config.warp_point_debug) - nd->class_=WARP_CLASS; - else - nd->class_=WARP_DEBUG_CLASS; - nd->speed=200; - nd->option = 0; - nd->opt1 = 0; - nd->opt2 = 0; - nd->opt3 = 0; - memcpy(nd->u.warp.name,to_mapname,16); - xs+=2; ys+=2; - nd->u.warp.x=to_x; - nd->u.warp.y=to_y; - nd->u.warp.xs=xs; - nd->u.warp.ys=ys; - - for(i=0;i<ys;i++) { - for(j=0;j<xs;j++) { - if(map_getcell(m,x-xs/2+j,y-ys/2+i,CELL_CHKNOPASS)) - continue; - map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC); - } - } - -// printf("warp npc %s %d read done\n",mapname,nd->bl.id); - npc_warp++; - nd->bl.type=BL_NPC; - nd->bl.subtype=WARP; - map_addblock(&nd->bl); - clif_spawnnpc(nd); - strdb_insert(npcname_db,nd->name,nd); - - return 0; -} - -/*========================================== - * shop行解析 - *------------------------------------------ - */ -static int npc_parse_shop(char *w1,char *w2,char *w3,char *w4) -{ - char *p; - int x, y, dir, m; - int max = 100, pos = 0; - char mapname[24]; - struct npc_data *nd; - - // 引数の個数チェック - if (sscanf(w1, "%[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 || - strchr(w4, ',') == NULL) { - printf("bad shop line : %s\n", w3); - return 1; - } - m = map_mapname2mapid(mapname); - - nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data) + - sizeof(nd->u.shop_item[0]) * (max + 1)); - p = strchr(w4, ','); - - while (p && pos < max) { - int nameid,value; - struct item_data *id; - p++; - if (sscanf(p, "%d:%d", &nameid, &value) != 2) - break; - nd->u.shop_item[pos].nameid = nameid; - id = itemdb_search(nameid); - if (value < 0) - value = id->value_buy; - nd->u.shop_item[pos].value = value; - // check for bad prices that can possibly cause exploits - if (value*75/100 < id->value_sell*124/100) { - sprintf (tmp_output, "Item %s [%d] buying:%d < selling:%d\n", - id->name, id->nameid, value*75/100, id->value_sell*124/100); - ShowWarning (tmp_output); - } - pos++; - p=strchr(p,','); - } - if (pos == 0) { - aFree(nd); - return 1; - } - nd->u.shop_item[pos++].nameid = 0; - - nd->bl.prev = nd->bl.next = NULL; - nd->bl.m = m; - nd->bl.x = x; - nd->bl.y = y; - nd->bl.id = npc_get_new_npc_id(); - nd->dir = dir; - nd->flag = 0; - memcpy(nd->name, w3, 24); - nd->class_ = atoi(w4); - nd->speed = 200; - nd->chat_id = 0; - nd->option = 0; - nd->opt1 = 0; - nd->opt2 = 0; - nd->opt3 = 0; - - nd = (struct npc_data *)aRealloc(nd, - sizeof(struct npc_data) + sizeof(nd->u.shop_item[0]) * pos); - - //printf("shop npc %s %d read done\n",mapname,nd->bl.id); - npc_shop++; - nd->bl.type=BL_NPC; - nd->bl.subtype=SHOP; - nd->n=map_addnpc(m,nd); - map_addblock(&nd->bl); - clif_spawnnpc(nd); - strdb_insert(npcname_db,nd->name,nd); - - return 0; -} -/*========================================== - * NPCのラベルデータコンバート - *------------------------------------------ - */ -int npc_convertlabel_db(void *key,void *data,va_list ap) -{ - char *lname=(char *)key; - int pos=(int)data; - struct npc_data *nd; - struct npc_label_list *lst; - int num; - char *p=strchr(lname,':'); - - nullpo_retr(0, ap); - nullpo_retr(0, nd=va_arg(ap,struct npc_data *)); - - lst=nd->u.scr.label_list; - num=nd->u.scr.label_list_num; - if(!lst){ - lst=(struct npc_label_list *)aCallocA(1,sizeof(struct npc_label_list)); - num=0; - }else - lst=(struct npc_label_list *)aRealloc(lst,sizeof(struct npc_label_list)*(num+1)); - - *p='\0'; - - // here we check if the label fit into the buffer - if (strlen(lname)>23) { - printf("npc_parse_script: label name longer than 23 chars! '%s'\n (%s)", lname, current_file); - exit(1); - } - memcpy(lst[num].name,lname,strlen(lname)+1); //including EOS - - - *p=':'; - lst[num].pos=pos; - nd->u.scr.label_list=lst; - nd->u.scr.label_list_num=num+1; - return 0; -} -/*========================================== - * script行解析 - *------------------------------------------ - */ -static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines) -{ - int x,y,dir=0,m,xs=0,ys=0,class_=0; // [Valaris] thanks to fov - char mapname[24]; - unsigned char *srcbuf=NULL,*script; - int srcsize=65536; - int startline=0; - unsigned char line[1024]; - int i; - struct npc_data *nd; - int evflag=0; - struct dbt *label_db; - char *p; - struct npc_label_list *label_dup=NULL; - int label_dupnum=0; - int src_id=0; - - if(strcmp(w1,"-")==0){ - x=0;y=0;m=-1; - }else{ - // 引数の個数チェック - if (sscanf(w1,"%[^,],%d,%d,%d",mapname,&x,&y,&dir) != 4 || - ( strcmp(w2,"script")==0 && strchr(w4,',')==NULL) ) { - printf("bad script line : %s\n",w3); - return 1; - } - m = map_mapname2mapid(mapname); - } - - if(strcmp(w2,"script")==0){ - // スクリプトの解析 - srcbuf=(unsigned char *)aCallocA(srcsize,sizeof(char)); - if (strchr(first_line,'{')) { - strcpy((char *) srcbuf,strchr(first_line,'{')); - startline=*lines; - } else - srcbuf[0]=0; - while(1) { - for(i=strlen((const char *) srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--); - if (i>=0 && srcbuf[i]=='}') - break; - fgets((char *) line,1020,fp); - (*lines)++; - if (feof(fp)) - break; - if (strlen((char *) srcbuf)+strlen((char *) line)+1>=srcsize) { - srcsize += 65536; - srcbuf = (unsigned char *)aRealloc(srcbuf, srcsize); - memset(srcbuf + srcsize - 65536, '\0', 65536); - } - if (srcbuf[0]!='{') { - if (strchr((char *) line,'{')) { - strcpy((char *) srcbuf,strchr((const char *) line,'{')); - startline=*lines; - } - } else - strcat((char *) srcbuf,(const char *) line); - } - script=(unsigned char *) parse_script((unsigned char *) srcbuf,startline); - if (script==NULL) { - // script parse error? - aFree(srcbuf); - return 1; - } - - }else{ - // duplicateする - - char srcname[128]; - struct npc_data *nd2; - if( sscanf(w2,"duplicate(%[^)])",srcname)!=1 ){ - printf("bad duplicate name (in %s)! : %s",current_file, w2); - return 0; - } - if( (nd2=npc_name2id(srcname))==NULL ){ - printf("bad duplicate name (in %s)! (not exist) : %s\n", current_file, srcname); - return 0; - } - script=(unsigned char *)nd2->u.scr.script; - label_dup=nd2->u.scr.label_list; - label_dupnum=nd2->u.scr.label_list_num; - src_id=nd2->bl.id; - - }// end of スクリプト解析 - - nd=(struct npc_data *)aCalloc(1,sizeof(struct npc_data)); - - if(m==-1){ - // スクリプトコピー用のダミーNPC - - }else if( sscanf(w4,"%d,%d,%d",&class_,&xs,&ys)==3) { - // 接触型NPC - int i,j; - - if (xs>=0)xs=xs*2+1; - if (ys>=0)ys=ys*2+1; - - if (class_>=0) { - - for(i=0;i<ys;i++) { - for(j=0;j<xs;j++) { - if(map_getcell(m,x-xs/2+j,y-ys/2+i,CELL_CHKNOPASS)) - continue; - map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC); - } - } - } - - nd->u.scr.xs=xs; - nd->u.scr.ys=ys; - } else { // クリック型NPC - class_=atoi(w4); - nd->u.scr.xs=0; - nd->u.scr.ys=0; - } - - if (class_<0 && m>=0) { // イベント型NPC - evflag=1; - } - - while((p=strchr(w3,':'))) { - if (p[1]==':') break; - } - if (p) { - *p=0; - memcpy(nd->name,w3,24); - memcpy(nd->exname,p+2,24); - }else{ - memcpy(nd->name,w3,24); - memcpy(nd->exname,w3,24); - } - - nd->bl.prev = nd->bl.next = NULL; - nd->bl.m = m; - nd->bl.x = x; - nd->bl.y = y; - nd->bl.id=npc_get_new_npc_id(); - nd->dir = dir; - nd->flag=0; - nd->class_=class_; - nd->speed=200; - nd->u.scr.script=(char *) script; - nd->u.scr.src_id=src_id; - nd->chat_id=0; - nd->option = 0; - nd->opt1 = 0; - nd->opt2 = 0; - nd->opt3 = 0; - nd->walktimer=-1; - - //printf("script npc %s %d %d read done\n",mapname,nd->bl.id,nd->class_); - npc_script++; - nd->bl.type=BL_NPC; - nd->bl.subtype=SCRIPT; - if(m>=0){ - nd->n=map_addnpc(m,nd); - map_addblock(&nd->bl); - - // clear event timers upon initialise - memset(nd->eventqueue, 0, sizeof(nd->eventqueue)); - for(i = 0; i < MAX_EVENTTIMER; i++) - nd->eventtimer[i] = -1; - - if (evflag) { // イベント型 - struct event_data *ev=(struct event_data *)aCalloc(1,sizeof(struct event_data)); - ev->nd=nd; - ev->pos=0; - strdb_insert(ev_db,nd->exname,ev); - }else - clif_spawnnpc(nd); - } - strdb_insert(npcname_db,nd->exname,nd); - - - //----------------------------------------- - // ラベルデータの準備 - if(srcbuf){ - // script本体がある場合の処理 - - // ラベルデータのコンバート - label_db=script_get_label_db(); - strdb_foreach(label_db,npc_convertlabel_db,nd); - - // もう使わないのでバッファ解放 - aFree(srcbuf); - - }else{ - // duplicate - -// nd->u.scr.label_list=aMallocA(sizeof(struct npc_label_list)*label_dupnum); -// memcpy(nd->u.scr.label_list,label_dup,sizeof(struct npc_label_list)*label_dupnum); - - nd->u.scr.label_list=label_dup; // ラベルデータ共有 - nd->u.scr.label_list_num=label_dupnum; - } - - //----------------------------------------- - // イベント用ラベルデータのエクスポート - for(i=0;i<nd->u.scr.label_list_num;i++){ - char *lname=nd->u.scr.label_list[i].name; - int pos=nd->u.scr.label_list[i].pos; - - if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) { -/* -I rearrange the code so this is just for commenting; remove it if you have enough if it [Shinomori] - struct event_data *ev; - char *buf; - // エクスポートされる - ev=(struct event_data *)aCalloc(1,sizeof(struct event_data)); -why allocing 50 chars ? - buf=(char *)aCallocA(50,sizeof(char)); -why checking here? -lname is identical to nd->u.scr.label_list[i].name which is only 24 chars so check for strlen should be 23 - if (strlen(lname)>24) { - printf("npc_parse_script: label name error (%s) !\n", current_file); - exit(1); - }else{ - //struct event_data *ev2; - ev->nd=nd; - ev->pos=pos; - sprintf(buf,"%s::%s",nd->exname,lname); - //ev2 = strdb_search(ev_db,buf); - //if(ev2 != NULL) { - // printf("npc_parse_script : duplicate event %s\n",buf); - // aFree(ev2); - //} -you are sure reentering the same database key will overwrite the existing entry? - strdb_insert(ev_db,buf,ev); -anyway instead of removing data from the db and inserting a new one -wouldn't it be easier just not to insert the new duplicate event, it is a duplicate anyway? - } -*/ - // this check is useless here because the buffer is only 24 chars - // and already overwritten if this is here is reached - // I leave the check anyway but place it correctly to npc_convertlabel_db - if (strlen(lname)>23) { - printf("npc_parse_script: label name longer than 23 chars! '%s' (%s)\n", lname, current_file); - exit(1); - }else{ - struct event_data *ev; - struct event_data *ev2; - char *buf; - // エクスポートされる - - // 51 comes from: 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS - //buf=(char *)aMalloc(51,sizeof(char)); - // but to save some memory we alloc only the really necessary space - buf=(char *)aMalloc( (3+strlen(nd->exname)+strlen(lname))*sizeof(char)); - sprintf(buf,"%s::%s",nd->exname,lname); - - // search the label in ev_db; - // remember the label is max 50 chars + eos; see the strdb_init below - ev2 = (struct event_data *)strdb_search(ev_db,buf); - if(ev2 != NULL) { - printf("npc_parse_script : duplicate event %s (%s)\n",buf, current_file); - - // just skip the label insertion and free the alloced buffer - aFree(buf); - } - else - { // generate the data and insert it - ev=(struct event_data *)aCalloc(1,sizeof(struct event_data)); - ev->nd=nd; - ev->pos=pos; - strdb_insert(ev_db,buf,ev); - } - - } - } - } - - //----------------------------------------- - // ラベルデータからタイマーイベント取り込み - for(i=0;i<nd->u.scr.label_list_num;i++){ - int t=0,k=0; - char *lname=nd->u.scr.label_list[i].name; - int pos=nd->u.scr.label_list[i].pos; - if(sscanf(lname,"OnTimer%d%n",&t,&k)==1 && lname[k]=='\0') { - // タイマーイベント - struct npc_timerevent_list *te=nd->u.scr.timer_event; - int j,k=nd->u.scr.timeramount; - if(te==NULL) - te=(struct npc_timerevent_list *)aCallocA(1,sizeof(struct npc_timerevent_list)); - else - te=(struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) ); - for(j=0;j<k;j++){ - if(te[j].timer>t){ - memmove(te+j+1,te+j,sizeof(struct npc_timerevent_list)*(k-j)); - break; - } - } - te[j].timer=t; - te[j].pos=pos; - nd->u.scr.timer_event=te; - nd->u.scr.timeramount=k+1; - } - } - nd->u.scr.nexttimer=-1; - nd->u.scr.timerid=-1; - - - return 0; -} - -/*========================================== - * function行解析 - *------------------------------------------ - */ -static int npc_parse_function(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines) -{ - char *srcbuf=NULL,*script; - int srcsize=65536; - int startline=0; - char line[1024]; - int i; -// struct dbt *label_db; - char *p; - - // スクリプトの解析 - srcbuf=(char *)aCallocA(srcsize,sizeof(char)); - if (strchr(first_line,'{')) { - strcpy(srcbuf,strchr(first_line,'{')); - startline=*lines; - } else - srcbuf[0]=0; - while(1) { - for(i=strlen(srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--); - if (i>=0 && srcbuf[i]=='}') - break; - fgets(line,1020,fp); - (*lines)++; - if (feof(fp)) - break; - if (strlen(srcbuf)+strlen(line)+1>=srcsize) { - srcsize += 65536; - srcbuf = (char *)aRealloc(srcbuf, srcsize); - memset(srcbuf + srcsize - 65536, '\0', 65536); - } - if (srcbuf[0]!='{') { - if (strchr(line,'{')) { - strcpy(srcbuf,strchr(line,'{')); - startline=*lines; - } - } else - strcat(srcbuf,line); - } - script= parse_script((unsigned char *) srcbuf,startline); - if (script==NULL) { - // script parse error? - aFree(srcbuf); - return 1; - } - - p=(char *)aCallocA(50,sizeof(char)); - - strncpy(p,w3,50); - strdb_insert(script_get_userfunc_db(),p,script); - -// label_db=script_get_label_db(); - - // もう使わないのでバッファ解放 - aFree(srcbuf); - -// printf("function %s => %p\n",p,script); - - return 0; -} - - -/*========================================== - * mob行解析 - *------------------------------------------ - */ -int npc_parse_mob(char *w1,char *w2,char *w3,char *w4) -{ - int m,x,y,xs,ys,class_,num,delay1,delay2,level; - int i; - char mapname[24]; - char mobname[24]; - char eventname[24]=""; - struct mob_data *md; - - xs=ys=0; - delay1=delay2=0; - // 引数の個数チェック - if (sscanf(w1,"%[^,],%d,%d,%d,%d",mapname,&x,&y,&xs,&ys) < 3 || - sscanf(w4,"%d,%d,%d,%d,%s",&class_,&num,&delay1,&delay2,eventname) < 2 ) { - printf("bad monster line : %s\n",w3); - return 1; - } - - m=map_mapname2mapid(mapname); - - if ( num>1 && battle_config.mob_count_rate!=100) { - if ( (num=num*battle_config.mob_count_rate/100)<1 ) - num=1; - } - - for(i=0;i<num;i++) { - md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data)); - - if(class_>4000) { // large/tiny mobs [Valaris] - md->size=2; - class_-=4000; - } - else if(class_>2000) { - md->size=1; - class_-=2000; - } - - md->bl.prev=NULL; - md->bl.next=NULL; - md->bl.m=m; - md->bl.x=x; - md->bl.y=y; - - if(sscanf(w3,"%[^,],%d",mobname,&level) > 1) - md->level=level; - if(strcmp(mobname,"--en--")==0) - memcpy(md->name,mob_db[class_].name,24); - else if(strcmp(mobname,"--ja--")==0) - memcpy(md->name,mob_db[class_].jname,24); - else memcpy(md->name,mobname,24); - - md->n = i; - md->base_class = md->class_ = class_; - md->bl.id=npc_get_new_npc_id(); - md->m =m; - md->x0=x; - md->y0=y; - md->xs=xs; - md->ys=ys; - md->spawndelay1=delay1; - md->spawndelay2=delay2; - - memset(&md->state,0,sizeof(md->state)); - md->timer = -1; - md->target_id=0; - md->attacked_id=0; - md->speed=mob_db[class_].speed; - - if (mob_db[class_].mode&0x02) - md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item)); - else - md->lootitem=NULL; - - if (strlen(eventname)>=4) { - memcpy(md->npc_event,eventname,24); - }else - memset(md->npc_event,0,24); - - md->bl.type=BL_MOB; - map_addiddb(&md->bl); - mob_spawn(md->bl.id); - - npc_mob++; - } - //printf("warp npc %s %d read done\n",mapname,nd->bl.id); - - return 0; -} - -/*========================================== - * マップフラグ行の解析 - *------------------------------------------ - */ -static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4) -{ - int m; - char mapname[24],savemap[16]; - int savex,savey; - char drop_arg1[16],drop_arg2[16]; - int drop_id=0,drop_type=0,drop_per=0; - - // 引数の個数チェック -// if ( sscanf(w1,"%[^,],%d,%d,%d",mapname,&x,&y,&dir) != 4 ) - if ( sscanf(w1,"%[^,]",mapname) != 1 ) - return 1; - - m=map_mapname2mapid(mapname); - if (m<0) - return 1; - -//マップフラグ - if ( strcmpi(w3,"nosave")==0) { - if (strcmp(w4,"SavePoint")==0) { - memcpy(map[m].save.map,"SavePoint",10); - map[m].save.x=-1; - map[m].save.y=-1; - }else if (sscanf(w4,"%[^,],%d,%d",savemap,&savex,&savey)==3) { - memcpy(map[m].save.map,savemap,16); - map[m].save.x=savex; - map[m].save.y=savey; - } - map[m].flag.nosave=1; - } - else if (strcmpi(w3,"nomemo")==0) { - map[m].flag.nomemo=1; - } - else if (strcmpi(w3,"noteleport")==0) { - map[m].flag.noteleport=1; - } - else if (strcmpi(w3,"nowarp")==0) { - map[m].flag.nowarp=1; - } - else if (strcmpi(w3,"nowarpto")==0) { - map[m].flag.nowarpto=1; - } - else if (strcmpi(w3,"noreturn")==0) { - map[m].flag.noreturn=1; - } - else if (strcmpi(w3,"monster_noteleport")==0) { - map[m].flag.monster_noteleport=1; - } - else if (strcmpi(w3,"nobranch")==0) { - map[m].flag.nobranch=1; - } - else if (strcmpi(w3,"nopenalty")==0) { - map[m].flag.nopenalty=1; - } - else if (strcmpi(w3,"pvp")==0) { - map[m].flag.pvp=1; - } - else if (strcmpi(w3,"pvp_noparty")==0) { - map[m].flag.pvp_noparty=1; - } - else if (strcmpi(w3,"pvp_noguild")==0) { - map[m].flag.pvp_noguild=1; - } - else if (strcmpi(w3,"pvp_nightmaredrop")==0) { - if (sscanf(w4,"%[^,],%[^,],%d",drop_arg1,drop_arg2,&drop_per)==3) { int i; - if(strcmp(drop_arg1,"random")==0) - drop_id = -1; - else if(itemdb_exists( (drop_id=atoi(drop_arg1)) )==NULL) - drop_id = 0; - if(strcmp(drop_arg2,"inventory")==0) - drop_type = 1; - else if(strcmp(drop_arg2,"equip")==0) - drop_type = 2; - else if(strcmp(drop_arg2,"all")==0) - drop_type = 3; - - if(drop_id != 0){ - for (i=0;i<MAX_DROP_PER_MAP;i++){ - if(map[m].drop_list[i].drop_id==0){ - map[m].drop_list[i].drop_id = drop_id; - map[m].drop_list[i].drop_type = drop_type; - map[m].drop_list[i].drop_per = drop_per; - break; - } - } - map[m].flag.pvp_nightmaredrop=1; - } - } - } - else if (strcmpi(w3,"pvp_nocalcrank")==0) { - map[m].flag.pvp_nocalcrank=1; - } - else if (strcmpi(w3,"gvg")==0) { - map[m].flag.gvg=1; - } - else if (strcmpi(w3,"gvg_noparty")==0) { - map[m].flag.gvg_noparty=1; - } - else if (strcmpi(w3,"nozenypenalty")==0) { - map[m].flag.nozenypenalty=1; - } - else if (strcmpi(w3,"notrade")==0) { - map[m].flag.notrade=1; - } - else if (strcmpi(w3,"noskill")==0) { - map[m].flag.noskill=1; - } - else if (battle_config.pk_mode && strcmpi(w3,"nopvp")==0) { // nopvp for pk mode [Valaris] - map[m].flag.nopvp=1; - map[m].flag.pvp=0; - } - else if (strcmpi(w3,"noicewall")==0) { // noicewall [Valaris] - map[m].flag.noicewall=1; - } - else if (strcmpi(w3,"snow")==0) { // snow [Valaris] - map[m].flag.snow=1; - } - else if (strcmpi(w3,"fog")==0) { // fog [Valaris] - map[m].flag.fog=1; - } - else if (strcmpi(w3,"sakura")==0) { // sakura [Valaris] - map[m].flag.sakura=1; - } - else if (strcmpi(w3,"leaves")==0) { // leaves [Valaris] - map[m].flag.leaves=1; - } - else if (strcmpi(w3,"rain")==0) { // rain [Valaris] - map[m].flag.rain=1; - } - else if (strcmpi(w3,"indoors")==0) { // celest - map[m].flag.indoors=1; - } - else if (strcmpi(w3,"nogo")==0) { // celest - map[m].flag.nogo=1; - } - - return 0; -} - -void npc_parsesrcfile(char *name) -{ - int m, lines = 0; - char line[1024]; - - FILE *fp = fopen (name,"r"); - if (fp == NULL) { - ShowError ("File not found : %s\n", name); - exit(1); - } - current_file = name; - - while (fgets(line, 1020, fp)) { - char w1[1024], w2[1024], w3[1024], w4[1024], mapname[1024]; - int i, j, w4pos, count; - lines++; - - if (line[0] == '/' && line[1] == '/') - continue; - // 不要なスペースやタブの連続は詰める - for (i = j = 0; line[i]; i++) { - if (line[i]==' ') { - if (!((line[i+1] && (isspace(line[i+1]) || line[i+1]==',')) || - (j && line[j-1]==','))) - line[j++]=' '; - } else if (line[i]=='\t') { - if (!(j && line[j-1]=='\t')) - line[j++]='\t'; - } else - line[j++]=line[i]; - } - // 最初はタブ区切りでチェックしてみて、ダメならスペース区切りで確認 - if ((count = sscanf(line,"%[^\t]\t%[^\t]\t%[^\t\r\n]\t%n%[^\t\r\n]", w1, w2, w3, &w4pos, w4)) < 3 && - (count = sscanf(line,"%s%s%s%n%s", w1, w2, w3, &w4pos, w4)) < 3) { - continue; - } - // マップの存在確認 - if (strcmp(w1,"-") !=0 && strcmpi(w1,"function") != 0 ){ - sscanf(w1,"%[^,]",mapname); - m = map_mapname2mapid(mapname); - if (strlen(mapname)>16 || m<0) { - // "mapname" is not assigned to this server - continue; - } - } - if (strcmpi(w2,"warp") == 0 && count > 3) { - npc_parse_warp(w1,w2,w3,w4); - } else if (strcmpi(w2,"shop") == 0 && count > 3) { - npc_parse_shop(w1,w2,w3,w4); - } else if (strcmpi(w2,"script") == 0 && count > 3) { - if (strcmpi(w1,"function") == 0) { - npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines); - } else { - npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines); - } - } else if ((i = 0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3) { - npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines); - } else if (strcmpi(w2,"monster") == 0 && count > 3) { - npc_parse_mob(w1,w2,w3,w4); - } else if (strcmpi(w2,"mapflag") == 0 && count >= 3) { - npc_parse_mapflag(w1,w2,w3,w4); - } - } - fclose(fp); - - return; -} - -static int npc_read_indoors(void) -{ - char *buf,*p; - int s, m; - - buf=(char *) grfio_reads("data\\indoorrswtable.txt",&s); - - if(buf==NULL) - return -1; - - buf[s]=0; - for(p=buf;p-buf<s;){ - char buf2[64]; - - if(sscanf(p,"%[^#]#",buf2) == 1){ - char map_name[64] = ""; - strncpy(map_name, buf2, strlen(buf2) - 4); - strcat(map_name, ".gat"); - if ((m = map_mapname2mapid(map_name)) >= 0) - map[m].flag.indoors=1; - } - - p=strchr(p,10); - if(!p) break; - p++; - } - aFree(buf); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\indoorrswtable.txt"); - ShowStatus(tmp_output); - - return 0; -} - -static int ev_db_final(void *key,void *data,va_list ap) -{ - aFree(data); - if(strstr((const char *) key,"::")!=NULL) - aFree(key); - return 0; -} -static int npcname_db_final(void *key,void *data,va_list ap) -{ - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int npc_cleanup_sub (struct block_list *bl, va_list ap) { - nullpo_retr(0, bl); - - switch(bl->type) { - case BL_NPC: - npc_unload((struct npc_data *)bl); - break; - case BL_MOB: - mob_unload((struct mob_data *)bl); - break; - } - - return 0; -} -int npc_reload(void) -{ - struct npc_src_list *nsl; - int m, last_npc_id; - time_t last_time = time(0); - int busy = 0; - char c = '-'; - - for (m = 0; m < map_num; m++) { - map_foreachinarea(npc_cleanup_sub, m, 0, 0, map[m].xs, map[m].ys, 0); - map[m].npc_num = 0; - } - if(ev_db) - strdb_final(ev_db,ev_db_final); - if(npcname_db) - strdb_final(npcname_db,npcname_db_final); - - // anything else we should cleanup? - // Reloading npc's now - ev_db = strdb_init(51); - npcname_db = strdb_init(24); - ev_db->release = ev_release; - npc_warp = npc_shop = npc_script = npc_mob = 0; - last_npc_id = npc_id; - - for (nsl = npc_src_first; nsl; nsl = nsl->next) { - npc_parsesrcfile(nsl->name); - printf("\r"); - ShowStatus("Loading NPCs... Working: "); - if (last_time != time(0)) { - last_time = time(0); - switch(busy) { - case 0: c='\\'; busy++; break; - case 1: c='|'; busy++; break; - case 2: c='/'; busy++; break; - case 3: c='-'; busy=0; - } - } - printf("[%c]",c); - fflush(stdout); - } - printf("\r"); - ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'" - CL_WHITE"%d"CL_RESET"' Warps\n\t-'" - CL_WHITE"%d"CL_RESET"' Shops\n\t-'" - CL_WHITE"%d"CL_RESET"' Scripts\n\t-'" - CL_WHITE"%d"CL_RESET"' Mobs\n", - npc_id - last_npc_id, "", npc_warp, npc_shop, npc_script, npc_mob); - - return 0; -} -/*========================================== - * 終了 - *------------------------------------------ - */ -int do_final_npc(void) -{ - int i; - struct block_list *bl; - struct npc_data *nd; - struct mob_data *md; - struct pet_data *pd; - - if(ev_db) - strdb_final(ev_db,ev_db_final); - if(npcname_db) - strdb_final(npcname_db,npcname_db_final); - - npc_clearsrcfile(); - - for (i = START_NPC_NUM; i < npc_id; i++){ - if((bl = map_id2bl(i))){ - if(bl->type == BL_NPC && (nd = (struct npc_data *)bl)){ - npc_unload(nd); - }else if (bl->type == BL_MOB && (md = (struct mob_data *)bl)){ - if (md->lootitem){ - aFree(md->lootitem); - md->lootitem = NULL; - } - aFree(md); - md = NULL; - }else if(bl->type == BL_PET && (pd = (struct pet_data *)bl)){ - aFree(pd); - pd = NULL; - } - } - } - - return 0; -} - -/*========================================== - * npc初期化 - *------------------------------------------ - */ -int do_init_npc(void) -{ - struct npc_src_list *nsl; - time_t last_time = time(0); - int busy = 0; - char c = '-'; - - // indoorrswtable.txt and etcinfo.txt [Celest] - if (battle_config.indoors_override_grffile) - npc_read_indoors(); - //npc_read_weather(); - - // comparing only the first 24 chars of labels that are 50 chars long isn't that nice - // will cause "duplicated" labels where actually no dup is... - //ev_db=strdb_init(24); - ev_db = strdb_init(51); - npcname_db = strdb_init(24); - ev_db->release = ev_release; - - memset(&ev_tm_b, -1, sizeof(ev_tm_b)); - - for (nsl = npc_src_first; nsl; nsl = nsl->next) { - /*if(nsl->prev){ // [Shinomori] - aFree(nsl->prev); - nsl->prev = NULL; - }*/ - // - npc_parsesrcfile(nsl->name); - current_file = NULL; - printf("\r"); - ShowStatus("Loading NPCs... Working: "); - if (last_time != time(0)) { - last_time = time(0); - switch(busy) { - case 0: c='\\'; busy++; break; - case 1: c='|'; busy++; break; - case 2: c='/'; busy++; break; - case 3: c='-'; busy=0; - } - } - printf("[%c]",c); - fflush(stdout); -// printf("\rLoading NPCs [%d]: %-54s",npc_id-START_NPC_NUM,nsl->name); -// fflush(stdout); - } - printf("\r"); - ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'" - CL_WHITE"%d"CL_RESET"' Warps\n\t-'" - CL_WHITE"%d"CL_RESET"' Shops\n\t-'" - CL_WHITE"%d"CL_RESET"' Scripts\n\t-'" - CL_WHITE"%d"CL_RESET"' Mobs\n", - npc_id - START_NPC_NUM, "", npc_warp, npc_shop, npc_script, npc_mob); - - add_timer_func_list(npc_walktimer,"npc_walktimer"); // [Valaris] - add_timer_func_list(npc_event_timer,"npc_event_timer"); - add_timer_func_list(npc_event_do_clock,"npc_event_do_clock"); - add_timer_func_list(npc_timerevent,"npc_timerevent"); - - //exit(1); - - return 0; -} diff --git a/src/map/npc.h b/src/map/npc.h deleted file mode 100644 index 2f81345d7..000000000 --- a/src/map/npc.h +++ /dev/null @@ -1,62 +0,0 @@ -// $Id: npc.h,v 1.5 2004/09/25 11:39:17 MouseJstr Exp $ -#ifndef _NPC_H_ -#define _NPC_H_ - -#define START_NPC_NUM 110000000 - -#define WARP_CLASS 45 -#define WARP_DEBUG_CLASS 722 -#define INVISIBLE_CLASS 32767 - -#ifdef PCRE_SUPPORT -void npc_chat_finalize(struct npc_data *nd); -#endif -int npc_chat_sub(struct block_list *bl, va_list ap); -int npc_event_dequeue(struct map_session_data *sd); -int npc_event_timer(int tid,unsigned int tick,int id,int data); -int npc_event(struct map_session_data *sd,const char *npcname,int); -int npc_timer_event(const char *eventname); // Added by RoVeRT -int npc_command(struct map_session_data *sd,char *npcname,char *command); -int npc_touch_areanpc(struct map_session_data *,int,int,int); -int npc_click(struct map_session_data *,int); -int npc_scriptcont(struct map_session_data *,int); -int npc_checknear(struct map_session_data *,int); -int npc_buysellsel(struct map_session_data *,int,int); -int npc_buylist(struct map_session_data *,int,unsigned short *); -int npc_selllist(struct map_session_data *,int,unsigned short *); -int npc_parse_mob(char *w1,char *w2,char *w3,char *w4); -int npc_parse_warp(char *w1,char *w2,char *w3,char *w4); -int npc_globalmessage(const char *name,char *mes); - -int npc_enable(const char *name,int flag); -struct npc_data* npc_name2id(const char *name); - -int npc_walktoxy(struct npc_data *nd,int x,int y,int easy); // npc walking [Valaris] -int npc_stop_walking(struct npc_data *nd,int type); -int npc_changestate(struct npc_data *nd,int state,int type); - -int npc_get_new_npc_id(void); - -void npc_addsrcfile(char *); -void npc_delsrcfile(char *); -int do_final_npc(void); -int do_init_npc(void); -int npc_event_do_oninit(void); -int npc_do_ontimer(int,int); - -int npc_event_doall(const char *name); -int npc_event_do(const char *name); -int npc_event_doall_id(const char *name, int id); - -int npc_timerevent_start(struct npc_data *nd, int rid); -int npc_timerevent_stop(struct npc_data *nd); -int npc_gettimerevent_tick(struct npc_data *nd); -int npc_settimerevent_tick(struct npc_data *nd,int newtimer); -int npc_remove_map(struct npc_data *nd); -int npc_unload(struct npc_data *nd); -int npc_reload(void); - -extern char *current_file; - -#endif - diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c deleted file mode 100644 index c15a26bf0..000000000 --- a/src/map/npc_chat.c +++ /dev/null @@ -1,502 +0,0 @@ -#ifdef PCRE_SUPPORT - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#ifdef __WIN32 -#define __USE_W32_SOCKETS -#include <windows.h> -#else -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif -#include <time.h> - -#include "../common/timer.h" -#include "../common/malloc.h" -#include "../common/version.h" -#include "../common/nullpo.h" -#include "../common/showmsg.h" - -#include "map.h" -#include "status.h" -#include "npc.h" -#include "chat.h" -#include "script.h" -#include "battle.h" - -#include "pcre.h" - -/** - * Written by MouseJstr in a vision... (2/21/2005) - * - * This allows you to make npc listen for spoken text (global - * messages) and pattern match against that spoken text using perl - * regular expressions. - * - * Please feel free to copy this code into your own personal ragnarok - * servers or distributions but please leave my name. Also, please - * wait until I've put it into the main eA branch which means I - * believe it is ready for distribution. - * - * So, how do people use this? - * - * The first and most important function is defpattern - * - * defpattern 1, "[^:]+: (.*) loves (.*)", "label"; - * - * this defines a new pattern in set 1 using perl syntax - * (http://www.troubleshooters.com/codecorn/littperl/perlreg.htm) - * and tells it to jump to the supplied label when the pattern - * is matched. - * - * each of the matched Groups will result in a variable being - * set ($p1$ through $p9$ with $p0$ being the entire string) - * before the script gets executed. - * - * activatepset 1; - * - * This activates a set of patterns.. You can have many pattern - * sets defined and many active all at once. This feature allows - * you to set up "conversations" and ever changing expectations of - * the pattern matcher - * - * deactivatepset 1; - * - * turns off a pattern set; - * - * deactivatepset -1; - * - * turns off ALL pattern sets; - * - * deletepset 1; - * - * deletes a pset - */ - -/* Structure containing all info associated with a single pattern - block */ - -struct pcrematch_entry { - struct pcrematch_entry *next_; - char *pattern_; - pcre *pcre_; - pcre_extra *pcre_extra_; - char *label_; -}; - -/* A set of patterns that can be activated and deactived with a single - command */ - -struct pcrematch_set { - struct pcrematch_set *next_, *prev_; - struct pcrematch_entry *head_; - int setid_; -}; - -/* - * Entire data structure hung off a NPC - * - * The reason I have done it this way (a void * in npc_data and then - * this) was to reduce the number of patches that needed to be applied - * to a ragnarok distribution to bring this code online. I - * also wanted people to be able to grab this one file to get updates - * without having to do a large number of changes. - */ - -struct npc_parse { - struct pcrematch_set *active_; - struct pcrematch_set *inactive_; -}; - - -/** - * delete everythign associated with a entry - * - * This does NOT do the list management - */ - -void finalize_pcrematch_entry(struct pcrematch_entry *e) { - free(e->pcre_); - free(e->pcre_extra_); - aFree(e->pattern_); - aFree(e->label_); -} - -/** - * Lookup (and possibly create) a new set of patterns by the set id - */ -static struct pcrematch_set * lookup_pcreset(struct npc_data *nd,int setid) -{ - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - nd->chatdb = npcParse = (struct npc_parse *) - aCalloc(sizeof(struct npc_parse), 1); - - pcreset = npcParse->active_; - - while (pcreset != NULL) { - if (pcreset->setid_ == setid) - break; - pcreset = pcreset->next_; - } - if (pcreset == NULL) - pcreset = npcParse->inactive_; - - while (pcreset != NULL) { - if (pcreset->setid_ == setid) - break; - pcreset = pcreset->next_; - } - - if (pcreset == NULL) { - pcreset = (struct pcrematch_set *) - aCalloc(sizeof(struct pcrematch_set), 1); - pcreset->next_ = npcParse->inactive_; - if (pcreset->next_ != NULL) - pcreset->next_->prev_ = pcreset; - pcreset->prev_ = 0; - npcParse->inactive_ = pcreset; - pcreset->setid_ = setid; - } - - return pcreset; -} - -/** - * activate a set of patterns. - * - * if the setid does not exist, this will silently return - */ - -static void activate_pcreset(struct npc_data *nd,int setid) { - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; // Nothing to activate... - pcreset = npcParse->inactive_; - while (pcreset != NULL) { - if (pcreset->setid_ == setid) - break; - pcreset = pcreset->next_; - } - if (pcreset == NULL) - return; // not in inactive list - if (pcreset->next_ != NULL) - pcreset->next_->prev_ = pcreset->prev_; - if (pcreset->prev_ != NULL) - pcreset->prev_->next_ = pcreset->next_; - else - npcParse->inactive_ = pcreset->next_; - - pcreset->prev_ = NULL; - pcreset->next_ = npcParse->active_; - if (pcreset->next_ != NULL) - pcreset->next_->prev_ = pcreset; - npcParse->active_ = pcreset; -} - -/** - * deactivate a set of patterns. - * - * if the setid does not exist, this will silently return - */ - -static void deactivate_pcreset(struct npc_data *nd,int setid) { - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; // Nothing to deactivate... - if (setid == -1) { - while(npcParse->active_ != NULL) - deactivate_pcreset(nd, npcParse->active_->setid_); - return; - } - pcreset = npcParse->active_; - while (pcreset != NULL) { - if (pcreset->setid_ == setid) - break; - pcreset = pcreset->next_; - } - if (pcreset == NULL) - return; // not in active list - if (pcreset->next_ != NULL) - pcreset->next_->prev_ = pcreset->prev_; - if (pcreset->prev_ != NULL) - pcreset->prev_->next_ = pcreset->next_; - else - npcParse->active_ = pcreset->next_; - - pcreset->prev_ = NULL; - pcreset->next_ = npcParse->inactive_; - if (pcreset->next_ != NULL) - pcreset->next_->prev_ = pcreset; - npcParse->inactive_ = pcreset; -} - -/** - * delete a set of patterns. - */ -static void delete_pcreset(struct npc_data *nd,int setid) { - int active = 1; - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; // Nothing to deactivate... - pcreset = npcParse->active_; - while (pcreset != NULL) { - if (pcreset->setid_ == setid) - break; - pcreset = pcreset->next_; - } - if (pcreset == NULL) { - active = 0; - pcreset = npcParse->inactive_; - while (pcreset != NULL) { - if (pcreset->setid_ == setid) - break; - pcreset = pcreset->next_; - } - } - if (pcreset == NULL) - return; - - if (pcreset->next_ != NULL) - pcreset->next_->prev_ = pcreset->prev_; - if (pcreset->prev_ != NULL) - pcreset->prev_->next_ = pcreset->next_; - else if(active == 1) - npcParse->active_ = pcreset->next_; - else - npcParse->inactive_ = pcreset->next_; - - pcreset->prev_ = NULL; - pcreset->next_ = NULL; - - while (pcreset->head_) { - struct pcrematch_entry *n = pcreset->head_->next_;; - finalize_pcrematch_entry(pcreset->head_); - pcreset->head_ = n; - } - - aFree(pcreset); -} - -/** - * create a new pattern entry - */ -static struct pcrematch_entry *create_pcrematch_entry(struct pcrematch_set * set) { - struct pcrematch_entry * e = (struct pcrematch_entry *) - aCalloc(sizeof(struct pcrematch_entry), 1); - struct pcrematch_entry * last = set->head_; - - // Normally we would have just stuck it at the end of the list but - // this doesn't sink up with peoples usage pattern. They wanted - // the items defined first to have a higher priority then the - // items defined later.. as a result, we have to do some work up - // front.. - - /* if we are the first pattern, stick us at the end */ - if (last == NULL) { - set->head_ = e; - return e; - } - - /* Look for the last entry */ - while (last->next_ != NULL) - last = last->next_; - - last->next_ = e; - e->next_ = NULL; - - return e; -} - -/** - * define/compile a new pattern - */ - -void npc_chat_def_pattern(struct npc_data *nd, int setid, - const char *pattern, const char *label) -{ - const char *err; - int erroff; - - struct pcrematch_set * s = lookup_pcreset(nd, setid); - struct pcrematch_entry *e = create_pcrematch_entry(s); - e->pattern_ = aStrdup(pattern); - e->label_ = aStrdup(label); - e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); - e->pcre_extra_ = pcre_study(e->pcre_, 0, &err); -} - -/** - * Delete everything associated with a NPC concerning the pattern - * matching code - * - * this could be more efficent but.. how often do you do this? - */ -void npc_chat_finalize(struct npc_data *nd) -{ - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; - - while(npcParse->active_) - delete_pcreset(nd, npcParse->active_->setid_); - - while(npcParse->inactive_) - delete_pcreset(nd, npcParse->inactive_->setid_); -} - -/** - * Handler called whenever a global message is spoken in a NPC's area - */ -int npc_chat_sub(struct block_list *bl, va_list ap) -{ - struct npc_data *nd = (struct npc_data *)bl; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - unsigned char *msg; - int len, pos, i; - struct map_session_data *sd; - struct npc_label_list *lst; - struct pcrematch_set *pcreset; - - // Not interested in anything you might have to say... - if (npcParse == NULL || npcParse->active_ == NULL) - return 0; - - msg = va_arg(ap,unsigned char*); - len = va_arg(ap,int); - sd = va_arg(ap,struct map_session_data *); - - // grab the active list - pcreset = npcParse->active_; - - // interate across all active sets - while (pcreset != NULL) { - struct pcrematch_entry *e = pcreset->head_; - // interate across all patterns in that set - while (e != NULL) { - int offsets[20]; - char buf[255]; - // perform pattern match - int r = pcre_exec(e->pcre_, e->pcre_extra_, (char *) msg, len, 0, - 0, offsets, sizeof(offsets) / sizeof(offsets[0])); - if (r >= 0) { - // save out the matched strings - switch (r) { - case 10: - memcpy(buf, &msg[offsets[18]], offsets[19]); - buf[offsets[19]] = '\0'; - set_var(sd, "$p9$", buf); - case 9: - memcpy(buf, &msg[offsets[16]], offsets[17]); - buf[offsets[17]] = '\0'; - set_var(sd, "$p8$", buf); - case 8: - memcpy(buf, &msg[offsets[14]], offsets[15]); - buf[offsets[15]] = '\0'; - set_var(sd, "$p7$", buf); - case 7: - memcpy(buf, &msg[offsets[12]], offsets[13]); - buf[offsets[13]] = '\0'; - set_var(sd, "$p6$", buf); - case 6: - memcpy(buf, &msg[offsets[10]], offsets[11]); - buf[offsets[11]] = '\0'; - set_var(sd, "$p5$", buf); - case 5: - memcpy(buf, &msg[offsets[8]], offsets[9]); - buf[offsets[9]] = '\0'; - set_var(sd, "$p4$", buf); - case 4: - memcpy(buf, &msg[offsets[6]], offsets[7]); - buf[offsets[7]] = '\0'; - set_var(sd, "$p3$", buf); - case 3: - memcpy(buf, &msg[offsets[4]], offsets[5]); - buf[offsets[5]] = '\0'; - set_var(sd, "$p2$", buf); - case 2: - memcpy(buf, &msg[offsets[2]], offsets[3]); - buf[offsets[3]] = '\0'; - set_var(sd, "$p1$", buf); - case 1: - memcpy(buf, &msg[offsets[0]], offsets[1]); - buf[offsets[1]] = '\0'; - set_var(sd, "$p0$", buf); - } - - // find the target label.. this sucks.. - lst=nd->u.scr.label_list; - pos = -1; - for (i = 0; i < nd->u.scr.label_list_num; i++) { - if (strncmp(lst[i].name, e->label_, sizeof(lst[i].name)) == 0) { - pos = lst[i].pos; - break; - } - } - if (pos == -1) { - printf("Unable to find label: %s", e->label_); - // unable to find label... do something.. - return 0; - } - // run the npc script - run_script(nd->u.scr.script,pos,sd->bl.id,nd->bl.id); - return 0; - } - e = e->next_; - } - pcreset = pcreset->next_; - } - - return 0; -} - -// Various script builtins used to support these functions - -int buildin_defpattern(struct script_state *st) { - int setid=conv_num(st,& (st->stack->stack_data[st->start+2])); - char *pattern=conv_str(st,& (st->stack->stack_data[st->start+3])); - char *label=conv_str(st,& (st->stack->stack_data[st->start+4])); - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - - npc_chat_def_pattern(nd, setid, pattern, label); - - return 0; -} - -int buildin_activatepset(struct script_state *st) { - int setid=conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - - activate_pcreset(nd, setid); - - return 0; -} -int buildin_deactivatepset(struct script_state *st) { - int setid=conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - - deactivate_pcreset(nd, setid); - - return 0; -} -int buildin_deletepset(struct script_state *st) { - int setid=conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - - delete_pcreset(nd, setid); - - return 0; -} - - -#endif diff --git a/src/map/party.c b/src/map/party.c deleted file mode 100644 index 7eb3f02dc..000000000 --- a/src/map/party.c +++ /dev/null @@ -1,657 +0,0 @@ -// $Id: party.c,v 1.2 2004/09/22 02:59:47 Akitasha Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "party.h" -#include "db.h" -#include "timer.h" -#include "socket.h" -#include "nullpo.h" -#include "malloc.h" -#include "pc.h" -#include "map.h" -#include "battle.h" -#include "intif.h" -#include "clif.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define PARTY_SEND_XYHP_INVERVAL 1000 // 座標やHP送信の間隔 - -static struct dbt* party_db; - -int party_send_xyhp_timer(int tid,unsigned int tick,int id,int data); -/*========================================== - * 終了 - *------------------------------------------ - */ -static int party_db_final(void *key,void *data,va_list ap) -{ - aFree(data); - return 0; -} -void do_final_party(void) -{ - if(party_db) - numdb_final(party_db,party_db_final); -} -// 初期化 -void do_init_party(void) -{ - party_db=numdb_init(); - add_timer_func_list(party_send_xyhp_timer,"party_send_xyhp_timer"); - add_timer_interval(gettick()+PARTY_SEND_XYHP_INVERVAL,party_send_xyhp_timer,0,0,PARTY_SEND_XYHP_INVERVAL); -} - -// 検索 -struct party *party_search(int party_id) -{ - return (struct party *) numdb_search(party_db,party_id); -} -int party_searchname_sub(void *key,void *data,va_list ap) -{ - struct party *p=(struct party *)data,**dst; - char *str; - str=va_arg(ap,char *); - dst=va_arg(ap,struct party **); - if(strcmpi(p->name,str)==0) - *dst=p; - return 0; -} -// パーティ名検索 -struct party* party_searchname(char *str) -{ - struct party *p=NULL; - numdb_foreach(party_db,party_searchname_sub,str,&p); - return p; -} -// 作成要求 -int party_create(struct map_session_data *sd,char *name,int item,int item2) -{ - nullpo_retr(0, sd); - - if(sd->status.party_id==0) - intif_create_party(sd,name,item,item2); - else - clif_party_created(sd,2); - return 0; -} - -// 作成可否 -int party_created(int account_id,int fail,int party_id,char *name) -{ - struct map_session_data *sd; - sd=map_id2sd(account_id); - - nullpo_retr(0, sd); - - if(fail==0){ - struct party *p; - sd->status.party_id=party_id; - if((p=(struct party *) numdb_search(party_db,party_id))!=NULL){ - printf("party: id already exists!\n"); - exit(1); - } - p=(struct party *)aCalloc(1,sizeof(struct party)); - p->party_id=party_id; - memcpy(p->name,name,24); - numdb_insert(party_db,party_id,p); - clif_party_created(sd,0); - }else{ - clif_party_created(sd,1); - } - return 0; -} - -// 情報要求 -int party_request_info(int party_id) -{ - return intif_request_partyinfo(party_id); -} - -// 所属キャラの確認 -int party_check_member(struct party *p) -{ - int i; - struct map_session_data *sd; - - nullpo_retr(0, p); - - for(i=0;i<fd_max;i++){ - if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth){ - if(sd->status.party_id==p->party_id){ - int j,f=1; - for(j=0;j<MAX_PARTY;j++){ // パーティにデータがあるか確認 - if( p->member[j].account_id==sd->status.account_id){ - if( strcmp(p->member[j].name,sd->status.name)==0 ) - f=0; // データがある - else - p->member[j].sd=NULL; // 同垢別キャラだった - } - } - if(f){ - sd->status.party_id=0; - if(battle_config.error_log) - printf("party: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name); - } - } - } - } - return 0; -} - -// 情報所得失敗(そのIDのキャラを全部未所属にする) -int party_recv_noinfo(int party_id) -{ - int i; - struct map_session_data *sd; - for(i=0;i<fd_max;i++){ - if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth){ - if(sd->status.party_id==party_id) - sd->status.party_id=0; - } - } - return 0; -} -// 情報所得 -int party_recv_info(struct party *sp) -{ - struct party *p; - int i; - - nullpo_retr(0, sp); - - if((p=(struct party *) numdb_search(party_db,sp->party_id))==NULL){ - p=(struct party *)aCalloc(1,sizeof(struct party)); - numdb_insert(party_db,sp->party_id,p); - - // 最初のロードなのでユーザーのチェックを行う - party_check_member(sp); - } - memcpy(p,sp,sizeof(struct party)); - - for(i=0;i<MAX_PARTY;i++){ // sdの設定 - struct map_session_data *sd = map_id2sd(p->member[i].account_id); - p->member[i].sd=(sd!=NULL && sd->status.party_id==p->party_id && !sd->state.waitingdisconnect)?sd:NULL; - } - - clif_party_info(p,-1); - - for(i=0;i<MAX_PARTY;i++){ // 設定情報の送信 -// struct map_session_data *sd = map_id2sd(p->member[i].account_id); - struct map_session_data *sd = p->member[i].sd; - if(sd!=NULL && sd->party_sended==0){ - clif_party_option(p,sd,0x100); - sd->party_sended=1; - } - } - - return 0; -} - -// パーティへの勧誘 -int party_invite(struct map_session_data *sd,int account_id) -{ - struct map_session_data *tsd= map_id2sd(account_id); - struct party *p=party_search(sd->status.party_id); - int i; - - nullpo_retr(0, sd); - - if(tsd==NULL || p==NULL) - return 0; - if(!battle_config.invite_request_check) { - if (tsd->guild_invite>0 || tsd->trade_partner) { // 相手が取引中かどうか - clif_party_inviteack(sd,tsd->status.name,0); - return 0; - } - } - if( tsd->status.party_id>0 || tsd->party_invite>0 ){ // 相手の所属確認 - clif_party_inviteack(sd,tsd->status.name,0); - return 0; - } - for(i=0;i<MAX_PARTY;i++){ // 同アカウント確認 - if(p->member[i].account_id==account_id){ - clif_party_inviteack(sd,tsd->status.name,0); - return 0; - } - } - - tsd->party_invite=sd->status.party_id; - tsd->party_invite_account=sd->status.account_id; - - clif_party_invite(sd,tsd); - return 0; -} -// パーティ勧誘への返答 -int party_reply_invite(struct map_session_data *sd,int account_id,int flag) -{ - struct map_session_data *tsd= map_id2sd(account_id); - - nullpo_retr(0, sd); - - if(flag==1){ // 承諾 - //inter鯖へ追加要求 - intif_party_addmember( sd->party_invite, sd->status.account_id ); - return 0; - } - else { // 拒否 - sd->party_invite=0; - sd->party_invite_account=0; - if(tsd==NULL) - return 0; - clif_party_inviteack(tsd,sd->status.name,1); - } - return 0; -} -// パーティが追加された -int party_member_added(int party_id,int account_id,int flag) -{ - struct map_session_data *sd = map_id2sd(account_id),*sd2; - if(sd == NULL){ - if (flag == 0) { - if(battle_config.error_log) - printf("party: member added error %d is not online\n",account_id); - intif_party_leave(party_id,account_id); // キャラ側に登録できなかったため脱退要求を出す - } - return 0; - } - sd2=map_id2sd(sd->party_invite_account); - sd->party_invite=0; - sd->party_invite_account=0; - - if(flag==1){ // 失敗 - if( sd2!=NULL ) - clif_party_inviteack(sd2,sd->status.name,0); - return 0; - } - - // 成功 - sd->party_sended=0; - sd->status.party_id=party_id; - - if( sd2!=NULL) - clif_party_inviteack(sd2,sd->status.name,2); - - // いちおう競合確認 - party_check_conflict(sd); - - return 0; -} -// パーティ除名要求 -int party_removemember(struct map_session_data *sd,int account_id,char *name) -{ - struct party *p; - int i; - - nullpo_retr(0, sd); - - if( (p = party_search(sd->status.party_id)) == NULL ) - return 0; - - for(i=0;i<MAX_PARTY;i++){ // リーダーかどうかチェック - if(p->member[i].account_id==sd->status.account_id) - if(p->member[i].leader==0) - return 0; - } - - for(i=0;i<MAX_PARTY;i++){ // 所属しているか調べる - if(p->member[i].account_id==account_id){ - intif_party_leave(p->party_id,account_id); - return 0; - } - } - return 0; -} - -// パーティ脱退要求 -int party_leave(struct map_session_data *sd) -{ - struct party *p; - int i; - - nullpo_retr(0, sd); - - if( (p = party_search(sd->status.party_id)) == NULL ) - return 0; - - for(i=0;i<MAX_PARTY;i++){ // 所属しているか - if(p->member[i].account_id==sd->status.account_id){ - intif_party_leave(p->party_id,sd->status.account_id); - return 0; - } - } - return 0; -} -// パーティメンバが脱退した -int party_member_leaved(int party_id,int account_id,char *name) -{ - struct map_session_data *sd=map_id2sd(account_id); - struct party *p=party_search(party_id); - if(p!=NULL){ - int i; - for(i=0;i<MAX_PARTY;i++) - if(p->member[i].account_id==account_id){ - clif_party_leaved(p,sd,account_id,name,0x00); - p->member[i].account_id=0; - p->member[i].sd=NULL; - } - } - if(sd!=NULL && sd->status.party_id==party_id){ - sd->status.party_id=0; - sd->party_sended=0; - } - return 0; -} -// パーティ解散通知 -int party_broken(int party_id) -{ - struct party *p; - int i; - if( (p=party_search(party_id))==NULL ) - return 0; - - for(i=0;i<MAX_PARTY;i++){ - if(p->member[i].sd!=NULL){ - clif_party_leaved(p,p->member[i].sd, - p->member[i].account_id,p->member[i].name,0x10); - p->member[i].sd->status.party_id=0; - p->member[i].sd->party_sended=0; - } - } - numdb_erase(party_db,party_id); - return 0; -} -// パーティの設定変更要求 -int party_changeoption(struct map_session_data *sd,int exp,int item) -{ - struct party *p; - - nullpo_retr(0, sd); - - if( sd->status.party_id==0 || (p=party_search(sd->status.party_id))==NULL ) - return 0; - intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item); - return 0; -} -// パーティの設定変更通知 -int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) -{ - struct party *p; - struct map_session_data *sd=map_id2sd(account_id); - if( (p=party_search(party_id))==NULL) - return 0; - - if(!(flag&0x01)) p->exp=exp; - if(!(flag&0x10)) p->item=item; - clif_party_option(p,sd,flag); - return 0; -} - -// パーティメンバの移動通知 -int party_recv_movemap(int party_id,int account_id,char *map,int online,int lv) -{ - struct party *p; - int i; - if( (p=party_search(party_id))==NULL) - return 0; - for(i=0;i<MAX_PARTY;i++){ - struct party_member *m=&p->member[i]; - if( m == NULL ){ - printf("party_recv_movemap nullpo?\n"); - return 0; - } - if(m->account_id==account_id){ - memcpy(m->map,map,16); - m->online=online; - m->lv=lv; - break; - } - } - if(i==MAX_PARTY){ - if(battle_config.error_log) - printf("party: not found member %d on %d[%s]",account_id,party_id,p->name); - return 0; - } - - for(i=0;i<MAX_PARTY;i++){ // sd再設定 - struct map_session_data *sd= map_id2sd(p->member[i].account_id); - p->member[i].sd=(sd!=NULL && sd->status.party_id==p->party_id && !sd->state.waitingdisconnect)?sd:NULL; - } - - party_send_xy_clear(p); // 座標再通知要請 - - clif_party_info(p,-1); - return 0; -} - -// パーティメンバの移動 -int party_send_movemap(struct map_session_data *sd) -{ - struct party *p; - - nullpo_retr(0, sd); - - if( sd->status.party_id==0 ) - return 0; - intif_party_changemap(sd,1); - - if( sd->party_sended!=0 ) // もうパーティデータは送信済み - return 0; - - // 競合確認 - party_check_conflict(sd); - - // あるならパーティ情報送信 - if( (p=party_search(sd->status.party_id))!=NULL ){ - party_check_member(p); // 所属を確認する - if(sd->status.party_id==p->party_id){ - clif_party_info(p,sd->fd); - clif_party_option(p,sd,0x100); - sd->party_sended=1; - } - } - - return 0; -} -// パーティメンバのログアウト -int party_send_logout(struct map_session_data *sd) -{ - struct party *p; - - nullpo_retr(0, sd); - - if( sd->status.party_id>0 ) - intif_party_changemap(sd,0); - - // sdが無効になるのでパーティ情報から削除 - if( (p=party_search(sd->status.party_id))!=NULL ){ - int i; - for(i=0;i<MAX_PARTY;i++) - if(p->member[i].sd==sd) - p->member[i].sd=NULL; - } - - return 0; -} -// パーティメッセージ送信 -int party_send_message(struct map_session_data *sd,char *mes,int len) -{ - if(sd->status.party_id==0) - return 0; - intif_party_message(sd->status.party_id,sd->status.account_id,mes,len); - party_recv_message(sd->status.party_id,sd->status.account_id,mes,len); - return 0; -} - -// パーティメッセージ受信 -int party_recv_message(int party_id,int account_id,char *mes,int len) -{ - struct party *p; - if( (p=party_search(party_id))==NULL) - return 0; - clif_party_message(p,account_id,mes,len); - return 0; -} -// パーティ競合確認 -int party_check_conflict(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - intif_party_checkconflict(sd->status.party_id,sd->status.account_id,sd->status.name); - return 0; -} - - -// 位置やHP通知用 -int party_send_xyhp_timer_sub(void *key,void *data,va_list ap) -{ - struct party *p=(struct party *)data; - int i; - - nullpo_retr(0, p); - - for(i=0;i<MAX_PARTY;i++){ - struct map_session_data *sd; - if((sd=p->member[i].sd)!=NULL){ - // 座標通知 - if(sd->party_x!=sd->bl.x || sd->party_y!=sd->bl.y){ - clif_party_xy(p,sd); - sd->party_x=sd->bl.x; - sd->party_y=sd->bl.y; - } - // HP通知 - if(sd->party_hp!=sd->status.hp){ - clif_party_hp(p,sd); - sd->party_hp=sd->status.hp; - } - - } - } - return 0; -} -// 位置やHP通知 -int party_send_xyhp_timer(int tid,unsigned int tick,int id,int data) -{ - numdb_foreach(party_db,party_send_xyhp_timer_sub,tick); - return 0; -} - -// 位置通知クリア -int party_send_xy_clear(struct party *p) -{ - int i; - - nullpo_retr(0, p); - - for(i=0;i<MAX_PARTY;i++){ - struct map_session_data *sd; - if((sd=p->member[i].sd)!=NULL){ - sd->party_x=-1; - sd->party_y=-1; - sd->party_hp=-1; - } - } - return 0; -} -// HP通知の必要性検査用(map_foreachinmoveareaから呼ばれる) -int party_send_hp_check(struct block_list *bl,va_list ap) -{ - int party_id; - int *flag; - struct map_session_data *sd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd=(struct map_session_data *)bl); - - party_id=va_arg(ap,int); - flag=va_arg(ap,int *); - - if(sd->status.party_id==party_id){ - *flag=1; - sd->party_hp=-1; - } - return 0; -} - -// exp share and added zeny share [Valaris] -int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny) -{ - struct map_session_data *sd; - int i,c; - - nullpo_retr(0, p); - - for (i=c=0; i < MAX_PARTY; i++) - if ((sd = p->member[i].sd) != NULL && p->member[i].online && sd->bl.m == map /*&& session[sd->fd] != NULL*/) // should be done in socket.c - c++; - - if(c == 0) - return 0; - for (i = 0; i < MAX_PARTY; i++) - if ((sd = p->member[i].sd) != NULL && p->member[i].online && sd->bl.m == map /*&& session[sd->fd] != NULL*/) { - if (battle_config.idle_no_share && (/* pc_issit(sd) || */ sd->chatID || (sd->idletime < (tick_ - 120)))) - continue; - #ifdef TWILIGHT - pc_gainexp(sd,base_exp,job_exp); - #else - pc_gainexp(sd,(base_exp/c)+1,(job_exp/c)+1); - #endif - if (battle_config.zeny_from_mobs) // zeny from mobs [Valaris] - pc_getzeny(sd,(zeny/c)+1); - } - return 0; -} - -// 同じマップのパーティメンバー全体に処理をかける -// type==0 同じマップ -// !=0 画面内 -void party_foreachsamemap(int (*func)(struct block_list*,va_list), - struct map_session_data *sd,int type,...) -{ - struct party *p; - va_list ap; - int i; - int x0,y0,x1,y1; - struct block_list *list[MAX_PARTY]; - int blockcount=0; - - nullpo_retv(sd); - - if((p=party_search(sd->status.party_id))==NULL) - return; - - x0=sd->bl.x-AREA_SIZE; - y0=sd->bl.y-AREA_SIZE; - x1=sd->bl.x+AREA_SIZE; - y1=sd->bl.y+AREA_SIZE; - - va_start(ap,type); - - for(i=0;i<MAX_PARTY;i++){ - struct party_member *m=&p->member[i]; - if(m->sd!=NULL){ - if(sd->bl.m!=m->sd->bl.m) - continue; - if(type!=0 && - (m->sd->bl.x<x0 || m->sd->bl.y<y0 || - m->sd->bl.x>x1 || m->sd->bl.y>y1 ) ) - continue; - list[blockcount++]=&m->sd->bl; - } - } - - map_freeblock_lock(); // メモリからの解放を禁止する - - for(i=0;i<blockcount;i++) - if(list[i]->prev) // 有効かどうかチェック - func(list[i],ap); - - map_freeblock_unlock(); // 解放を許可する - - va_end(ap); -} diff --git a/src/map/party.h b/src/map/party.h deleted file mode 100644 index 203dd1057..000000000 --- a/src/map/party.h +++ /dev/null @@ -1,47 +0,0 @@ -// $Id: party.h,v 1.3 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _PARTY_H_ -#define _PARTY_H_ - -#include <stdarg.h> - -struct party; -struct map_session_data; -struct block_list; - -void do_init_party(void); -void do_final_party(void); -struct party *party_search(int party_id); -struct party* party_searchname(char *str); - -int party_create(struct map_session_data *sd,char *name, int item, int item2); -int party_created(int account_id,int fail,int party_id,char *name); -int party_request_info(int party_id); -int party_invite(struct map_session_data *sd,int account_id); -int party_member_added(int party_id,int account_id,int flag); -int party_leave(struct map_session_data *sd); -int party_removemember(struct map_session_data *sd,int account_id,char *name); -int party_member_leaved(int party_id,int account_id,char *name); -int party_reply_invite(struct map_session_data *sd,int account_id,int flag); -int party_recv_noinfo(int party_id); -int party_recv_info(struct party *sp); -int party_recv_movemap(int party_id,int account_id,char *map,int online,int lv); -int party_broken(int party_id); -int party_optionchanged(int party_id,int account_id,int exp,int item,int flag); -int party_changeoption(struct map_session_data *sd,int exp,int item); - -int party_send_movemap(struct map_session_data *sd); -int party_send_logout(struct map_session_data *sd); - -int party_send_message(struct map_session_data *sd,char *mes,int len); -int party_recv_message(int party_id,int account_id,char *mes,int len); - -int party_check_conflict(struct map_session_data *sd); - -int party_send_xy_clear(struct party *p); -int party_send_hp_check(struct block_list *bl,va_list ap); - -int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny); - -void party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int type,...); - -#endif diff --git a/src/map/path.c b/src/map/path.c deleted file mode 100644 index c2b852469..000000000 --- a/src/map/path.c +++ /dev/null @@ -1,470 +0,0 @@ -// $Id: path.c,v 1.1.1.1 2004/09/10 17:27:00 MagicalTux Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "map.h" -#include "battle.h" -#include "nullpo.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -//#define PATH_STANDALONETEST - -#define MAX_HEAP 150 -struct tmp_path { short x,y,dist,before,cost; char dir,flag;}; -#define calc_index(x,y) (((x)+(y)*MAX_WALKPATH) & (MAX_WALKPATH*MAX_WALKPATH-1)) - -/*========================================== - * 経路探索補助heap push - *------------------------------------------ - */ -static void push_heap_path(int *heap,struct tmp_path *tp,int index) -{ - int i,h; - - if( heap == NULL || tp == NULL ){ - printf("push_heap_path nullpo\n"); - return; - } - - heap[0]++; - - for(h=heap[0]-1,i=(h-1)/2; - h>0 && tp[index].cost<tp[heap[i+1]].cost; - i=(h-1)/2) - heap[h+1]=heap[i+1],h=i; - heap[h+1]=index; -} - -/*========================================== - * 経路探索補助heap update - * costが減ったので根の方へ移動 - *------------------------------------------ - */ -static void update_heap_path(int *heap,struct tmp_path *tp,int index) -{ - int i,h; - - nullpo_retv(heap); - nullpo_retv(tp); - - for(h=0;h<heap[0];h++) - if(heap[h+1]==index) - break; - if(h==heap[0]){ - fprintf(stderr,"update_heap_path bug\n"); - exit(1); - } - for(i=(h-1)/2; - h>0 && tp[index].cost<tp[heap[i+1]].cost; - i=(h-1)/2) - heap[h+1]=heap[i+1],h=i; - heap[h+1]=index; -} - -/*========================================== - * 経路探索補助heap pop - *------------------------------------------ - */ -static int pop_heap_path(int *heap,struct tmp_path *tp) -{ - int i,h,k; - int ret,last; - - nullpo_retr(-1, heap); - nullpo_retr(-1, tp); - - if(heap[0]<=0) - return -1; - ret=heap[1]; - last=heap[heap[0]]; - heap[0]--; - - for(h=0,k=2;k<heap[0];k=k*2+2){ - if(tp[heap[k+1]].cost>tp[heap[k]].cost) - k--; - heap[h+1]=heap[k+1], h=k; - } - if(k==heap[0]) - heap[h+1]=heap[k], h=k-1; - - for(i=(h-1)/2; - h>0 && tp[heap[i+1]].cost>tp[last].cost; - i=(h-1)/2) - heap[h+1]=heap[i+1],h=i; - heap[h+1]=last; - - return ret; -} - -/*========================================== - * 現在の点のcost計算 - *------------------------------------------ - */ -static int calc_cost(struct tmp_path *p,int x1,int y1) -{ - int xd,yd; - - nullpo_retr(0, p); - - xd=x1-p->x; - if(xd<0) xd=-xd; - yd=y1-p->y; - if(yd<0) yd=-yd; - return (xd+yd)*10+p->dist; -} - -/*========================================== - * 必要ならpathを追加/修正する - *------------------------------------------ - */ -static int add_path(int *heap,struct tmp_path *tp,int x,int y,int dist,int dir,int before,int x1,int y1) -{ - int i; - - nullpo_retr(0, heap); - nullpo_retr(0, tp); - - i=calc_index(x,y); - - if(tp[i].x==x && tp[i].y==y){ - if(tp[i].dist>dist){ - tp[i].dist=dist; - tp[i].dir=dir; - tp[i].before=before; - tp[i].cost=calc_cost(&tp[i],x1,y1); - if(tp[i].flag) - push_heap_path(heap,tp,i); - else - update_heap_path(heap,tp,i); - tp[i].flag=0; - } - return 0; - } - - if(tp[i].x || tp[i].y) - return 1; - - tp[i].x=x; - tp[i].y=y; - tp[i].dist=dist; - tp[i].dir=dir; - tp[i].before=before; - tp[i].cost=calc_cost(&tp[i],x1,y1); - tp[i].flag=0; - push_heap_path(heap,tp,i); - - return 0; -} - - -/*========================================== - * (x,y)が移動不可能地帯かどうか - * flag 0x10000 遠距離攻撃判定 - *------------------------------------------ - */ -static int can_place(struct map_data *m,int x,int y,int flag) -{ - nullpo_retr(0, m); - - if(map_getcellp(m,x,y,CELL_CHKPASS)) - return 1; - else if((flag&0x10000)&&map_getcellp(m,x,y,CELL_CHKGROUND)) - return 1; - return 0; -} - -/*========================================== - * (x0,y0)から(x1,y1)へ1歩で移動可能か計算 - *------------------------------------------ - */ -static int can_move(struct map_data *m,int x0,int y0,int x1,int y1,int flag) -{ - nullpo_retr(0, m); - - if(x0-x1<-1 || x0-x1>1 || y0-y1<-1 || y0-y1>1) - return 0; - if(x1<0 || y1<0 || x1>=m->xs || y1>=m->ys) - return 0; - if(!can_place(m,x0,y0,flag)) - return 0; - if(!can_place(m,x1,y1,flag)) - return 0; - if(x0==x1 || y0==y1) - return 1; - if(!can_place(m,x0,y1,flag) || !can_place(m,x1,y0,flag)) - return 0; - return 1; -} -/*========================================== - * (x0,y0)から(dx,dy)方向へcountセル分 - * 吹き飛ばしたあとの座標を所得 - *------------------------------------------ - */ -int path_blownpos(int m,int x0,int y0,int dx,int dy,int count) -{ - struct map_data *md; - - if(!map[m].gat) - return -1; - md=&map[m]; - - if(count>15){ // 最大10マスに制限 - if(battle_config.error_log) - printf("path_blownpos: count too many %d !\n",count); - count=15; - } - if(dx>1 || dx<-1 || dy>1 || dy<-1){ - if(battle_config.error_log) - printf("path_blownpos: illeagal dx=%d or dy=%d !\n",dx,dy); - dx=(dx>=0)?1:((dx<0)?-1:0); - dy=(dy>=0)?1:((dy<0)?-1:0); - } - - while( (count--)>0 && (dx!=0 || dy!=0) ){ - if( !can_move(md,x0,y0,x0+dx,y0+dy,0) ){ - int fx=(dx!=0 && can_move(md,x0,y0,x0+dx,y0,0)); - int fy=(dy!=0 && can_move(md,x0,y0,x0,y0+dy,0)); - if( fx && fy ){ - if(rand()&1) dx=0; - else dy=0; - } - if( !fx ) dx=0; - if( !fy ) dy=0; - } - x0+=dx; - y0+=dy; - } - return (x0<<16)|y0; -} - -/*========================================== - * タヒ袮ヘ?ェャハヲメェォェノェヲェォェレェケ - *------------------------------------------ - */ -#define swap(x,y) { int t; t = x; x = y; y = t; } -int path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1) -{ - int dx, dy; - int wx = 0, wy = 0; - int weight; - struct map_data *md; - - if (!map[m].gat) - return 0; - md = &map[m]; - - dx = (x1 - x0); - if (dx < 0) { - swap(x0, x1); - swap(y0, y1); - dx = -dx; - } - dy = (y1 - y0); - - if (spd) { - spd->rx = spd->ry = 0; - spd->len = 1; - spd->x[0] = x0; - spd->y[0] = y0; - } - - if (map_getcellp(md,x1,y1,CELL_CHKWALL)) - return 0; - - if (dx > abs(dy)) { - weight = dx; - if (spd) - spd->ry=1; - } else { - weight = abs(y1 - y0); - if (spd) - spd->rx=1; - } - - while (x0 != x1 || y0 != y1) { - if (map_getcellp(md,x0,y0,CELL_CHKWALL)) - return 0; - wx += dx; - wy += dy; - if (wx >= weight) { - wx -= weight; - x0 ++; - } - if (wy >= weight) { - wy -= weight; - y0 ++; - } else if (wy < 0) { - wy += weight; - y0 --; - } - if (spd && spd->len<MAX_WALKPATH) { - spd->x[spd->len] = x0; - spd->y[spd->len] = y0; - spd->len++; - } - } - - return 1; -} - -/*========================================== - * path探索 (x0,y0)->(x1,y1) - *------------------------------------------ - */ -int path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag) -{ - int heap[MAX_HEAP+1]; - struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH]; - int i,rp,x,y; - struct map_data *md; - int dx,dy; - - nullpo_retr(0, wpd); - - if(!map[m].gat) - return -1; - md=&map[m]; - if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || map_getcellp(md,x1,y1,CELL_CHKNOPASS)) - return -1; - - // easy - dx = (x1-x0<0) ? -1 : 1; - dy = (y1-y0<0) ? -1 : 1; - for(x=x0,y=y0,i=0;x!=x1 || y!=y1;){ - if(i>=sizeof(wpd->path)) - return -1; - if(x!=x1 && y!=y1){ - if(!can_move(md,x,y,x+dx,y+dy,flag)) - break; - x+=dx; - y+=dy; - wpd->path[i++]=(dx<0) ? ((dy>0)? 1 : 3) : ((dy<0)? 5 : 7); - } else if(x!=x1){ - if(!can_move(md,x,y,x+dx,y ,flag)) - break; - x+=dx; - wpd->path[i++]=(dx<0) ? 2 : 6; - } else { // y!=y1 - if(!can_move(md,x,y,x ,y+dy,flag)) - break; - y+=dy; - wpd->path[i++]=(dy>0) ? 0 : 4; - } - if(x==x1 && y==y1){ - wpd->path_len=i; - wpd->path_pos=0; - wpd->path_half=0; - return 0; - } - } - if(flag&1) - return -1; - - memset(tp,0,sizeof(tp)); - - i=calc_index(x0,y0); - tp[i].x=x0; - tp[i].y=y0; - tp[i].dist=0; - tp[i].dir=0; - tp[i].before=0; - tp[i].cost=calc_cost(&tp[i],x1,y1); - tp[i].flag=0; - heap[0]=0; - push_heap_path(heap,tp,calc_index(x0,y0)); - while(1){ - int e=0,fromdir; - - if(heap[0]==0) - return -1; - rp=pop_heap_path(heap,tp); - x=tp[rp].x; - y=tp[rp].y; - if(x==x1 && y==y1){ - int len,j; - - for(len=0,i=rp;len<100 && i!=calc_index(x0,y0);i=tp[i].before,len++); - if(len==100 || len>=sizeof(wpd->path)) - return -1; - wpd->path_len=len; - wpd->path_pos=0; - wpd->path_half=0; - for(i=rp,j=len-1;j>=0;i=tp[i].before,j--) - wpd->path[j]=tp[i].dir; - - return 0; - } - fromdir=tp[rp].dir; - if(can_move(md,x,y,x+1,y-1,flag)) - e+=add_path(heap,tp,x+1,y-1,tp[rp].dist+14,5,rp,x1,y1); - if(can_move(md,x,y,x+1,y ,flag)) - e+=add_path(heap,tp,x+1,y ,tp[rp].dist+10,6,rp,x1,y1); - if(can_move(md,x,y,x+1,y+1,flag)) - e+=add_path(heap,tp,x+1,y+1,tp[rp].dist+14,7,rp,x1,y1); - if(can_move(md,x,y,x ,y+1,flag)) - e+=add_path(heap,tp,x ,y+1,tp[rp].dist+10,0,rp,x1,y1); - if(can_move(md,x,y,x-1,y+1,flag)) - e+=add_path(heap,tp,x-1,y+1,tp[rp].dist+14,1,rp,x1,y1); - if(can_move(md,x,y,x-1,y ,flag)) - e+=add_path(heap,tp,x-1,y ,tp[rp].dist+10,2,rp,x1,y1); - if(can_move(md,x,y,x-1,y-1,flag)) - e+=add_path(heap,tp,x-1,y-1,tp[rp].dist+14,3,rp,x1,y1); - if(can_move(md,x,y,x ,y-1,flag)) - e+=add_path(heap,tp,x ,y-1,tp[rp].dist+10,4,rp,x1,y1); - tp[rp].flag=1; - if(e || heap[0]>=MAX_HEAP-5) - return -1; - } - return -1; -} - -#ifdef PATH_STANDALONETEST -char gat[64][64]={ - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,1,0,0,0,0,0}, -}; -struct map_data map[1]; - -/*========================================== - * 経路探索ルーチン単体テスト用main関数 - *------------------------------------------ - */ -void main(int argc,char *argv[]) -{ - struct walkpath_data wpd; - - map[0].gat=gat; - map[0].xs=64; - map[0].ys=64; - - path_search(&wpd,0,3,4,5,4); - path_search(&wpd,0,5,4,3,4); - path_search(&wpd,0,6,4,3,4); - path_search(&wpd,0,7,4,3,4); - path_search(&wpd,0,4,3,4,5); - path_search(&wpd,0,4,2,4,5); - path_search(&wpd,0,4,1,4,5); - path_search(&wpd,0,4,5,4,3); - path_search(&wpd,0,4,6,4,3); - path_search(&wpd,0,4,7,4,3); - path_search(&wpd,0,7,4,3,4); - path_search(&wpd,0,8,4,3,4); - path_search(&wpd,0,9,4,3,4); - path_search(&wpd,0,10,4,3,4); - path_search(&wpd,0,11,4,3,4); - path_search(&wpd,0,12,4,3,4); - path_search(&wpd,0,13,4,3,4); - path_search(&wpd,0,14,4,3,4); - path_search(&wpd,0,15,4,3,4); - path_search(&wpd,0,16,4,3,4); - path_search(&wpd,0,17,4,3,4); - path_search(&wpd,0,18,4,3,4); -} -#endif diff --git a/src/map/pc.c b/src/map/pc.c deleted file mode 100644 index e0c13012d..000000000 --- a/src/map/pc.c +++ /dev/null @@ -1,7337 +0,0 @@ -// $Id: pc.c 101 2004-12-13 7:23:07 PM Celestia $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <time.h> - -#include "socket.h" // [Valaris] -#include "timer.h" -#include "db.h" - -#include "malloc.h" -#include "map.h" -#include "chrif.h" -#include "clif.h" -#include "intif.h" -#include "pc.h" -#include "status.h" -#include "npc.h" -#include "mob.h" -#include "pet.h" -#include "itemdb.h" -#include "script.h" -#include "battle.h" -#include "skill.h" -#include "party.h" -#include "guild.h" -#include "chat.h" -#include "trade.h" -#include "storage.h" -#include "vending.h" -#include "nullpo.h" -#include "atcommand.h" -#include "log.h" -#include "showmsg.h" - -#ifndef TXT_ONLY // mail system [Valaris] -#include "mail.h" -#endif - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define PVP_CALCRANK_INTERVAL 1000 // PVP順位計算の間隔 - -static int exp_table[14][MAX_LEVEL]; -static short statp[MAX_LEVEL]; - -extern char msg_table[1000][256]; - -// h-files are for declarations, not for implementations... [Shinomori] -struct skill_tree_entry skill_tree[3][25][MAX_SKILL_TREE]; -// timer for night.day implementation -int day_timer_tid; -int night_timer_tid; - -static int dirx[8]={0,-1,-1,-1,0,1,1,1}; -static int diry[8]={1,1,0,-1,-1,-1,0,1}; - -static unsigned int equip_pos[11]={0x0080,0x0008,0x0040,0x0004,0x0001,0x0200,0x0100,0x0010,0x0020,0x0002,0x8000}; - -//static struct dbt *gm_account_db; -static struct gm_account *gm_account = NULL; -static int GM_num = 0; - -int pc_isGM(struct map_session_data *sd) { -// struct gm_account *p; - int i; - - nullpo_retr(0, sd); - - if(sd->bl.type!=BL_PC ) - return 0; - -/* p = numdb_search(gm_account_db, sd->status.account_id); - if (p == NULL) - return 0; - return p->level;*/ - - //For console [Wizputer] - if ( sd->fd == 0 ) - return 99; - - for(i = 0; i < GM_num; i++) - if (gm_account[i].account_id == sd->status.account_id) - return gm_account[i].level; - return 0; - -} - -int pc_iskiller(struct map_session_data *src, struct map_session_data *target) { - nullpo_retr(0, src); - - if(src->bl.type!=BL_PC ) - return 0; - if (src->special_state.killer) - return 1; - - if(target->bl.type!=BL_PC ) - return 0; - if (target->special_state.killable) - return 1; - - return 0; -} - - -int pc_set_gm_level(int account_id, int level) { - int i; - for (i = 0; i < GM_num; i++) { - if (account_id == gm_account[i].account_id) { - gm_account[i].level = level; - return 0; - } - } - - GM_num++; - gm_account = (struct gm_account *) aRealloc(gm_account, sizeof(struct gm_account) * GM_num); - gm_account[GM_num - 1].account_id = account_id; - gm_account[GM_num - 1].level = level; - return 0; -} - -static int distance(int x0, int y0, int x1, int y1) { - int dx, dy; - - dx = abs(x0-x1); - dy = abs(y0-y1); - return dx>dy ? dx : dy; -} - -static int pc_invincible_timer(int tid,unsigned int tick,int id,int data) { - struct map_session_data *sd; - - if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC ) - return 1; - - if(sd->invincible_timer != tid){ - if(battle_config.error_log) - printf("invincible_timer %d != %d\n",sd->invincible_timer,tid); - return 0; - } - sd->invincible_timer=-1; - skill_unit_move(&sd->bl,tick,1); - - return 0; -} - -int pc_setinvincibletimer(struct map_session_data *sd,int val) { - nullpo_retr(0, sd); - - if(sd->invincible_timer != -1) - delete_timer(sd->invincible_timer,pc_invincible_timer); - sd->invincible_timer = add_timer(gettick()+val,pc_invincible_timer,sd->bl.id,0); - return 0; -} - -int pc_delinvincibletimer(struct map_session_data *sd) { - nullpo_retr(0, sd); - - if(sd->invincible_timer != -1) { - delete_timer(sd->invincible_timer,pc_invincible_timer); - sd->invincible_timer = -1; - } - skill_unit_move(&sd->bl,gettick(),1); - return 0; -} - -static int pc_spiritball_timer(int tid,unsigned int tick,int id,int data) { - struct map_session_data *sd; - - if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC ) - return 1; - - if(sd->spirit_timer[0] != tid){ - if(battle_config.error_log) - printf("spirit_timer %d != %d\n",sd->spirit_timer[0],tid); - return 0; - } - - if(sd->spiritball <= 0) { - if(battle_config.error_log) - printf("Spiritballs are already 0 when pc_spiritball_timer gets called"); - sd->spiritball = 0; - return 0; - } - - sd->spiritball--; - // I leave this here as bad example [Shinomori] - //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * sd->spiritball ); - memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int) ); - sd->spirit_timer[sd->spiritball]=-1; - - clif_spiritball(sd); - - return 0; -} - -int pc_addspiritball(struct map_session_data *sd,int interval,int max) { - nullpo_retr(0, sd); - - if(max > MAX_SKILL_LEVEL) - max = MAX_SKILL_LEVEL; - if(sd->spiritball < 0) - sd->spiritball = 0; - - if(sd->spiritball >= max) { - if(sd->spirit_timer[0] != -1) - delete_timer(sd->spirit_timer[0],pc_spiritball_timer); - // I leave this here as bad example [Shinomori] - //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * (sd->spiritball - 1)); - memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball - 1)*sizeof(int) ); - //sd->spirit_timer[sd->spiritball-1] = -1; // intentionally, but will be overwritten - } else - sd->spiritball++; - - sd->spirit_timer[sd->spiritball-1] = add_timer(gettick()+interval,pc_spiritball_timer,sd->bl.id,0); - clif_spiritball(sd); - - return 0; -} - -int pc_delspiritball(struct map_session_data *sd,int count,int type) { - int i; - - nullpo_retr(0, sd); - - if(sd->spiritball <= 0) { - sd->spiritball = 0; - return 0; - } - - if(count > sd->spiritball) - count = sd->spiritball; - sd->spiritball -= count; - if(count > MAX_SKILL_LEVEL) - count = MAX_SKILL_LEVEL; - - for(i=0;i<count;i++) { - if(sd->spirit_timer[i] != -1) { - delete_timer(sd->spirit_timer[i],pc_spiritball_timer); - sd->spirit_timer[i] = -1; - } - } - for(i=count;i<MAX_SKILL_LEVEL;i++) { - sd->spirit_timer[i-count] = sd->spirit_timer[i]; - sd->spirit_timer[i] = -1; - } - - if(!type) - clif_spiritball(sd); - - return 0; -} - -int pc_setrestartvalue(struct map_session_data *sd,int type) { - //?生や養子の場合の元の職業を算出する - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - s_class = pc_calc_base_job(sd->status.class_); - - //----------------------- - // 死亡した - if(sd->special_state.restart_full_recover || // オシリスカ?ド - sd->state.snovice_flag == 4) { // [Celest] - sd->status.hp=sd->status.max_hp; - sd->status.sp=sd->status.max_sp; - if (sd->state.snovice_flag == 4) { - sd->state.snovice_flag = 0; - status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],1,0,0,0,skill_get_time(MO_STEELBODY,1),0 ); - } - } - else { - if(s_class.job == 0 && battle_config.restart_hp_rate < 50) { //ノビは半分回復 - sd->status.hp=(sd->status.max_hp)/2; - } - else { - if(battle_config.restart_hp_rate <= 0) - sd->status.hp = 1; - else { - sd->status.hp = sd->status.max_hp * battle_config.restart_hp_rate /100; - if(sd->status.hp <= 0) - sd->status.hp = 1; - } - } - if(battle_config.restart_sp_rate > 0) { - int sp = sd->status.max_sp * battle_config.restart_sp_rate /100; - if(sd->status.sp < sp) - sd->status.sp = sp; - } - } - if(type&1) - clif_updatestatus(sd,SP_HP); - if(type&1) - clif_updatestatus(sd,SP_SP); - - /* removed exp penalty on spawn [Valaris] */ - - if(type&2 && sd->status.class_ != 0 && battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) { - int zeny = (int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.); - if(zeny < 1) zeny = 1; - sd->status.zeny -= zeny; - if(sd->status.zeny < 0) sd->status.zeny = 0; - clif_updatestatus(sd,SP_ZENY); - } - - return 0; -} - -/*========================================== - * 自分をロックしているMOBの?を?える(foreachclient) - *------------------------------------------ - */ -static int pc_counttargeted_sub(struct block_list *bl,va_list ap) -{ - int id,*c,target_lv; - struct block_list *src; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - id=va_arg(ap,int); - - nullpo_retr(0, c=va_arg(ap,int *)); - - src=va_arg(ap,struct block_list *); - target_lv=va_arg(ap,int); - if(id == bl->id || (src && id == src->id)) return 0; - if(bl->type == BL_PC) { - struct map_session_data *sd=(struct map_session_data *)bl; - if( sd && sd->attacktarget == id && sd->attacktimer != -1 && sd->attacktarget_lv >= target_lv) - (*c)++; - } - else if(bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)bl; - if(md && md->target_id == id && md->timer != -1 && md->state.state == MS_ATTACK && md->target_lv >= target_lv) - - (*c)++; - //printf("md->target_lv:%d, target_lv:%d\n",((struct mob_data *)bl)->target_lv,target_lv); - } - return 0; -} - -int pc_counttargeted(struct map_session_data *sd,struct block_list *src,int target_lv) -{ - int c=0; - map_foreachinarea(pc_counttargeted_sub, sd->bl.m, - sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE, - sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,0,sd->bl.id,&c,src,target_lv); - return c; -} - -/*========================================== - * ロ?カルプロトタイプ宣言 (必要な物のみ) - *------------------------------------------ - */ -static int pc_walktoxy_sub(struct map_session_data *); - -/*========================================== - * saveに必要なステ?タス修正を行なう - *------------------------------------------ - */ -int pc_makesavestatus(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - // 秒フ色は色?弊害が多いので保存?象にはしない - if(!battle_config.save_clothcolor) - sd->status.clothes_color=0; - - // 死亡?態だったのでhpを1、位置をセ?ブ場所に?更 - if(!sd->state.waitingdisconnect) { - if(pc_isdead(sd)){ - pc_setrestartvalue(sd,0); - memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point)); - } else { - memcpy(sd->status.last_point.map,sd->mapname,24); - sd->status.last_point.x = sd->bl.x; - sd->status.last_point.y = sd->bl.y; - } - - // セ?ブ禁止マップだったので指定位置に移動 - if(map[sd->bl.m].flag.nosave){ - struct map_data *m=&map[sd->bl.m]; - if(strcmp(m->save.map,"SavePoint")==0) - memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point)); - else - memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point)); - } - } - - //マナ?ポイントがプラスだった場合0に - if(battle_config.muting_players && sd->status.manner > 0) - sd->status.manner = 0; - - return 0; -} - -/*========================================== - * 接?暫フ初期化 - *------------------------------------------ - */ -int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, int client_tick, int sex, int fd) { - nullpo_retr(0, sd); - - sd->bl.id = account_id; - sd->char_id = char_id; - sd->login_id1 = login_id1; - sd->login_id2 = 0; // at this point, we can not know the value :( - sd->client_tick = client_tick; - sd->sex = sex; - sd->state.auth = 0; - sd->bl.type = BL_PC; - sd->canact_tick = sd->canmove_tick = gettick(); - sd->canlog_tick = gettick(); - sd->state.waitingdisconnect = 0; - - return 0; -} - -int pc_equippoint(struct map_session_data *sd,int n) -{ - int ep = 0; - //?生や養子の場合の元の職業を算出する - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - s_class = pc_calc_base_job(sd->status.class_); - - if(sd->inventory_data[n]) { - ep = sd->inventory_data[n]->equip; - if(sd->inventory_data[n]->look == 1 || sd->inventory_data[n]->look == 2 || sd->inventory_data[n]->look == 6) { - if(ep == 2 && (pc_checkskill(sd,AS_LEFT) > 0 || s_class.job == 12)) - return 34; - } - } - return ep; -} - -int pc_setinventorydata(struct map_session_data *sd) -{ - int i,id; - - nullpo_retr(0, sd); - - for(i=0;i<MAX_INVENTORY;i++) { - id = sd->status.inventory[i].nameid; - sd->inventory_data[i] = itemdb_search(id); - } - return 0; -} - -int pc_calcweapontype(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - if(sd->weapontype1 != 0 && sd->weapontype2 == 0) - sd->status.weapon = sd->weapontype1; - if(sd->weapontype1 == 0 && sd->weapontype2 != 0)// 左手武器 Only - sd->status.weapon = sd->weapontype2; - else if(sd->weapontype1 == 1 && sd->weapontype2 == 1)// ?短? - sd->status.weapon = 0x11; - else if(sd->weapontype1 == 2 && sd->weapontype2 == 2)// ??手? - sd->status.weapon = 0x12; - else if(sd->weapontype1 == 6 && sd->weapontype2 == 6)// ??手斧 - sd->status.weapon = 0x13; - else if( (sd->weapontype1 == 1 && sd->weapontype2 == 2) || - (sd->weapontype1 == 2 && sd->weapontype2 == 1) ) // 短? - ?手? - sd->status.weapon = 0x14; - else if( (sd->weapontype1 == 1 && sd->weapontype2 == 6) || - (sd->weapontype1 == 6 && sd->weapontype2 == 1) ) // 短? - 斧 - sd->status.weapon = 0x15; - else if( (sd->weapontype1 == 2 && sd->weapontype2 == 6) || - (sd->weapontype1 == 6 && sd->weapontype2 == 2) ) // ?手? - 斧 - sd->status.weapon = 0x16; - else - sd->status.weapon = sd->weapontype1; - - return 0; -} - -int pc_setequipindex(struct map_session_data *sd) -{ - int i,j; - - nullpo_retr(0, sd); - - for(i=0;i<11;i++) - sd->equip_index[i] = -1; - - for(i=0;i<MAX_INVENTORY;i++) { - if(sd->status.inventory[i].nameid <= 0) - continue; - if(sd->status.inventory[i].equip) { - for(j=0;j<11;j++) - if(sd->status.inventory[i].equip & equip_pos[j]) - sd->equip_index[j] = i; - if(sd->status.inventory[i].equip & 0x0002) { - if(sd->inventory_data[i]) - sd->weapontype1 = sd->inventory_data[i]->look; - else - sd->weapontype1 = 0; - } - if(sd->status.inventory[i].equip & 0x0020) { - if(sd->inventory_data[i]) { - if(sd->inventory_data[i]->type == 4) { - if(sd->status.inventory[i].equip == 0x0020) - sd->weapontype2 = sd->inventory_data[i]->look; - else - sd->weapontype2 = 0; - } - else - sd->weapontype2 = 0; - } - else - sd->weapontype2 = 0; - } - } - } - pc_calcweapontype(sd); - - return 0; -} - -int pc_isequip(struct map_session_data *sd,int n) -{ - struct item_data *item; - struct status_change *sc_data; - //?生や養子の場合の元の職業を算出する - - nullpo_retr(0, sd); - - item = sd->inventory_data[n]; - sc_data = status_get_sc_data(&sd->bl); - //s_class = pc_calc_base_job(sd->status.class_); - - if( battle_config.gm_allequip>0 && pc_isGM(sd)>=battle_config.gm_allequip ) - return 1; - - if(item == NULL) - return 0; - if(item->sex != 2 && sd->status.sex != item->sex) - return 0; - if(item->elv > 0 && sd->status.base_level < item->elv) - return 0; -// -- moonsoul (below statement substituted for commented out version further below -// as it allows all advanced classes to equip items their normal versions -// could equip) -// - if(((sd->status.class_==13 || sd->status.class_==4014) && ((1<<7)&item->class_) == 0) || // have mounted classes use unmounted equipment [Valaris] - ((sd->status.class_==21 || sd->status.class_==4022) && ((1<<14)&item->class_) == 0)) - return 0; - if(sd->status.class_!=13 && sd->status.class_!=4014 && sd->status.class_!=21 && sd->status.class_!=4022) - if((sd->status.class_<=4000 && ((1<<sd->status.class_)&item->class_) == 0) || (sd->status.class_>4000 && sd->status.class_<4023 && ((1<<(sd->status.class_-4001))&item->class_) == 0) || - (sd->status.class_>=4023 && ((1<<(sd->status.class_-4023))&item->class_) == 0)) - return 0; -// if(((1<<sd->status.class_)&item->class_) == 0) -// return 0; - if(map[sd->bl.m].flag.pvp && (item->flag.no_equip&1)) //optimized by Lupus - return 0; - if(map[sd->bl.m].flag.gvg && (item->flag.no_equip>1)) //optimized by Lupus - return 0; - if(item->equip & 0x0002 && sc_data && sc_data[SC_STRIPWEAPON].timer != -1) - return 0; - if(item->equip & 0x0020 && sc_data && sc_data[SC_STRIPSHIELD].timer != -1) - return 0; - if(item->equip & 0x0010 && sc_data && sc_data[SC_STRIPARMOR].timer != -1) - return 0; - if(item->equip & 0x0100 && sc_data && sc_data[SC_STRIPHELM].timer != -1) - return 0; - return 1; -} - -//装備破壊 -int pc_break_equip(struct map_session_data *sd, unsigned short where) -{ - int i; - int sc; - - nullpo_retr(-1, sd); - if(sd->unbreakable_equip & where) - return 0; - if(sd->unbreakable >= rand()%100) - return 0; - switch (where) { - case EQP_WEAPON: - sc = SC_CP_WEAPON; - break; - case EQP_ARMOR: - sc = SC_CP_ARMOR; - break; - case EQP_SHIELD: - sc = SC_CP_SHIELD; - break; - case EQP_HELM: - sc = SC_CP_HELM; - break; - default: - return 0; - } - if(sd->sc_count && sd->sc_data[sc].timer != -1) - return 0; - - for (i=0;i<MAX_INVENTORY;i++) { - if (sd->status.inventory[i].equip & where && - sd->status.inventory[i].attribute != 1) { - sd->status.inventory[i].attribute = 1; - pc_unequipitem(sd,i,3); - sprintf(tmp_output, "%s has broken.",sd->inventory_data[i]->jname); - clif_emotion(&sd->bl,23); - clif_displaymessage(sd->fd, tmp_output); - clif_equiplist(sd); - break; - } - } - - return 1; -} - -/*========================================== - * session idに問題無し - * char鯖から送られてきたステ?タスを設定 - *------------------------------------------ - */ -int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_charstatus *st) -{ - struct map_session_data *sd = NULL; - - struct party *p; - struct guild *g; - int i; - unsigned long tick = gettick(); - - sd = map_id2sd(id); - nullpo_retr(1, sd); - - // check if double login occured - if(sd->new_fd){ - // 2重login状態だったので、両方落す - clif_authfail_fd(sd->fd,2); // same id - clif_authfail_fd(sd->new_fd,8); // same id - return 1; - } - sd->login_id2 = login_id2; - memcpy(&sd->status, st, sizeof(*st)); - - if (sd->status.sex != sd->sex) { - clif_authfail_fd(sd->fd, 0); - return 1; - } - - memset(&sd->state, 0, sizeof(sd->state)); - // 基本的な初期化 - sd->state.connect_new = 1; - sd->bl.prev = sd->bl.next = NULL; - - sd->weapontype1 = sd->weapontype2 = 0; - sd->view_class = sd->status.class_; - sd->speed = DEFAULT_WALK_SPEED; - sd->state.dead_sit = 0; - sd->dir = 0; - sd->head_dir = 0; - sd->state.auth = 1; - sd->walktimer = -1; - sd->next_walktime = -1; - sd->attacktimer = -1; - sd->followtimer = -1; // [MouseJstr] - sd->skilltimer = -1; - sd->skillitem = -1; - sd->skillitemlv = -1; - sd->invincible_timer = -1; - - sd->deal_locked = 0; - sd->trade_partner = 0; - - sd->inchealhptick = 0; - sd->inchealsptick = 0; - sd->hp_sub = 0; - sd->sp_sub = 0; - sd->inchealspirithptick = 0; - sd->inchealspiritsptick = 0; - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->canregen_tick = tick; - sd->attackabletime = tick; - sd->reg_num = 0; - sd->doridori_counter = 0; - sd->change_level = pc_readglobalreg(sd,"jobchange_level"); - -#ifndef TXT_ONLY // mail system [Valaris] - if(battle_config.mail_system) - sd->mail_counter = 0; -#endif - sd->spiritball = 0; - for(i = 0; i < MAX_SKILL_LEVEL; i++) - sd->spirit_timer[i] = -1; - for(i = 0; i < MAX_SKILLTIMERSKILL; i++) - sd->skilltimerskill[i].timer = -1; - sd->timerskill_count=0; - - memset(sd->blockskill,0,sizeof(sd->blockskill)); - - memset(&sd->dev,0,sizeof(struct square)); - for(i = 0; i < 5; i++) { - sd->dev.val1[i] = 0; - sd->dev.val2[i] = 0; - } - - // アカウント??の送信要求 - intif_request_accountreg(sd); - - // アイテムチェック - pc_setinventorydata(sd); - pc_checkitem(sd); - - // pet - sd->petDB = NULL; - sd->pd = NULL; - sd->pet_hungry_timer = -1; - memset(&sd->pet, 0, sizeof(struct s_pet)); - - // ステ?タス異常の初期化 - for(i = 0; i < MAX_STATUSCHANGE; i++) { - sd->sc_data[i].timer=-1; - sd->sc_data[i].val1 = sd->sc_data[i].val2 = sd->sc_data[i].val3 = sd->sc_data[i].val4 = 0; - } - sd->sc_count=0; - if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && - (pc_isGM(sd) >= get_atcommand_level(AtCommand_Hide))) - sd->status.option &= (OPTION_MASK | OPTION_HIDE); - else - sd->status.option &= OPTION_MASK; - - // スキルユニット?係の初期化 - memset(sd->skillunit, 0, sizeof(sd->skillunit)); - memset(sd->skillunittick, 0, sizeof(sd->skillunittick)); - - // パ?ティ??係の初期化 - sd->party_sended = 0; - sd->party_invite = 0; - sd->party_x = -1; - sd->party_y = -1; - sd->party_hp = -1; - - // ギルド?係の初期化 - sd->guild_sended = 0; - sd->guild_invite = 0; - sd->guild_alliance = 0; - - // イベント?係の初期化 - memset(sd->eventqueue, 0, sizeof(sd->eventqueue)); - for(i = 0; i < MAX_EVENTTIMER; i++) - sd->eventtimer[i] = -1; - sd->eventcount=0; - - // 位置の設定 - if (pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, 0) != 0) { - if(battle_config.error_log) { - char buf[32]; - sprintf(buf, "Last_point_map %s not found\n", sd->status.last_point.map); - ShowError (buf); - } - // try warping to a default map instead - if (pc_setpos(sd, "prontera.gat", 273, 354, 0) != 0) { - // if we fail again - clif_authfail_fd(sd->fd, 0); - return 1; - } - } - - // pet - if (sd->status.pet_id > 0) - intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id); - - // パ?ティ、ギルドデ?タの要求 - if (sd->status.party_id > 0 && (p = party_search(sd->status.party_id)) == NULL) - party_request_info(sd->status.party_id); - if (sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) == NULL) - guild_request_info(sd->status.guild_id); - - // pvpの設定 - sd->pvp_rank = 0; - sd->pvp_point = 0; - sd->pvp_timer = -1; - - // 通知 - - clif_authok(sd); - map_addnickdb(sd); - if (map_charid2nick(sd->status.char_id) == NULL) - map_addchariddb(sd->status.char_id, sd->status.name); - - //スパノビ用死にカウンタ?のスクリプト??からの?み出しとsdへのセット - sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER"); - - // Automated script events - if (script_config.event_requires_trigger) { - sd->state.event_death = pc_readglobalreg(sd, script_config.die_event_name); - sd->state.event_kill = pc_readglobalreg(sd, script_config.kill_event_name); - sd->state.event_disconnect = pc_readglobalreg(sd, script_config.logout_event_name); - // if script triggers are not required - } else { - sd->state.event_death = 1; - sd->state.event_kill = 1; - sd->state.event_disconnect = 1; - } - - if (night_flag == 1 && !map[sd->bl.m].flag.indoors) { - char tmpstr[1024]; - strcpy(tmpstr, msg_txt(500)); // Actually, it's the night... - clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1); - if (battle_config.night_darkness_level > 0) - clif_specialeffect(&sd->bl, 474 + battle_config.night_darkness_level, 0); - else - //clif_specialeffect(&sd->bl, 483, 0); // default darkness level - sd->opt2 |= STATE_BLIND; - } - - // ステ?タス初期計算など - status_calc_pc(sd,1); - - if (pc_isGM(sd)) - sprintf(tmp_output,"GM Character '"CL_WHITE"%s"CL_RESET"' logged in. (Acc. ID: '"CL_WHITE"%d"CL_RESET"', GM Level '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id, pc_isGM(sd)); - else - sprintf(tmp_output,"Character '"CL_WHITE"%s"CL_RESET"' logged in. (Account ID: '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id); - ShowInfo(tmp_output); - - if (script_config.event_script_type == 0) { - struct npc_data *npc; - //printf("pc: OnPCLogin event done. (%d events)\n", npc_event_doall("OnPCLogin") ); - if ((npc = npc_name2id(script_config.login_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLoginNPC - sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.login_event_name); - ShowStatus(tmp_output); - } - } else { - sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.login_event_name, sd->bl.id), script_config.login_event_name); - ShowStatus(tmp_output); - } - - // Send friends list - clif_friends_list_send(sd); - - // Message of the Dayの送信 - { - char buf[256]; - FILE *fp; - if ((fp = fopen(motd_txt, "r")) != NULL) { - while (fgets(buf, sizeof(buf)-1, fp) != NULL) { - int i; - for(i=0; buf[i]; i++) { - if (buf[i] == '\r' || buf[i]== '\n') { - buf[i] = 0; - break; - } - } - if (battle_config.motd_type) - clif_disp_onlyself(sd,buf,strlen(buf)); - else - clif_displaymessage(sd->fd, buf); - } - fclose(fp); - } - else if(battle_config.error_log) { - sprintf(tmp_output, "In function pc_atuhok() -> File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt); - ShowWarning(tmp_output); - } - } - -#ifndef TXT_ONLY - if(battle_config.mail_system) - mail_check(sd,1); // check mail at login [Valaris] -#endif - - // message of the limited time of the account - if (connect_until_time != 0) { // don't display if it's unlimited or unknow value - char tmpstr[1024]; - strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&connect_until_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S." - clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1); - } - - return 0; -} - -/*========================================== - * session idに問題ありなので後始末 - *------------------------------------------ - */ -int pc_authfail(int id) { - struct map_session_data *sd; - - sd = map_id2sd(id); - if (sd == NULL) - return 1; - - if(sd->new_fd){ - // 2重login状態だったので、新しい接続のみ落す - clif_authfail_fd(sd->new_fd,0); - sd->new_fd=0; - return 0; - } - - clif_authfail_fd(sd->fd, 0); - - return 0; -} - -static int pc_calc_skillpoint(struct map_session_data* sd) -{ - int i,skill,skill_point=0; - - nullpo_retr(0, sd); - - for(i=1;i<MAX_SKILL;i++){ - if( (skill = pc_checkskill(sd,i)) > 0) { - if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) { - if(!sd->status.skill[i].flag) - skill_point += skill; - else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) { - skill_point += (sd->status.skill[i].flag - 2); - } - } - } - } - - return skill_point; -} - -/*========================================== - * ?えられるスキルの計算 - *------------------------------------------ - */ -int pc_calc_skilltree(struct map_session_data *sd) -{ - int i,id=0,flag; - int c=0, s=0; - //?生や養子の場合の元の職業を算出する - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - s_class = pc_calc_base_job(sd->status.class_); - c = s_class.job; - //s = (s_class.upper==1) ? 1 : 0 ; //?生以外は通常のスキル? - s = s_class.upper; - - c = pc_calc_skilltree_normalize_job(c, sd); - - for(i=0;i<MAX_SKILL;i++){ -// if(skill_get_inf2(i) & 0x01) -// continue; - if (sd->status.skill[i].flag != 13) - sd->status.skill[i].id=0; - if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、 - sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本?のlvに - sd->status.skill[i].flag=0; // flagは0にしておく - } - } - - if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){ - // 全てのスキル - for(i=1;i<158;i++) - sd->status.skill[i].id=i; - for(i=210;i<291;i++) - sd->status.skill[i].id=i; - for(i=304;i<338;i++){ - if(i==331) continue; - sd->status.skill[i].id=i; - } - for(i=355;i<411;i++) - sd->status.skill[i].id=i; - for(i=475;i<480;i++) - sd->status.skill[i].id=i; - } else { - do { - flag=0; - for(i=0;(id=skill_tree[s][c][i].id)>0;i++){ - int j,f=1; - if(!battle_config.skillfree) { - for(j=0;j<5;j++) { - if( skill_tree[s][c][i].need[j].id && - pc_checkskill(sd,skill_tree[s][c][i].need[j].id) < - skill_tree[s][c][i].need[j].lv) { - f=0; - break; - } - } - if (sd->status.job_level < skill_tree[s][c][i].joblv) - f=0; - else if (id >= 2 && id <= 53 && pc_checkskill(sd, NV_BASIC) < 9) - f=0; - } - if(f && sd->status.skill[id].id==0 ){ - sd->status.skill[id].id=id; - flag=1; - } - } - } while(flag); - } -// if(battle_config.etc_log) -// printf("calc skill_tree\n"); - return 0; -} - -// Make sure all the skills are in the correct condition -// before persisting to the backend.. [MouseJstr] -int pc_clean_skilltree(struct map_session_data *sd) { - int i; - for (i = 0; i < MAX_SKILL; i++){ - if (sd->status.skill[i].flag == 13){ - sd->status.skill[i].id = 0; - sd->status.skill[i].lv = 0; - sd->status.skill[i].flag = 0; - } - } - - return 0; -} - -int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) { - //if((battle_config.skillup_limit) && ((c >= 0 && c < 23) || (c >= 4001 && c < 4023) || (c >= 4023 && c < 4045))) { - if (battle_config.skillup_limit && c >= 0 && c < 23) { - int skill_point = pc_calc_skillpoint(sd); - if(skill_point < 9) - c = 0; - //else if((sd->status.skill_point >= sd->status.job_level && skill_point < 58) && ((c > 6 && c < 23) || (c > 4007 && c < 4023) || (c > 4029 && c < 4045))) { - //else if ((sd->status.skill_point >= sd->status.job_level && skill_point < 58) && (c > 6 && c < 23)) { - else if (sd->status.skill_point >= sd->status.job_level && ((sd->change_level > 0 && skill_point < sd->change_level+8) || skill_point < 58) && (c > 6 && c < 23)) { - switch(c) { - case 7: - case 13: - case 14: - case 21: - c = 1; - break; - case 8: - case 15: - c = 4; - break; - case 9: - case 16: - c = 2; - break; - case 10: - case 18: - c = 5; - break; - case 11: - case 19: - case 20: - c = 3; - break; - case 12: - case 17: - c = 6; - break; -#if 0 - case 4008: - case 4014: - case 4015: - case 4022: - c = 4002; - break; - case 4009: - case 4016: - c = 4005; - break; - case 4010: - case 4017: - c = 4003; - break; - case 4011: - case 4019: - c = 4006; - break; - case 4012: - case 4020: - case 4021: - c = 4004; - break; - case 4013: - case 4018: - c = 4007; - break; - case 4030: - case 4036: - case 4037: - case 4044: - c = 4024; - break; - case 4031: - case 4038: - c = 4027; - break; - case 4032: - case 4039: - c = 4025; - break; - case 4033: - case 4040: - c = 4028; - break; - case 4034: - case 4041: - case 4042: - c = 4026; - break; - case 4035: - case 4043: - c = 4029; - break; -#endif - } - } - } - return c; -} - -/*========================================== - * 重量アイコンの確認 - *------------------------------------------ - */ -int pc_checkweighticon(struct map_session_data *sd) -{ - int flag=0; - - nullpo_retr(0, sd); - - if(sd->weight*2 >= sd->max_weight) - flag=1; - if(sd->weight*10 >= sd->max_weight*9) - flag=2; - - if(flag==1){ - if(sd->sc_data[SC_WEIGHT50].timer==-1) - status_change_start(&sd->bl,SC_WEIGHT50,0,0,0,0,0,0); - }else{ - status_change_end(&sd->bl,SC_WEIGHT50,-1); - } - if(flag==2){ - if(sd->sc_data[SC_WEIGHT90].timer==-1) - status_change_start(&sd->bl,SC_WEIGHT90,0,0,0,0,0,0); - }else{ - status_change_end(&sd->bl,SC_WEIGHT90,-1); - } - return 0; -} - -/*========================================== - * ? 備品による能力等のボ?ナス設定 - *------------------------------------------ - */ -int pc_bonus(struct map_session_data *sd,int type,int val) -{ - int i; - nullpo_retr(0, sd); - - switch(type){ - case SP_STR: - case SP_AGI: - case SP_VIT: - case SP_INT: - case SP_DEX: - case SP_LUK: - if(sd->state.lr_flag != 2) - sd->parame[type-SP_STR]+=val; - break; - case SP_ATK1: - if(!sd->state.lr_flag) - sd->watk+=val; - else if(sd->state.lr_flag == 1) - sd->watk_+=val; - break; - case SP_ATK2: - if(!sd->state.lr_flag) - sd->watk2+=val; - else if(sd->state.lr_flag == 1) - sd->watk_2+=val; - break; - case SP_BASE_ATK: - if(sd->state.lr_flag != 2) - sd->base_atk+=val; - break; - case SP_MATK1: - if(sd->state.lr_flag != 2) - sd->matk1 += val; - break; - case SP_MATK2: - if(sd->state.lr_flag != 2) - sd->matk2 += val; - break; - case SP_MATK: - if(sd->state.lr_flag != 2) { - sd->matk1 += val; - sd->matk2 += val; - } - break; - case SP_DEF1: - if(sd->state.lr_flag != 2) - sd->def+=val; - break; - case SP_MDEF1: - if(sd->state.lr_flag != 2) - sd->mdef+=val; - break; - case SP_MDEF2: - if(sd->state.lr_flag != 2) - sd->mdef+=val; - break; - case SP_HIT: - if(sd->state.lr_flag != 2) - sd->hit+=val; - else - sd->arrow_hit+=val; - break; - case SP_FLEE1: - if(sd->state.lr_flag != 2) - sd->flee+=val; - break; - case SP_FLEE2: - if(sd->state.lr_flag != 2) - sd->flee2+=val*10; - break; - case SP_CRITICAL: - if(sd->state.lr_flag != 2) - sd->critical+=val*10; - else - sd->arrow_cri += val*10; - break; - case SP_ATKELE: - if(!sd->state.lr_flag) - sd->atk_ele=val; - else if(sd->state.lr_flag == 1) - sd->atk_ele_=val; - else if(sd->state.lr_flag == 2) - sd->arrow_ele=val; - break; - case SP_DEFELE: - if(sd->state.lr_flag != 2) - sd->def_ele=val; - break; - case SP_MAXHP: - if(sd->state.lr_flag != 2) - sd->status.max_hp+=val; - break; - case SP_MAXSP: - if(sd->state.lr_flag != 2) - sd->status.max_sp+=val; - break; - case SP_CASTRATE: - if(sd->state.lr_flag != 2) - sd->castrate+=val; - break; - case SP_MAXHPRATE: - if(sd->state.lr_flag != 2) - sd->hprate+=val; - break; - case SP_MAXSPRATE: - if(sd->state.lr_flag != 2) - sd->sprate+=val; - break; - case SP_SPRATE: - if(sd->state.lr_flag != 2) - sd->dsprate+=val; - break; - case SP_ATTACKRANGE: - if(!sd->state.lr_flag) - sd->attackrange += val; - else if(sd->state.lr_flag == 1) - sd->attackrange_ += val; - else if(sd->state.lr_flag == 2) - sd->arrow_range += val; - break; - case SP_ADD_SPEED: - if(sd->state.lr_flag != 2) - sd->speed -= val; - break; - case SP_SPEED_RATE: - if(sd->state.lr_flag != 2) { - if(sd->speed_rate > 100-val) - sd->speed_rate = 100-val; - } - break; - case SP_SPEED_ADDRATE: - if(sd->state.lr_flag != 2) - sd->speed_add_rate = sd->speed_add_rate * (100-val)/100; - break; - case SP_ASPD: - if(sd->state.lr_flag != 2) - sd->aspd -= val*10; - break; - case SP_ASPD_RATE: - if(sd->state.lr_flag != 2) { - if(sd->aspd_rate > 100-val) - sd->aspd_rate = 100-val; - } - break; - case SP_ASPD_ADDRATE: - if(sd->state.lr_flag != 2) - sd->aspd_add_rate = sd->aspd_add_rate * (100-val)/100; - break; - case SP_HP_RECOV_RATE: - if(sd->state.lr_flag != 2) - sd->hprecov_rate += val; - break; - case SP_SP_RECOV_RATE: - if(sd->state.lr_flag != 2) - sd->sprecov_rate += val; - break; - case SP_CRITICAL_DEF: - if(sd->state.lr_flag != 2) - sd->critical_def += val; - break; - case SP_NEAR_ATK_DEF: - if(sd->state.lr_flag != 2) - sd->near_attack_def_rate += val; - break; - case SP_LONG_ATK_DEF: - if(sd->state.lr_flag != 2) - sd->long_attack_def_rate += val; - break; - case SP_DOUBLE_RATE: - if(sd->state.lr_flag == 0 && sd->double_rate < val) - sd->double_rate = val; - break; - case SP_DOUBLE_ADD_RATE: - if(sd->state.lr_flag == 0) - sd->double_add_rate += val; - break; - case SP_MATK_RATE: - if(sd->state.lr_flag != 2) - sd->matk_rate += val; - break; - case SP_IGNORE_DEF_ELE: - if(!sd->state.lr_flag) - sd->ignore_def_ele |= 1<<val; - else if(sd->state.lr_flag == 1) - sd->ignore_def_ele_ |= 1<<val; - break; - case SP_IGNORE_DEF_RACE: - if(!sd->state.lr_flag) - sd->ignore_def_race |= 1<<val; - else if(sd->state.lr_flag == 1) - sd->ignore_def_race_ |= 1<<val; - break; - case SP_ATK_RATE: - if(sd->state.lr_flag != 2) - sd->atk_rate += val; - break; - case SP_MAGIC_ATK_DEF: - if(sd->state.lr_flag != 2) - sd->magic_def_rate += val; - break; - case SP_MISC_ATK_DEF: - if(sd->state.lr_flag != 2) - sd->misc_def_rate += val; - break; - case SP_IGNORE_MDEF_ELE: - if(sd->state.lr_flag != 2) - sd->ignore_mdef_ele |= 1<<val; - break; - case SP_IGNORE_MDEF_RACE: - if(sd->state.lr_flag != 2) - sd->ignore_mdef_race |= 1<<val; - break; - case SP_PERFECT_HIT_RATE: - if(sd->state.lr_flag != 2 && sd->perfect_hit < val) - sd->perfect_hit = val; - break; - case SP_PERFECT_HIT_ADD_RATE: - if(sd->state.lr_flag != 2) - sd->perfect_hit_add += val; - break; - case SP_CRITICAL_RATE: - if(sd->state.lr_flag != 2) - sd->critical_rate+=val; - break; - case SP_GET_ZENY_NUM: - if(sd->state.lr_flag != 2 && sd->get_zeny_num < val) - sd->get_zeny_num = val; - break; - case SP_ADD_GET_ZENY_NUM: - if(sd->state.lr_flag != 2) - sd->get_zeny_add_num += val; - break; - case SP_DEF_RATIO_ATK_ELE: - if(!sd->state.lr_flag) - sd->def_ratio_atk_ele |= 1<<val; - else if(sd->state.lr_flag == 1) - sd->def_ratio_atk_ele_ |= 1<<val; - break; - case SP_DEF_RATIO_ATK_RACE: - if(!sd->state.lr_flag) - sd->def_ratio_atk_race |= 1<<val; - else if(sd->state.lr_flag == 1) - sd->def_ratio_atk_race_ |= 1<<val; - break; - case SP_HIT_RATE: - if(sd->state.lr_flag != 2) - sd->hit_rate += val; - break; - case SP_FLEE_RATE: - if(sd->state.lr_flag != 2) - sd->flee_rate += val; - break; - case SP_FLEE2_RATE: - if(sd->state.lr_flag != 2) - sd->flee2_rate += val; - break; - case SP_DEF_RATE: - if(sd->state.lr_flag != 2) - sd->def_rate += val; - break; - case SP_DEF2_RATE: - if(sd->state.lr_flag != 2) - sd->def2_rate += val; - break; - case SP_MDEF_RATE: - if(sd->state.lr_flag != 2) - sd->mdef_rate += val; - break; - case SP_MDEF2_RATE: - if(sd->state.lr_flag != 2) - sd->mdef2_rate += val; - break; - case SP_RESTART_FULL_RECORVER: - if(sd->state.lr_flag != 2) - sd->special_state.restart_full_recover = 1; - break; - case SP_NO_CASTCANCEL: - if(sd->state.lr_flag != 2) - sd->special_state.no_castcancel = 1; - break; - case SP_NO_CASTCANCEL2: - if(sd->state.lr_flag != 2) - sd->special_state.no_castcancel2 = 1; - break; - case SP_NO_SIZEFIX: - if(sd->state.lr_flag != 2) - sd->special_state.no_sizefix = 1; - break; - case SP_NO_MAGIC_DAMAGE: - if(sd->state.lr_flag != 2) - sd->special_state.no_magic_damage = 1; - break; - case SP_NO_WEAPON_DAMAGE: - if(sd->state.lr_flag != 2) - sd->special_state.no_weapon_damage = 1; - break; - case SP_NO_GEMSTONE: - if(sd->state.lr_flag != 2) - sd->special_state.no_gemstone = 1; - break; - case SP_INFINITE_ENDURE: - if(sd->state.lr_flag != 2) - sd->special_state.infinite_endure = 1; - break; - case SP_SPLASH_RANGE: - if(sd->state.lr_flag != 2 && sd->splash_range < val) - sd->splash_range = val; - break; - case SP_SPLASH_ADD_RANGE: - if(sd->state.lr_flag != 2) - sd->splash_add_range += val; - break; - case SP_SHORT_WEAPON_DAMAGE_RETURN: - if(sd->state.lr_flag != 2) - sd->short_weapon_damage_return += val; - break; - case SP_LONG_WEAPON_DAMAGE_RETURN: - if(sd->state.lr_flag != 2) - sd->long_weapon_damage_return += val; - break; - case SP_MAGIC_DAMAGE_RETURN: //AppleGirl Was Here - if(sd->state.lr_flag != 2) - sd->magic_damage_return += val; - break; - case SP_ALL_STATS: // [Valaris] - if(sd->state.lr_flag!=2) { - sd->parame[SP_STR-SP_STR]+=val; - sd->parame[SP_AGI-SP_STR]+=val; - sd->parame[SP_VIT-SP_STR]+=val; - sd->parame[SP_INT-SP_STR]+=val; - sd->parame[SP_DEX-SP_STR]+=val; - sd->parame[SP_LUK-SP_STR]+=val; - } - break; - case SP_AGI_VIT: // [Valaris] - if(sd->state.lr_flag!=2) { - sd->parame[SP_AGI-SP_STR]+=val; - sd->parame[SP_VIT-SP_STR]+=val; - } - break; - case SP_AGI_DEX_STR: // [Valaris] - if(sd->state.lr_flag!=2) { - sd->parame[SP_AGI-SP_STR]+=val; - sd->parame[SP_DEX-SP_STR]+=val; - sd->parame[SP_STR-SP_STR]+=val; - } - break; - case SP_PERFECT_HIDE: // [Valaris] - if(sd->state.lr_flag!=2) { - sd->perfect_hiding=1; - } - break; - case SP_DISGUISE: // Disguise script for items [Valaris] - if(sd->state.lr_flag!=2 && sd->disguiseflag==0) { - if(pc_isriding(sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(sd->fd, "Cannot wear disguise when riding a Peco."); - break; - } - sd->disguise=val; - clif_clearchar(&sd->bl, 9); - pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3); - } - break; - case SP_UNBREAKABLE: - if(sd->state.lr_flag!=2) { - sd->unbreakable += val; - } - break; - case SP_UNBREAKABLE_WEAPON: - if(sd->state.lr_flag != 2) - sd->unbreakable_equip |= EQP_WEAPON; - break; - case SP_UNBREAKABLE_ARMOR: - if(sd->state.lr_flag != 2) - sd->unbreakable_equip |= EQP_ARMOR; - break; - case SP_UNBREAKABLE_HELM: - if(sd->state.lr_flag != 2) - sd->unbreakable_equip |= EQP_HELM; - break; - case SP_UNBREAKABLE_SHIELD: - if(sd->state.lr_flag != 2) - sd->unbreakable_equip |= EQP_SHIELD; - break; - case SP_CLASSCHANGE: // [Valaris] - if(sd->state.lr_flag !=2){ - sd->classchange=val; - } - break; - case SP_LONG_ATK_RATE: - if(sd->status.weapon == 11 && sd->state.lr_flag != 2) - sd->atk_rate += val; - break; - case SP_BREAK_WEAPON_RATE: - if(sd->state.lr_flag != 2) - sd->break_weapon_rate+=val; - break; - case SP_BREAK_ARMOR_RATE: - if(sd->state.lr_flag != 2) - sd->break_armor_rate+=val; - break; - case SP_ADD_STEAL_RATE: - if(sd->state.lr_flag != 2) - sd->add_steal_rate+=val; - break; - case SP_DELAYRATE: - if(sd->state.lr_flag != 2) - sd->delayrate+=val; - break; - case SP_CRIT_ATK_RATE: - if(sd->state.lr_flag != 2) - sd->crit_atk_rate += val; - break; - case SP_NO_REGEN: - if(sd->state.lr_flag != 2) - sd->no_regen = val; - break; - case SP_UNSTRIPABLE_WEAPON: - if(sd->state.lr_flag != 2) - sd->unstripable_equip |= EQP_WEAPON; - break; - case SP_UNSTRIPABLE: - case SP_UNSTRIPABLE_ARMOR: - if(sd->state.lr_flag != 2) - sd->unstripable_equip |= EQP_ARMOR; - break; - case SP_UNSTRIPABLE_HELM: - if(sd->state.lr_flag != 2) - sd->unstripable_equip |= EQP_HELM; - break; - case SP_UNSTRIPABLE_SHIELD: - if(sd->state.lr_flag != 2) - sd->unstripable_equip |= EQP_SHIELD; - break; - case SP_SP_GAIN_VALUE: - if(!sd->state.lr_flag) - sd->sp_gain_value += val; - break; - case SP_IGNORE_DEF_MOB: // 0:normal monsters only, 1:affects boss monsters as well - if(!sd->state.lr_flag) - sd->ignore_def_mob |= 1<<val; - else if(sd->state.lr_flag == 1) - sd->ignore_def_mob_ |= 1<<val; - break; - case SP_HP_GAIN_VALUE: - if(!sd->state.lr_flag) - sd->hp_gain_value += val; - break; - case SP_DAMAGE_WHEN_UNEQUIP: - if(!sd->state.lr_flag) { - for (i=0; i<11; i++) { - if (sd->inventory_data[current_equip_item_index]->equip & equip_pos[i]) { - sd->unequip_losehp[i] += val; - break; - } - } - } - break; - case SP_LOSESP_WHEN_UNEQUIP: - if(!sd->state.lr_flag) { - for (i=0; i<11; i++) { - if (sd->inventory_data[current_equip_item_index]->equip & equip_pos[i]) { - sd->unequip_losesp[i] += val; - break; - } - } - } - break; - default: - if(battle_config.error_log) - printf("pc_bonus: unknown type %d %d !\n",type,val); - break; - } - return 0; -} - -/*========================================== - * ? 備品による能力等のボ?ナス設定 - *------------------------------------------ - */ -int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) -{ - int i; - - nullpo_retr(0, sd); - - switch(type){ - case SP_ADDELE: - if(!sd->state.lr_flag) - sd->addele[type2]+=val; - else if(sd->state.lr_flag == 1) - sd->addele_[type2]+=val; - else if(sd->state.lr_flag == 2) - sd->arrow_addele[type2]+=val; - break; - case SP_ADDRACE: - if(!sd->state.lr_flag) - sd->addrace[type2]+=val; - else if(sd->state.lr_flag == 1) - sd->addrace_[type2]+=val; - else if(sd->state.lr_flag == 2) - sd->arrow_addrace[type2]+=val; - break; - case SP_ADDSIZE: - if(!sd->state.lr_flag) - sd->addsize[type2]+=val; - else if(sd->state.lr_flag == 1) - sd->addsize_[type2]+=val; - else if(sd->state.lr_flag == 2) - sd->arrow_addsize[type2]+=val; - break; - case SP_SUBELE: - if(sd->state.lr_flag != 2) - sd->subele[type2]+=val; - break; - case SP_SUBRACE: - if(sd->state.lr_flag != 2) - sd->subrace[type2]+=val; - break; - case SP_ADDEFF: - if(sd->state.lr_flag != 2) - sd->addeff[type2]+=val; - else - sd->arrow_addeff[type2]+=val; - break; - case SP_ADDEFF2: - if(sd->state.lr_flag != 2) - sd->addeff2[type2]+=val; - else - sd->arrow_addeff2[type2]+=val; - break; - case SP_RESEFF: - if(sd->state.lr_flag != 2) - sd->reseff[type2]+=val; - break; - case SP_MAGIC_ADDELE: - if(sd->state.lr_flag != 2) - sd->magic_addele[type2]+=val; - break; - case SP_MAGIC_ADDRACE: - if(sd->state.lr_flag != 2) - sd->magic_addrace[type2]+=val; - break; - case SP_MAGIC_SUBRACE: - if(sd->state.lr_flag != 2) - sd->magic_subrace[type2]+=val; - break; - case SP_ADD_DAMAGE_CLASS: - if(!sd->state.lr_flag) { - for(i=0;i<sd->add_damage_class_count;i++) { - if(sd->add_damage_classid[i] == type2) { - sd->add_damage_classrate[i] += val; - break; - } - } - if(i >= sd->add_damage_class_count && sd->add_damage_class_count < 10) { - sd->add_damage_classid[sd->add_damage_class_count] = type2; - sd->add_damage_classrate[sd->add_damage_class_count] += val; - sd->add_damage_class_count++; - } - } - else if(sd->state.lr_flag == 1) { - for(i=0;i<sd->add_damage_class_count_;i++) { - if(sd->add_damage_classid_[i] == type2) { - sd->add_damage_classrate_[i] += val; - break; - } - } - if(i >= sd->add_damage_class_count_ && sd->add_damage_class_count_ < 10) { - sd->add_damage_classid_[sd->add_damage_class_count_] = type2; - sd->add_damage_classrate_[sd->add_damage_class_count_] += val; - sd->add_damage_class_count_++; - } - } - break; - case SP_ADD_MAGIC_DAMAGE_CLASS: - if(sd->state.lr_flag != 2) { - for(i=0;i<sd->add_magic_damage_class_count;i++) { - if(sd->add_magic_damage_classid[i] == type2) { - sd->add_magic_damage_classrate[i] += val; - break; - } - } - if(i >= sd->add_magic_damage_class_count && sd->add_magic_damage_class_count < 10) { - sd->add_magic_damage_classid[sd->add_magic_damage_class_count] = type2; - sd->add_magic_damage_classrate[sd->add_magic_damage_class_count] += val; - sd->add_magic_damage_class_count++; - } - } - break; - case SP_ADD_DEF_CLASS: - if(sd->state.lr_flag != 2) { - for(i=0;i<sd->add_def_class_count;i++) { - if(sd->add_def_classid[i] == type2) { - sd->add_def_classrate[i] += val; - break; - } - } - if(i >= sd->add_def_class_count && sd->add_def_class_count < 10) { - sd->add_def_classid[sd->add_def_class_count] = type2; - sd->add_def_classrate[sd->add_def_class_count] += val; - sd->add_def_class_count++; - } - } - break; - case SP_ADD_MDEF_CLASS: - if(sd->state.lr_flag != 2) { - for(i=0;i<sd->add_mdef_class_count;i++) { - if(sd->add_mdef_classid[i] == type2) { - sd->add_mdef_classrate[i] += val; - break; - } - } - if(i >= sd->add_mdef_class_count && sd->add_mdef_class_count < 10) { - sd->add_mdef_classid[sd->add_mdef_class_count] = type2; - sd->add_mdef_classrate[sd->add_mdef_class_count] += val; - sd->add_mdef_class_count++; - } - } - break; - case SP_HP_DRAIN_RATE: - if(!sd->state.lr_flag) { - sd->hp_drain_rate += type2; - sd->hp_drain_per += val; - } - else if(sd->state.lr_flag == 1) { - sd->hp_drain_rate_ += type2; - sd->hp_drain_per_ += val; - } - break; - case SP_HP_DRAIN_VALUE: - if(!sd->state.lr_flag) { - sd->hp_drain_rate += type2; - sd->hp_drain_value += val; - } - else if(sd->state.lr_flag == 1) { - sd->hp_drain_rate_ += type2; - sd->hp_drain_value_ += val; - } - break; - case SP_SP_DRAIN_RATE: - if(!sd->state.lr_flag) { - sd->sp_drain_rate += type2; - sd->sp_drain_per += val; - } - else if(sd->state.lr_flag == 1) { - sd->sp_drain_rate_ += type2; - sd->sp_drain_per_ += val; - } - sd->sp_drain_type = 0; - break; - case SP_SP_DRAIN_VALUE: - if(!sd->state.lr_flag) { - sd->sp_drain_rate += type2; - sd->sp_drain_value += val; - } - else if(sd->state.lr_flag == 1) { - sd->sp_drain_rate_ += type2; - sd->sp_drain_value_ += val; - } - sd->sp_drain_type = 0; - break; - case SP_WEAPON_COMA_ELE: - if(sd->state.lr_flag != 2) - sd->weapon_coma_ele[type2] += val; - break; - case SP_WEAPON_COMA_RACE: - if(sd->state.lr_flag != 2) - sd->weapon_coma_race[type2] += val; - break; - case SP_RANDOM_ATTACK_INCREASE: // [Valaris] - if(sd->state.lr_flag !=2){ - sd->random_attack_increase_add = type2; - sd->random_attack_increase_per += val; - } - break; - case SP_WEAPON_ATK: - if(sd->state.lr_flag != 2) - sd->weapon_atk[type2]+=val; - break; - case SP_WEAPON_ATK_RATE: - if(sd->state.lr_flag != 2) - sd->weapon_atk_rate[type2]+=val; - break; - case SP_CRITICAL_ADDRACE: - if(sd->state.lr_flag != 2) - sd->critaddrace[type2]+=val; - break; - case SP_ADDEFF_WHENHIT: - if(sd->state.lr_flag != 2) { - sd->addeff3[type2]+=val; - sd->addeff3_type[type2]=1; - } - break; - case SP_ADDEFF_WHENHIT_SHORT: - if(sd->state.lr_flag != 2) { - sd->addeff3[type2]+=val; - sd->addeff3_type[type2]=0; - } - break; - case SP_SKILL_ATK: - if(sd->state.lr_flag != 2) { - if (sd->skillatk[0] == type2) - sd->skillatk[1] += val; - else { - sd->skillatk[0] = type2; - sd->skillatk[1] = val; - } - } - break; - case SP_ADD_DAMAGE_BY_CLASS: - if(sd->state.lr_flag != 2) { - for(i=0;i<sd->add_damage_class_count2;i++) { - if(sd->add_damage_classid2[i] == type2) { - sd->add_damage_classrate2[i] += val; - break; - } - } - if(i >= sd->add_damage_class_count2 && sd->add_damage_class_count2 < 10) { - sd->add_damage_classid2[sd->add_damage_class_count2] = type2; - sd->add_damage_classrate2[sd->add_damage_class_count2] += val; - sd->add_damage_class_count2++; - } - } - break; - case SP_HP_LOSS_RATE: - if(sd->state.lr_flag != 2) { - sd->hp_loss_value = type2; - sd->hp_loss_rate = val; - } - break; - case SP_ADDRACE2: - if (type2 > 0 && type2 < MAX_MOB_RACE_DB) - break; - if(sd->state.lr_flag != 2) - sd->addrace2[type2] += val; - else - sd->addrace2_[type2] += val; - break; - case SP_SUBSIZE: - if(sd->state.lr_flag != 2) - sd->subsize[type2]+=val; - break; - case SP_SUBRACE2: - if(sd->state.lr_flag != 2) - sd->subrace2[type2]+=val; - break; - case SP_ADD_ITEM_HEAL_RATE: - if(sd->state.lr_flag != 2) - sd->itemhealrate[type2 - 1] += val; - break; - case SP_EXP_ADDRACE: - if(sd->state.lr_flag != 2) - sd->expaddrace[type2]+=val; - break; - case SP_SP_GAIN_RACE: - if(sd->state.lr_flag != 2) - sd->sp_gain_race[type2]+=val; - break; - - default: - if(battle_config.error_log) - printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); - break; - } - return 0; -} - -int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) -{ - int i; - switch(type){ - case SP_ADD_MONSTER_DROP_ITEM: - if(sd->state.lr_flag != 2) { - for(i=0;i<sd->monster_drop_item_count;i++) { - if(sd->monster_drop_itemid[i] == type2) { - sd->monster_drop_race[i] |= 1<<type3; - if(sd->monster_drop_itemrate[i] < val) - sd->monster_drop_itemrate[i] = val; - break; - } - } - if(i >= sd->monster_drop_item_count && sd->monster_drop_item_count < 10) { - sd->monster_drop_itemid[sd->monster_drop_item_count] = type2; - sd->monster_drop_race[sd->monster_drop_item_count] |= 1<<type3; - sd->monster_drop_itemrate[sd->monster_drop_item_count] = val; - sd->monster_drop_item_count++; - } - } - break; - case SP_AUTOSPELL: - if(sd->state.lr_flag != 2){ - sd->autospell_id = type2; - sd->autospell_lv = type3; - sd->autospell_rate = val; - } - break; - case SP_AUTOSPELL_WHENHIT: - if(sd->state.lr_flag != 2){ - sd->autospell2_id = type2; - sd->autospell2_lv = type3; - sd->autospell2_rate = val; - sd->autospell2_type = 1; // enemy - } - break; - case SP_HP_LOSS_RATE: - if(sd->state.lr_flag != 2) { - sd->hp_loss_value = type2; - sd->hp_loss_rate = type3; - sd->hp_loss_type = val; - } - break; - case SP_SP_DRAIN_RATE: - if(!sd->state.lr_flag) { - sd->sp_drain_rate += type2; - sd->sp_drain_per += type3; - } - else if(sd->state.lr_flag == 1) { - sd->sp_drain_rate_ += type2; - sd->sp_drain_per_ += type3; - } - sd->sp_drain_type = val; - break; - case SP_SP_DRAIN_VALUE: - if(!sd->state.lr_flag) { - sd->sp_drain_rate += type2; - sd->sp_drain_value += type3; - } - else if(sd->state.lr_flag == 1) { - sd->sp_drain_rate_ += type2; - sd->sp_drain_value_ += type3; - } - sd->sp_drain_type = val; - default: - if(battle_config.error_log) - printf("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val); - break; - } - - return 0; -} - -int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val) -{ - switch(type){ - case SP_AUTOSPELL_WHENHIT: - if(sd->state.lr_flag != 2){ - sd->autospell2_id = type2; - sd->autospell2_lv = type3; - sd->autospell2_rate = type4; - sd->autospell2_type = val; // 0: self, 1: enemy - } - break; - default: - if(battle_config.error_log) - printf("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val); - break; - } - - return 0; -} - -/*========================================== - * スクリプトによるスキル所得 - *------------------------------------------ - */ -int pc_skill(struct map_session_data *sd,int id,int level,int flag) -{ - nullpo_retr(0, sd); - - if(level>MAX_SKILL_LEVEL){ - if(battle_config.error_log) - printf("support card skill only!\n"); - return 0; - } - if(!flag && (sd->status.skill[id].id == id || level == 0)){ // クエスト所得ならここで?件を確認して送信する - sd->status.skill[id].lv=level; - status_calc_pc(sd,0); - clif_skillinfoblock(sd); - } - else if(flag==2 && (sd->status.skill[id].id == id || level == 0)){ // クエスト所得ならここで?件を確認して送信する - sd->status.skill[id].lv+=level; - status_calc_pc(sd,0); - clif_skillinfoblock(sd); - } - else if(sd->status.skill[id].lv < level){ // ?えられるがlvが小さいなら - if(sd->status.skill[id].id==id) - sd->status.skill[id].flag=sd->status.skill[id].lv+2; // lvを記憶 - else { - sd->status.skill[id].id=id; - sd->status.skill[id].flag=1; // cardスキルとする - } - sd->status.skill[id].lv=level; - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int pc_blockskill_end(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd = map_id2sd(id); - if (data <= 0 || data >= MAX_SKILL) - return 0; - if (sd) sd->blockskill[data] = 0; - - return 1; -} -int pc_blockskill_start (struct map_session_data *sd, int skillid, int tick) -{ - nullpo_retr (-1, sd); - - if (skillid >= 10000 && skillid < 10015) - skillid -= 9500; - else if (skillid < 1 || skillid > MAX_SKILL) - return -1; - - sd->blockskill[skillid] = 1; - return add_timer(gettick()+tick,pc_blockskill_end,sd->bl.id,skillid); -} - -/*========================================== - * カ?ド?入 - *------------------------------------------ - */ -int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip) -{ - nullpo_retr(0, sd); - - if(idx_card >= 0 && idx_card < MAX_INVENTORY && idx_equip >= 0 && idx_equip < MAX_INVENTORY && sd->inventory_data[idx_card]) { - int i; - int nameid=sd->status.inventory[idx_equip].nameid; - int cardid=sd->status.inventory[idx_card].nameid; - int ep=sd->inventory_data[idx_card]->equip; - - if( nameid <= 0 || sd->inventory_data[idx_equip] == NULL || - (sd->inventory_data[idx_equip]->type!=4 && sd->inventory_data[idx_equip]->type!=5)|| // ? 備じゃない - ( sd->status.inventory[idx_equip].identify==0 ) || // 未鑑定 - ( sd->status.inventory[idx_equip].card[0]==0x00ff) || // 製造武器 - ( sd->status.inventory[idx_equip].card[0]==0x00fe) || - ( (sd->inventory_data[idx_equip]->equip&ep)==0 ) || // ? 備個所違い - ( sd->inventory_data[idx_equip]->type==4 && ep==32) || // ? 手武器と盾カ?ド - ( sd->status.inventory[idx_equip].card[0]==(short)0xff00) || sd->status.inventory[idx_equip].equip){ - - clif_insert_card(sd,idx_equip,idx_card,1); - return 0; - } - for(i=0;i<sd->inventory_data[idx_equip]->slot;i++){ - if( sd->status.inventory[idx_equip].card[i] == 0){ - // 空きスロットがあったので差し?む - sd->status.inventory[idx_equip].card[i]=cardid; - - // カ?ドは減らす - clif_insert_card(sd,idx_equip,idx_card,0); - pc_delitem(sd,idx_card,1,1); - return 0; - } - } - } - else - clif_insert_card(sd,idx_equip,idx_card,1); - - return 0; -} - -// -// アイテム物 -// - -/*========================================== - * スキルによる買い値修正 - *------------------------------------------ - */ -int pc_modifybuyvalue(struct map_session_data *sd,int orig_value) -{ - int skill,val = orig_value,rate1 = 0,rate2 = 0; - if((skill=pc_checkskill(sd,MC_DISCOUNT))>0) // ディスカウント - rate1 = 5+skill*2-((skill==10)? 1:0); - if((skill=pc_checkskill(sd,RG_COMPULSION))>0) // コムパルションディスカウント - rate2 = 5+skill*4; - if(rate1 < rate2) rate1 = rate2; - if(rate1) - val = (int)((double)orig_value*(double)(100-rate1)/100.); - if(val < 0) val = 0; - if(orig_value > 0 && val < 1) val = 1; - - return val; -} - -/*========================================== - * スキルによる?り値修正 - *------------------------------------------ - */ -int pc_modifysellvalue(struct map_session_data *sd,int orig_value) -{ - int skill,val = orig_value,rate = 0; - if((skill=pc_checkskill(sd,MC_OVERCHARGE))>0) // オ?バ?チャ?ジ - rate = 5+skill*2-((skill==10)? 1:0); - if(rate) - val = (int)((double)orig_value*(double)(100+rate)/100.); - if(val < 0) val = 0; - if(orig_value > 0 && val < 1) val = 1; - - return val; -} - -/*========================================== - * アイテムを買った暫ノ、新しいアイテム欄を使うか、 - * 3万個制限にかかるか確認 - *------------------------------------------ - */ -int pc_checkadditem(struct map_session_data *sd,int nameid,int amount) -{ - int i; - - nullpo_retr(0, sd); - - if(itemdb_isequip(nameid)) - return ADDITEM_NEW; - - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid==nameid){ - if(sd->status.inventory[i].amount+amount > MAX_AMOUNT) - return ADDITEM_OVERAMOUNT; - return ADDITEM_EXIST; - } - } - - if(amount > MAX_AMOUNT) - return ADDITEM_OVERAMOUNT; - return ADDITEM_NEW; -} - -/*========================================== - * 空きアイテム欄の個? - *------------------------------------------ - */ -int pc_inventoryblank(struct map_session_data *sd) -{ - int i,b; - - nullpo_retr(0, sd); - - for(i=0,b=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid==0) - b++; - } - - return b; -} - -/*========================================== - * お金を?う - *------------------------------------------ - */ -int pc_payzeny(struct map_session_data *sd,int zeny) -{ - double z; - - nullpo_retr(0, sd); - - z = (double)sd->status.zeny; - if(sd->status.zeny<zeny || z - (double)zeny > MAX_ZENY) - return 1; - sd->status.zeny-=zeny; - clif_updatestatus(sd,SP_ZENY); - - return 0; -} - -/*========================================== - * お金を得る - *------------------------------------------ - */ -int pc_getzeny(struct map_session_data *sd,int zeny) -{ - double z; - - nullpo_retr(0, sd); - - z = (double)sd->status.zeny; - if(z + (double)zeny > MAX_ZENY) { - zeny = 0; - sd->status.zeny = MAX_ZENY; - } - sd->status.zeny+=zeny; - clif_updatestatus(sd,SP_ZENY); - - return 0; -} - -/*========================================== - * アイテムを探して、インデックスを返す - *------------------------------------------ - */ -int pc_search_inventory(struct map_session_data *sd,int item_id) -{ - int i; - - nullpo_retr(-1, sd); - - for(i=0;i<MAX_INVENTORY;i++) { - if(sd->status.inventory[i].nameid == item_id && - (sd->status.inventory[i].amount > 0 || item_id == 0)) - return i; - } - - return -1; -} - -/*========================================== - * アイテム追加。個?のみitem構造?の?字を無視 - *------------------------------------------ - */ -int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) -{ - struct item_data *data; - int i,w; - - nullpo_retr(1, sd); - nullpo_retr(1, item_data); - - if(item_data->nameid <= 0 || amount <= 0) - return 1; - data = itemdb_search(item_data->nameid); - if((w = data->weight*amount) + sd->weight > sd->max_weight) - return 2; - - i = MAX_INVENTORY; - - if(!itemdb_isequip2(data)){ - // 装 備品ではないので、既所有品なら個数のみ変化させる - for(i=0;i<MAX_INVENTORY;i++) - if(sd->status.inventory[i].nameid == item_data->nameid && - sd->status.inventory[i].card[0] == item_data->card[0] && sd->status.inventory[i].card[1] == item_data->card[1] && - sd->status.inventory[i].card[2] == item_data->card[2] && sd->status.inventory[i].card[3] == item_data->card[3]) { - if(sd->status.inventory[i].amount+amount > MAX_AMOUNT) - return 5; - sd->status.inventory[i].amount+=amount; - clif_additem(sd,i,amount,0); - break; - } - } - if(i >= MAX_INVENTORY){ - // 装 備品か未所有品だったので空き欄へ追加 - i = pc_search_inventory(sd,0); - if(i >= 0) { - memcpy(&sd->status.inventory[i],item_data,sizeof(sd->status.inventory[0])); - sd->status.inventory[i].amount=amount; - sd->inventory_data[i]=data; - clif_additem(sd,i,amount,0); - } - else return 4; - } - sd->weight += w; - clif_updatestatus(sd,SP_WEIGHT); - - return 0; -} - -/*========================================== - * アイテムを減らす - *------------------------------------------ - */ -int pc_delitem(struct map_session_data *sd,int n,int amount,int type) -{ - nullpo_retr(1, sd); - - if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL) - return 1; - - sd->status.inventory[n].amount -= amount; - sd->weight -= sd->inventory_data[n]->weight*amount ; - if(sd->status.inventory[n].amount<=0){ - if(sd->status.inventory[n].equip) - pc_unequipitem(sd,n,3); - memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0])); - sd->inventory_data[n] = NULL; - } - if(!(type&1)) - clif_delitem(sd,n,amount); - if(!(type&2)) - clif_updatestatus(sd,SP_WEIGHT); - - return 0; -} - -/*========================================== - * アイテムを落す - *------------------------------------------ - */ -int pc_dropitem(struct map_session_data *sd,int n,int amount) -{ - nullpo_retr(1, sd); - - if(n < 0 || n >= MAX_INVENTORY) - return 1; - - if(amount <= 0) - return 1; - - if (sd->status.inventory[n].nameid <= 0 || - sd->status.inventory[n].amount < amount || - sd->trade_partner != 0 || sd->vender_id != 0 || - sd->status.inventory[n].amount <= 0 || - itemdb_isdropable(sd->status.inventory[n].nameid) == 0 || // Celest - pc_candrop(sd,sd->status.inventory[n].nameid)) - return 1; - map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, NULL, NULL, NULL, 0); - pc_delitem(sd, n, amount, 0); - - return 0; -} - -/*========================================== - * アイテムを拾う - *------------------------------------------ - */ -int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem) -{ - int flag; - unsigned int tick = gettick(); - struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL; - - nullpo_retr(0, sd); - nullpo_retr(0, fitem); - - if(fitem->first_get_id > 0) { - first_sd = map_id2sd(fitem->first_get_id); - if(tick < fitem->first_get_tick) { - if(fitem->first_get_id != sd->bl.id && !(first_sd && first_sd->status.party_id == sd->status.party_id)) { - clif_additem(sd,0,0,6); - return 0; - } - } - else if(fitem->second_get_id > 0) { - second_sd = map_id2sd(fitem->second_get_id); - if(tick < fitem->second_get_tick) { - if(fitem->first_get_id != sd->bl.id && fitem->second_get_id != sd->bl.id && - !(first_sd && first_sd->status.party_id == sd->status.party_id) && !(second_sd && second_sd->status.party_id == sd->status.party_id)) { - clif_additem(sd,0,0,6); - return 0; - } - } - else if(fitem->third_get_id > 0) { - third_sd = map_id2sd(fitem->third_get_id); - if(tick < fitem->third_get_tick) { - if(fitem->first_get_id != sd->bl.id && fitem->second_get_id != sd->bl.id && fitem->third_get_id != sd->bl.id && - !(first_sd && first_sd->status.party_id == sd->status.party_id) && !(second_sd && second_sd->status.party_id == sd->status.party_id) && - !(third_sd && third_sd->status.party_id == sd->status.party_id)) { - clif_additem(sd,0,0,6); - return 0; - } - } - } - } - } - if((flag = pc_additem(sd,&fitem->item_data,fitem->item_data.amount))) - // 重量overで取得失敗 - clif_additem(sd,0,0,flag); - else { - /* 取得成功 */ - if(sd->attacktimer != -1) - pc_stopattack(sd); - clif_takeitem(&sd->bl,&fitem->bl); - map_clearflooritem(fitem->bl.id); - } - return 0; -} - -int pc_isUseitem(struct map_session_data *sd,int n) -{ - struct item_data *item; - int nameid; - - nullpo_retr(0, sd); - - item = sd->inventory_data[n]; - nameid = sd->status.inventory[n].nameid; - - if(item == NULL) - return 0; - if(item->type != 0 && item->type != 2) - return 0; - if((nameid == 605) && map[sd->bl.m].flag.gvg) - return 0; - if(nameid == 601 && (map[sd->bl.m].flag.noteleport || map[sd->bl.m].flag.gvg)) { - clif_skill_teleportmessage(sd,0); - return 0; - } - if(nameid == 602 && map[sd->bl.m].flag.noreturn) - return 0; - if(nameid == 604 && (map[sd->bl.m].flag.nobranch || map[sd->bl.m].flag.gvg)) - return 0; - if(item->sex != 2 && sd->status.sex != item->sex) - return 0; - if(item->elv > 0 && sd->status.base_level < item->elv) - return 0; - if(((sd->status.class_==13 || sd->status.class_==4014) && ((1<<7)&item->class_) == 0) || // have mounted classes use unmounted items [Valaris] - ((sd->status.class_==21 || sd->status.class_==4022) && ((1<<14)&item->class_) == 0)) - return 0; - if(sd->status.class_!=13 && sd->status.class_!=4014 && sd->status.class_!=21 && sd->status.class_!=4022) - if((sd->status.class_<=4000 && ((1<<sd->status.class_)&item->class_) == 0) || (sd->status.class_>4000 && sd->status.class_<4023 && ((1<<(sd->status.class_-4001))&item->class_) == 0) || - (sd->status.class_>=4023 && ((1<<(sd->status.class_-4023))&item->class_) == 0)) - return 0; - - if((log_config.branch > 0) && (nameid == 604)) - log_branch(sd); - - return 1; -} - -/*========================================== - * アイテムを使う - *------------------------------------------ - */ -int pc_useitem(struct map_session_data *sd,int n) -{ - int amount; - - nullpo_retr(1, sd); - - if(n >=0 && n < MAX_INVENTORY) { - char *script; - sd->itemid = sd->status.inventory[n].nameid; - amount = sd->status.inventory[n].amount; - if(sd->status.inventory[n].nameid <= 0 || - sd->status.inventory[n].amount <= 0 || - sd->sc_data[SC_BERSERK].timer!=-1 || - sd->sc_data[SC_MARIONETTE].timer!=-1 || - (pc_issit(sd) && (sd->itemid == 605 || sd->itemid == 606)) || - //added item_noequip.txt items check by Maya&[Lupus] - (map[sd->bl.m].flag.pvp && (sd->inventory_data[n]->flag.no_equip&1) ) || // PVP - (map[sd->bl.m].flag.gvg && (sd->inventory_data[n]->flag.no_equip>1) ) || // GVG - !pc_isUseitem(sd,n) ) { - clif_useitemack(sd,n,0,0); - return 1; - } - script = sd->inventory_data[n]->use_script; - amount = sd->status.inventory[n].amount; - clif_useitemack(sd,n,amount-1,1); - run_script(script,0,sd->bl.id,0); - pc_delitem(sd,n,1,1); - } - - return 0; -} - -/*========================================== - * カ?トアイテム追加。個?のみitem構造?の?字を無視 - *------------------------------------------ - */ -int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount) -{ - struct item_data *data; - int i,w; - - nullpo_retr(1, sd); - nullpo_retr(1, item_data); - - if(item_data->nameid <= 0 || amount <= 0) - return 1; - data = itemdb_search(item_data->nameid); - - if((w=data->weight*amount) + sd->cart_weight > sd->cart_max_weight) - return 1; - - i=MAX_CART; - if(!itemdb_isequip2(data)){ - // 装 備品ではないので、既所有品なら個数のみ変化させる - for(i=0;i<MAX_CART;i++){ - if(sd->status.cart[i].nameid==item_data->nameid && - sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] && - sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3]){ - if(sd->status.cart[i].amount+amount > MAX_AMOUNT) - return 1; - sd->status.cart[i].amount+=amount; - clif_cart_additem(sd,i,amount,0); - break; - } - } - } - if(i >= MAX_CART){ - // 装 備品か未所有品だったので空き欄へ追加 - for(i=0;i<MAX_CART;i++){ - if(sd->status.cart[i].nameid==0){ - memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0])); - sd->status.cart[i].amount=amount; - sd->cart_num++; - clif_cart_additem(sd,i,amount,0); - break; - } - } - if(i >= MAX_CART) - return 1; - } - sd->cart_weight += w; - clif_updatestatus(sd,SP_CARTINFO); - - return 0; -} - -/*========================================== - * カ?トアイテムを減らす - *------------------------------------------ - */ -int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type) -{ - nullpo_retr(1, sd); - - if(sd->status.cart[n].nameid==0 || - sd->status.cart[n].amount<amount) - return 1; - - sd->status.cart[n].amount -= amount; - sd->cart_weight -= itemdb_weight(sd->status.cart[n].nameid)*amount ; - if(sd->status.cart[n].amount <= 0){ - memset(&sd->status.cart[n],0,sizeof(sd->status.cart[0])); - sd->cart_num--; - } - if(!type) { - clif_cart_delitem(sd,n,amount); - clif_updatestatus(sd,SP_CARTINFO); - } - - return 0; -} - -/*========================================== - * カ?トへアイテム移動 - *------------------------------------------ - */ -int pc_putitemtocart(struct map_session_data *sd,int idx,int amount) { - struct item *item_data; - - nullpo_retr(0, sd); - nullpo_retr(0, item_data = &sd->status.inventory[idx]); - - if(itemdb_isdropable(sd->status.inventory[idx].nameid) == 0) - return 1; - if(pc_candrop(sd,sd->status.inventory[idx].nameid)==1) - return 1; - if (item_data->nameid==0 || item_data->amount<amount || sd->vender_id) - return 1; - if (pc_cart_additem(sd,item_data,amount) == 0) - return pc_delitem(sd,idx,amount,0); - - return 1; -} - -/*========================================== - * カ?ト?のアイテム?確認(個?の差分を返す) - *------------------------------------------ - */ -int pc_cartitem_amount(struct map_session_data *sd,int idx,int amount) -{ - struct item *item_data; - - nullpo_retr(-1, sd); - nullpo_retr(-1, item_data=&sd->status.cart[idx]); - - if( item_data->nameid==0 || !item_data->amount) - return -1; - return item_data->amount-amount; -} -/*========================================== - * カ?トからアイテム移動 - *------------------------------------------ - */ - -int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount) -{ - struct item *item_data; - int flag; - - nullpo_retr(0, sd); - nullpo_retr(0, item_data=&sd->status.cart[idx]); - - if( item_data->nameid==0 || item_data->amount<amount || sd->vender_id ) - return 1; - if((flag = pc_additem(sd,item_data,amount)) == 0) - return pc_cart_delitem(sd,idx,amount,0); - - clif_additem(sd,0,0,flag); - return 1; -} - -/*========================================== - * アイテム鑑定 - *------------------------------------------ - */ -int pc_item_identify(struct map_session_data *sd,int idx) -{ - int flag=1; - - nullpo_retr(0, sd); - - // Celest - if (sd->skillid == BS_REPAIRWEAPON) - return pc_item_repair (sd, idx); - else if (sd->skillid == WS_WEAPONREFINE) - return pc_item_refine (sd, idx); - - if(idx >= 0 && idx < MAX_INVENTORY) { - if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].identify == 0 ){ - flag=0; - sd->status.inventory[idx].identify=1; - } - clif_item_identified(sd,idx,flag); - } - else - clif_item_identified(sd,idx,flag); - - return !flag; -} - -/*========================================== - * Weapon Repair [Celest] - *------------------------------------------ - */ -int pc_item_repair(struct map_session_data *sd,int idx) -{ - int flag=1, material; - int materials[5] = { 0, 1002, 998, 999, 756 }; - struct item *item; - - nullpo_retr(0, sd); - - item = &sd->status.inventory[idx]; - - if(idx >= 0 && idx < MAX_INVENTORY) { - if(item->nameid > 0 && item->attribute == 1 ) { - if (itemdb_type(item->nameid)==4) - material = materials [itemdb_wlv (item->nameid)]; - else - material = materials [3]; - - if (pc_search_inventory(sd, material) < 0 ) { //fixed by Lupus (item pos can be = 0!) - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - flag=0; - item->attribute=0; - //Temporary Weapon Repair code [DracoRPG] - pc_delitem(sd, pc_search_inventory(sd, material), 1, 0); - clif_equiplist(sd); - clif_produceeffect(sd, 0, item->nameid); - clif_misceffect(&sd->bl, 3); - clif_displaymessage(sd->fd,"Item has been repaired."); - } - } - - return !flag; -} - -/*========================================== - * Weapon Refining [Celest] - *------------------------------------------ - */ -int pc_item_refine(struct map_session_data *sd,int idx) -{ - int flag = 1, i = 0, ep = 0, per; - int material[5] = { 0, 1010, 1011, 984, 984 }; - struct item *item; - - nullpo_retr(0, sd); - item = &sd->status.inventory[idx]; - - if(idx >= 0 && idx < MAX_INVENTORY) { - if(item->nameid > 0 && itemdb_type(item->nameid)==4) { - // if it's no longer refineable - if (item->refine >= sd->skilllv || item->refine == 10) { - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - if ((i=pc_search_inventory(sd, material [itemdb_wlv (item->nameid)])) < 0 ) { //fixed by Lupus (item pos can be = 0!) - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - - per = percentrefinery [itemdb_wlv (item->nameid)][(int)item->refine]; - //per += pc_checkskill(sd,BS_WEAPONRESEARCH); - per *= (75 + sd->status.job_level/2)/100; - - if (per > rand() % 100) { - flag = 0; - item->refine++; - pc_delitem(sd, i, 1, 0); - if(item->equip) { - ep = item->equip; - pc_unequipitem(sd,idx,3); - } - clif_refine(sd->fd,sd,0,idx,item->refine); - clif_delitem(sd,idx,1); - clif_additem(sd,idx,1,0); - if (ep) - pc_equipitem(sd,idx,ep); - clif_misceffect(&sd->bl,3); - } - else { - pc_delitem(sd, i, 1, 0); - item->refine = 0; - if(item->equip) - pc_unequipitem(sd,idx,3); - clif_refine(sd->fd,sd,1,idx,item->refine); - pc_delitem(sd,idx,1,0); - clif_misceffect(&sd->bl,2); - - clif_emotion(&sd->bl, 23); - } - } - } - - return !flag; -} - -/*========================================== - * スティル品公開 - *------------------------------------------ - */ -int pc_show_steal(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - int itemid; - int type; - - struct item_data *item=NULL; - char output[100]; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd=va_arg(ap,struct map_session_data *)); - - itemid=va_arg(ap,int); - type=va_arg(ap,int); - - if(!type){ - if((item=itemdb_exists(itemid))==NULL) - sprintf(output,"%s stole an Unknown_Item.",sd->status.name); - else - sprintf(output,"%s stole %s.",sd->status.name,item->jname); - clif_displaymessage( ((struct map_session_data *)bl)->fd, output); - }else{ - sprintf(output,"%s has not stolen the item because of being overweight.",sd->status.name); - clif_displaymessage( ((struct map_session_data *)bl)->fd, output); - } - - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -//** pc.c: Small Steal Item fix by fritz -int pc_steal_item(struct map_session_data *sd,struct block_list *bl) -{ - if(sd != NULL && bl != NULL && bl->type == BL_MOB) { - int i,skill,itemid,flag, count; - struct mob_data *md; - md=(struct mob_data *)bl; - if(!md->state.steal_flag && mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode&0x20) && - (!(md->class_>1324 && md->class_<1364))) // prevent stealing from treasure boxes [Valaris] - { - if (md->sc_data && (md->sc_data[SC_STONE].timer != -1 || md->sc_data[SC_FREEZE].timer != -1)) - return 0; - skill = battle_config.skill_steal_type == 1 - ? (sd->paramc[4] - mob_db[md->class_].dex)/2 + pc_checkskill(sd,TF_STEAL)*6 + 10 - : sd->paramc[4] - mob_db[md->class_].dex + pc_checkskill(sd,TF_STEAL)*3 + 10; - - if(0 < skill) - { - for(count = 10; count <= 10 && count != 0; count--) //8 -> 10 Lupus - { - i = rand()%10; //8 -> 10 Lupus - itemid = mob_db[md->class_].dropitem[i].nameid; - - if(itemid > 0 && itemdb_type(itemid) != 6) - { - //fixed rate. From Freya [Lupus] - if (rand() % 10000 < ((mob_db[md->class_].dropitem[i].p * skill) / 100 + sd->add_steal_rate)) - { - struct item tmp_item; - memset(&tmp_item,0,sizeof(tmp_item)); - tmp_item.nameid = itemid; - tmp_item.amount = 1; - tmp_item.identify = 1; - flag = pc_additem(sd,&tmp_item,1); - if(battle_config.show_steal_in_same_party) - { - party_foreachsamemap(pc_show_steal,sd,1,sd,tmp_item.nameid,0); - } - - if(flag) - { - if(battle_config.show_steal_in_same_party) - { - party_foreachsamemap(pc_show_steal,sd,1,sd,tmp_item.nameid,1); - } - - clif_additem(sd,0,0,flag); - } - md->state.steal_flag = 1; - return 1; - } - } - } - } - } - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int pc_steal_coin(struct map_session_data *sd,struct block_list *bl) -{ - if(sd != NULL && bl != NULL && bl->type == BL_MOB) { - int rate,skill; - struct mob_data *md=(struct mob_data *)bl; - if(md && !md->state.steal_coin_flag) { - if (md->sc_data && (md->sc_data[SC_STONE].timer != -1 || md->sc_data[SC_FREEZE].timer != -1)) - return 0; - skill = pc_checkskill(sd,RG_STEALCOIN)*10; - rate = skill + (sd->status.base_level - mob_db[md->class_].lv)*3 + sd->paramc[4]*2 + sd->paramc[5]*2; - if(rand()%1000 < rate) { - pc_getzeny(sd,mob_db[md->class_].lv*10 + rand()%100); - md->state.steal_coin_flag = 1; - return 1; - } - } - } - - return 0; -} -// -// -// -/*========================================== - * PCの位置設定 - *------------------------------------------ - */ -int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrtype) -{ - char mapname[24]; - int m=0,disguise=0; - - nullpo_retr(0, sd); - - if(sd->chatID) // チャットから出る - chat_leavechat(sd); - if(sd->trade_partner) // 取引を中?する - trade_tradecancel(sd); - if(sd->state.storage_flag) - storage_guild_storage_quit(sd,0); - else - storage_storage_quit(sd); // 倉庫を開いてるなら保存する - - if(sd->party_invite>0) // パ?ティ?誘を拒否する - party_reply_invite(sd,sd->party_invite_account,0); - if(sd->guild_invite>0) // ギルド?誘を拒否する - guild_reply_invite(sd,sd->guild_invite,0); - if(sd->guild_alliance>0) // ギルド同盟?誘を拒否する - guild_reply_reqalliance(sd,sd->guild_alliance_account,0); - - skill_castcancel(&sd->bl,0); // 詠唱中? - pc_stop_walking(sd,0); // ?行中? - pc_stopattack(sd); // 攻?中? - - if(pc_issit(sd)) { - pc_setstand(sd); - skill_gangsterparadise(sd,0); - } - - if (sd->sc_count) { - if(sd->sc_data[SC_TRICKDEAD].timer != -1) - status_change_end(&sd->bl, SC_TRICKDEAD, -1); - if(sd->sc_data[SC_BLADESTOP].timer!=-1) - status_change_end(&sd->bl,SC_BLADESTOP,-1); - if(sd->sc_data[SC_DANCING].timer!=-1) // clear dance effect when warping [Valaris] - skill_stop_dancing(&sd->bl,0); - if (sd->sc_data[SC_BASILICA].timer!=-1) { - /*int i; - for (i=0;i<MAX_SKILLUNITGROUP;i++) - if (sd->skillunit[i].skill_id==HP_BASILICA) - skill_delunitgroup(&sd->skillunit[i]);*/ - - struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc_data[SC_BASILICA].val4; - if (sg && sg->src_id == sd->bl.id) - skill_delunitgroup (sg); - status_change_end(&sd->bl,SC_BASILICA,-1); - } - } - - if(sd->status.option&2) - status_change_end(&sd->bl, SC_HIDING, -1); - if(sd->status.option&4) - status_change_end(&sd->bl, SC_CLOAKING, -1); - if(sd->status.option&16384) - status_change_end(&sd->bl, SC_CHASEWALK, -1); - - if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) { - pet_stopattack(sd->pd); - pet_changestate(sd->pd,MS_IDLE,0); - } - - if(sd->disguise) { // clear disguises when warping [Valaris] - clif_clearchar(&sd->bl, 9); - disguise=sd->disguise; - sd->disguise=0; - } - - strncpy(mapname,mapname_org,sizeof(mapname)); - mapname[16]=0; - if(strstr(mapname,".gat")==NULL && strstr(mapname,".afm")==NULL && strlen(mapname)<16){ - strcat(mapname,".gat"); - } - - m=map_mapname2mapid(mapname); - - if(m<0){ - if(sd->mapname[0]){ - int ip,port; - if(map_mapname2ipport(mapname,&ip,&port)==0){ - skill_stop_dancing(&sd->bl,1); - skill_unit_move(&sd->bl,gettick(),0); - clif_clearchar_area(&sd->bl,clrtype&0xffff); - skill_gangsterparadise(sd,0); - map_delblock(&sd->bl); - if(sd->status.pet_id > 0 && sd->pd) { - if(sd->pd->bl.m != m && sd->pet.intimate <= 0) { - pet_remove_map(sd); - intif_delete_petdata(sd->status.pet_id); - sd->status.pet_id = 0; - sd->pd = NULL; - sd->petDB = NULL; - if(battle_config.pet_status_support) - status_calc_pc(sd,2); - } - else if(sd->pet.intimate > 0) { - pet_stopattack(sd->pd); - pet_changestate(sd->pd,MS_IDLE,0); - clif_clearchar_area(&sd->pd->bl,clrtype&0xffff); - map_delblock(&sd->pd->bl); - } - } - memcpy(sd->mapname,mapname,24); - sd->bl.x=x; - sd->bl.y=y; - sd->state.waitingdisconnect=1; - pc_clean_skilltree(sd); - pc_makesavestatus(sd); - if(sd->status.pet_id > 0 && sd->pd) - intif_save_petdata(sd->status.account_id,&sd->pet); - chrif_save(sd); - storage_storage_save(sd); - storage_delete(sd->status.account_id); - chrif_changemapserver(sd, mapname, x, y, ip, port); - return 0; - } - } -#if 0 - clif_authfail_fd(sd->fd,0); // cancel - clif_setwaitclose(sd->fd); -#endif - return 1; - } - - if(x <0 || x >= map[m].xs || y <0 || y >= map[m].ys) - x=y=0; - if((x==0 && y==0) || map_getcell(m,x,y,CELL_CHKNOPASS)){ - if(x||y) { - if(battle_config.error_log) - printf("stacked (%d,%d)\n",x,y); - } - do { - x=rand()%(map[m].xs-2)+1; - y=rand()%(map[m].ys-2)+1; - } while(map_getcell(m,x,y,CELL_CHKNOPASS)); - } - - if(sd->mapname[0] && sd->bl.prev != NULL){ - skill_unit_move(&sd->bl,gettick(),0); - clif_clearchar_area(&sd->bl,clrtype&0xffff); - skill_gangsterparadise(sd,0); - map_delblock(&sd->bl); - // pet - if(sd->status.pet_id > 0 && sd->pd) { - if(sd->pd->bl.m != m && sd->pet.intimate <= 0) { - pet_remove_map(sd); - intif_delete_petdata(sd->status.pet_id); - sd->status.pet_id = 0; - sd->pd = NULL; - sd->petDB = NULL; - if(battle_config.pet_status_support) - status_calc_pc(sd,2); - pc_clean_skilltree(sd); - pc_makesavestatus(sd); - chrif_save(sd); - storage_storage_save(sd); - } - else if(sd->pet.intimate > 0) { - pet_stopattack(sd->pd); - pet_changestate(sd->pd,MS_IDLE,0); - clif_clearchar_area(&sd->pd->bl,clrtype&0xffff); - map_delblock(&sd->pd->bl); - } - } - clif_changemap(sd,map[m].name,x,y); // [MouseJstr] - } - - if(disguise) // disguise teleport fix [Valaris] - sd->disguise=disguise; - - memcpy(sd->mapname,mapname,24); - sd->bl.m = m; - sd->to_x = x; - sd->to_y = y; - - // moved and changed dance effect stopping - - sd->bl.x = x; - sd->bl.y = y; - - if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) { - sd->pd->bl.m = m; - sd->pd->bl.x = sd->pd->to_x = x; - sd->pd->bl.y = sd->pd->to_y = y; - sd->pd->dir = sd->dir; - } - -// map_addblock(&sd->bl); /// ブロック登?とspawnは -// clif_spawnpc(sd); - - return 0; -} - -/*========================================== - * PCのランダムワ?プ - *------------------------------------------ - */ -int pc_randomwarp(struct map_session_data *sd, int type) { - int x,y,i=0; - int m; - - nullpo_retr(0, sd); - - m=sd->bl.m; - - if (map[sd->bl.m].flag.noteleport) // テレポ?ト禁止 - return 0; - - do{ - x=rand()%(map[m].xs-2)+1; - y=rand()%(map[m].ys-2)+1; - }while(map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000 ); - - if (i < 1000) - pc_setpos(sd,map[m].name,x,y,type); - - return 0; -} - -/*========================================== - * 現在位置のメモ - *------------------------------------------ - */ -int pc_memo(struct map_session_data *sd, int i) { - int skill; - int j; - - nullpo_retr(0, sd); - - skill = pc_checkskill(sd, AL_WARP); - - if (i >= MIN_PORTAL_MEMO) - i -= MIN_PORTAL_MEMO; - else if (map[sd->bl.m].flag.nomemo || (map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd))) { - clif_skill_teleportmessage(sd, 1); - return 0; - } - - if (skill < 1) { - clif_skill_memo(sd,2); - } - - if (skill < 2 || i < -1 || i > 2) { - clif_skill_memo(sd, 1); - return 0; - } - - for(j = 0 ; j < 3; j++) { - if (strcmp(sd->status.memo_point[j].map, map[sd->bl.m].name) == 0) { - i = j; - break; - } - } - - if (i == -1) { - for(i = skill - 3; i >= 0; i--) { - memcpy(&sd->status.memo_point[i+1],&sd->status.memo_point[i], - sizeof(struct point)); - } - i = 0; - } - memcpy(sd->status.memo_point[i].map, map[sd->bl.m].name, 24); - sd->status.memo_point[i].x = sd->bl.x; - sd->status.memo_point[i].y = sd->bl.y; - - clif_skill_memo(sd, 0); - - return 1; -} - -/*========================================== - * - *------------------------------------------ - */ -int pc_can_reach(struct map_session_data *sd,int x,int y) -{ - struct walkpath_data wpd; - - nullpo_retr(0, sd); - - if( sd->bl.x==x && sd->bl.y==y ) // 同じマス - return 1; - - // 障害物判定 - wpd.path_len=0; - wpd.path_pos=0; - wpd.path_half=0; - return (path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,x,y,0)!=-1)?1:0; -} - -// -// ? 行物 -// -/*========================================== - * 次の1?にかかる史ヤを計算 - *------------------------------------------ - */ -static int calc_next_walk_step(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - if(sd->walkpath.path_pos>=sd->walkpath.path_len) - return -1; - if(sd->walkpath.path[sd->walkpath.path_pos]&1) - return sd->speed*14/10; - - return sd->speed; -} - -/*========================================== - * 半?進む(timer??) - *------------------------------------------ - */ -static int pc_walk(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd; - int i; - int moveblock; - int x,y,dx,dy; - - if ((sd = map_id2sd(id)) == NULL) - return 0; - - if(sd->walktimer != tid){ - if(battle_config.error_log) - printf("pc_walk %d != %d\n",sd->walktimer,tid); - return 0; - } - sd->walktimer=-1; - if(sd->walkpath.path_pos>=sd->walkpath.path_len || sd->walkpath.path_pos!=data) - return 0; - - //?いたので息吹のタイマ?を初期化 - sd->inchealspirithptick = 0; - sd->inchealspiritsptick = 0; - - sd->walkpath.path_half ^= 1; - if(sd->walkpath.path_half==0){ // マス目中心へ途 - sd->walkpath.path_pos++; - - if(sd->state.change_walk_target){ - pc_walktoxy_sub(sd); - return 0; - } - } else { // マス目境界へ途 - if(sd->walkpath.path[sd->walkpath.path_pos]>=8) - return 1; - - x = sd->bl.x; - y = sd->bl.y; - if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) { - pc_stop_walking(sd,1); - return 0; - } - sd->dir=sd->head_dir=sd->walkpath.path[sd->walkpath.path_pos]; - dx = dirx[(int)sd->dir]; - dy = diry[(int)sd->dir]; - if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) { - pc_walktoxy_sub(sd); - return 0; - } - if (skill_check_moonlit (&sd->bl,x+dx,y+dy)) { - pc_stop_walking(sd,1); - return 0; - } - moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE); - - sd->walktimer = 1; - map_foreachinmovearea(clif_pcoutsight,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,0,sd); - - x += dx; - y += dy; - - skill_unit_move(&sd->bl,tick,0); - if(moveblock) map_delblock(&sd->bl); - sd->bl.x = x; - sd->bl.y = y; - if(moveblock) map_addblock(&sd->bl); - skill_unit_move(&sd->bl,tick,1); - - map_foreachinmovearea(clif_pcinsight,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,0,sd); - sd->walktimer = -1; - - if(sd->status.party_id>0){ // パ?ティのHP情報通知?査 - struct party *p=party_search(sd->status.party_id); - if(p!=NULL){ - int p_flag=0; - map_foreachinmovearea(party_send_hp_check,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,sd->status.party_id,&p_flag); - if(p_flag) - sd->party_hp=-1; - } - } - if(sd->status.option&4) // クロ?キングの消滅?査 - skill_check_cloaking(&sd->bl); - /* ディボ?ション?査 */ - for(i=0;i<5;i++) - if(sd->dev.val1[i]){ - skill_devotion3(&sd->bl,sd->dev.val1[i]); - break; - } - /* 被ディボ?ション?査 */ - if(sd->sc_count) { - if (sd->sc_data[SC_DANCING].timer!=-1) - skill_unit_move_unit_group((struct skill_unit_group *)sd->sc_data[SC_DANCING].val2,sd->bl.m,dx,dy); - - if (sd->sc_data[SC_DEVOTION].val1) - skill_devotion2(&sd->bl,sd->sc_data[SC_DEVOTION].val1); - - if (sd->sc_data[SC_BASILICA].timer!=-1) { // Basilica cancels if caster moves [celest] - /*int i; - for (i=0;i<MAX_SKILLUNITGROUP;i++) - if (sd->skillunit[i].skill_id==HP_BASILICA*/ - struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc_data[SC_BASILICA].val4; - if (sg && sg->src_id == sd->bl.id) - skill_delunitgroup (sg); - status_change_end(&sd->bl,SC_BASILICA,-1); - } - } - - if(map_getcell(sd->bl.m,x,y,CELL_CHKNPC)) - npc_touch_areanpc(sd,sd->bl.m,x,y); - else - sd->areanpc_id=0; - } - if((i=calc_next_walk_step(sd))>0) { - i = i>>1; - if(i < 1 && sd->walkpath.path_half == 0) - i = 1; - sd->walktimer=add_timer(tick+i,pc_walk,id,sd->walkpath.path_pos); - } - if(battle_config.disp_hpmeter) - clif_hpmeter(sd); - - return 0; -} - -/*========================================== - * 移動可能か確認して、可能なら?行開始 - *------------------------------------------ - */ -static int pc_walktoxy_sub(struct map_session_data *sd) -{ - struct walkpath_data wpd; - int i; - - nullpo_retr(1, sd); - - if(path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,sd->to_x,sd->to_y,0)) - return 1; - memcpy(&sd->walkpath,&wpd,sizeof(wpd)); - - clif_walkok(sd); - sd->state.change_walk_target=0; - - if((i=calc_next_walk_step(sd))>0){ - i = i>>2; - sd->walktimer=add_timer(gettick()+i,pc_walk,sd->bl.id,0); - } - clif_movechar(sd); - - return 0; -} - -/*========================================== - * pc? 行要求 - *------------------------------------------ - */ -int pc_walktoxy(struct map_session_data *sd,int x,int y) -{ - - nullpo_retr(0, sd); - - sd->to_x=x; - sd->to_y=y; - sd->idletime = tick_; - - if(sd->walktimer != -1 && sd->state.change_walk_target==0){ - // 現在?いている最中の目的地?更なのでマス目の中心に?た暫ノ - // timer??からpc_walktoxy_subを呼ぶようにする - sd->state.change_walk_target=1; - } else { - pc_walktoxy_sub(sd); - } - - if (sd->state.gmaster_flag > 0) { - struct guild *g = (struct guild *)sd->state.gmaster_flag; - if (g) - map_foreachinarea (skill_guildaura_sub, sd->bl.m, - sd->bl.x-2, sd->bl.y-2, sd->bl.x+2, sd->bl.y+2, BL_PC, - sd->bl.id, sd->status.guild_id, g); - } - - return 0; -} - -/*========================================== - * ? 行停止 - *------------------------------------------ - */ -int pc_stop_walking(struct map_session_data *sd,int type) -{ - nullpo_retr(0, sd); - - if(sd->walktimer != -1) { - delete_timer(sd->walktimer,pc_walk); - sd->walktimer=-1; - } - sd->walkpath.path_len=0; - sd->to_x = sd->bl.x; - sd->to_y = sd->bl.y; - if(type&0x01) - clif_fixpos(&sd->bl); - if(type&0x02 && battle_config.pc_damage_delay) { - unsigned int tick = gettick(); - int delay = status_get_dmotion(&sd->bl); - if(sd->canmove_tick < tick) - sd->canmove_tick = tick + delay; - } - - return 0; -} - -/*========================================== - * Random walk - *------------------------------------------ - */ -int pc_randomwalk(struct map_session_data *sd,int tick) -{ - const int retrycount = 20; - nullpo_retr(0, sd); - - if(DIFF_TICK(sd->next_walktime,tick)<0){ - int i,x,y,d; - d = rand()%7+5; - for(i=0;i<retrycount;i++){ // Search of a movable place - int r=rand(); - x=sd->bl.x+r%(d*2+1)-d; - y=sd->bl.y+r/(d*2+1)%(d*2+1)-d; - if((map_getcell(sd->bl.m,x,y,CELL_CHKPASS)) && pc_walktoxy(sd,x,y)==0) - break; - } - // Working on this part later [celest] - /*for(i=c=0;i<sd->walkpath.path_len;i++){ // The next walk start time is calculated. - if(sd->walkpath.path[i]&1) - c+=sd->speed*14/10; - else - c+=sd->speed; - } - sd->next_walktime = (d=tick+rand()%3000+c); - return d;*/ - return 1; - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int pc_movepos(struct map_session_data *sd,int dst_x,int dst_y) -{ - int moveblock; - int dx,dy; - int tick = gettick(); - - struct walkpath_data wpd; - - nullpo_retr(0, sd); - - if(path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,dst_x,dst_y,0)) - return 1; - - sd->dir = sd->head_dir = map_calc_dir(&sd->bl, dst_x,dst_y); - - dx = dst_x - sd->bl.x; - dy = dst_y - sd->bl.y; - - moveblock = ( sd->bl.x/BLOCK_SIZE != dst_x/BLOCK_SIZE || sd->bl.y/BLOCK_SIZE != dst_y/BLOCK_SIZE); - - map_foreachinmovearea(clif_pcoutsight,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,dx,dy,0,sd); - - skill_unit_move(&sd->bl,tick,0); - if(moveblock) map_delblock(&sd->bl); - sd->bl.x = dst_x; - sd->bl.y = dst_y; - if(moveblock) map_addblock(&sd->bl); - skill_unit_move(&sd->bl,tick,1); - - map_foreachinmovearea(clif_pcinsight,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,-dx,-dy,0,sd); - - if(sd->status.party_id>0){ // パ?ティのHP情報通知?査 - struct party *p=party_search(sd->status.party_id); - if(p!=NULL){ - int flag=0; - map_foreachinmovearea(party_send_hp_check,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,-dx,-dy,BL_PC,sd->status.party_id,&flag); - if(flag) - sd->party_hp=-1; - } - } - - if(sd->status.option&4) // クロ?キングの消滅?査 - skill_check_cloaking(&sd->bl); - - if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC)) - npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y); - else - sd->areanpc_id=0; - return 0; -} - -// -// 武器?? -// -/*========================================== - * スキルの?索 所有していた場合Lvが返る - *------------------------------------------ - */ -int pc_checkskill(struct map_session_data *sd,int skill_id) -{ - if(sd == NULL) return 0; - if( skill_id>=10000 ){ - struct guild *g; - if( sd->status.guild_id>0 && (g=guild_search(sd->status.guild_id))!=NULL) - return guild_checkskill(g,skill_id); - return 0; - } - - if(sd->status.skill[skill_id].id == skill_id) - return (sd->status.skill[skill_id].lv); - - return 0; -} - -/*========================================== - * 武器?更によるスキルの??チェック - * 引?: - * struct map_session_data *sd セッションデ?タ - * int nameid ?備品ID - * 返り値: - * 0 ?更なし - * -1 スキルを解除 - *------------------------------------------ - */ -int pc_checkallowskill(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - nullpo_retr(0, sd->sc_data); - - if(!(skill_get_weapontype(KN_TWOHANDQUICKEN)&(1<<sd->status.weapon)) && sd->sc_data[SC_TWOHANDQUICKEN].timer!=-1) { // 2HQ - status_change_end(&sd->bl,SC_TWOHANDQUICKEN,-1); // 2HQを解除 - return -1; - } - if(!(skill_get_weapontype(LK_AURABLADE)&(1<<sd->status.weapon)) && sd->sc_data[SC_AURABLADE].timer!=-1) { /* オ?ラブレ?ド */ - status_change_end(&sd->bl,SC_AURABLADE,-1); /* オ?ラブレ?ドを解除 */ - return -1; - } - if(!(skill_get_weapontype(LK_PARRYING)&(1<<sd->status.weapon)) && sd->sc_data[SC_PARRYING].timer!=-1) { /* パリイング */ - status_change_end(&sd->bl,SC_PARRYING,-1); /* パリイングを解除 */ - return -1; - } - if(!(skill_get_weapontype(LK_CONCENTRATION)&(1<<sd->status.weapon)) && sd->sc_data[SC_CONCENTRATION].timer!=-1) { /* コンセントレ?ション */ - status_change_end(&sd->bl,SC_CONCENTRATION,-1); /* コンセントレ?ションを解除 */ - return -1; - } - if(!(skill_get_weapontype(CR_SPEARQUICKEN)&(1<<sd->status.weapon)) && sd->sc_data[SC_SPEARSQUICKEN].timer!=-1){ // スピアクィッケン - status_change_end(&sd->bl,SC_SPEARSQUICKEN,-1); // スピアクイッケンを解除 - return -1; - } - if(!(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon)) && sd->sc_data[SC_ADRENALINE].timer!=-1){ // アドレナリンラッシュ - status_change_end(&sd->bl,SC_ADRENALINE,-1); // アドレナリンラッシュを解除 - return -1; - } - - if(sd->status.shield <= 0) { - if(sd->sc_data[SC_AUTOGUARD].timer!=-1){ // オ?トガ?ド - status_change_end(&sd->bl,SC_AUTOGUARD,-1); - return -1; - } - if(sd->sc_data[SC_DEFENDER].timer!=-1){ // ディフェンダ? - status_change_end(&sd->bl,SC_DEFENDER,-1); - return -1; - } - if(sd->sc_data[SC_REFLECTSHIELD].timer!=-1){ //リフレクトシ?ルド - status_change_end(&sd->bl,SC_REFLECTSHIELD,-1); - return -1; - } - } - - return 0; -} - -/*========================================== - * ? 備品のチェック - *------------------------------------------ - */ -int pc_checkequip(struct map_session_data *sd,int pos) -{ - int i; - - nullpo_retr(-1, sd); - - for(i=0;i<11;i++){ - if(pos & equip_pos[i]) - return sd->equip_index[i]; - } - - return -1; -} - -/*========================================== - * ?生職や養子職の元の職業を返す - *------------------------------------------ - */ -struct pc_base_job pc_calc_base_job(int b_class) -{ - struct pc_base_job bj; - //?生や養子の場合の元の職業を算出する - //if(b_class < MAX_PC_CLASS){ //通常 - if(b_class < 4001){ - bj.job = b_class; - bj.upper = 0; - }else if(b_class >= 4001 && b_class < 4023){ //?生職 - // Athena almost never uses this... well, used this. :3 - bj.job = b_class - 4001; - bj.upper = 1; - //}else if(b_class == 23 + 4023 -1){ //養子スパノビ - }else if(b_class == 4045){ // super baby - //bj.job = b_class - (4023 - 1); - bj.job = 23; - bj.upper = 2; - }else{ //養子スパノビ以外の養子 - bj.job = b_class - 4023; - bj.upper = 2; - } - - if(bj.job == 0){ - bj.type = 0; - }else if(bj.job < 7){ - bj.type = 1; - }else{ - bj.type = 2; - } - - return bj; -} - -/*========================================== - * For quick calculating [Celest] - *------------------------------------------ - */ -int pc_calc_base_job2 (int b_class) -{ - if(b_class < 4001) - return b_class; - else if(b_class >= 4001 && b_class < 4023) - return b_class - 4001; - else if(b_class == 4045) - return 23; - return b_class - 4023; -} - -int pc_calc_upper(int b_class) -{ - if(b_class < 4001) - return 0; - else if(b_class >= 4001 && b_class < 4023) - return 1; - return 2; -} - -/*========================================== - * PCの攻? (timer??) - *------------------------------------------ - */ -int pc_attack_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd; - struct block_list *bl; - struct status_change *sc_data; - short *opt; - int dist,skill,range; - - sd=map_id2sd(id); - if(sd == NULL) - return 0; - - sd->idletime = tick_; - - if(sd->attacktimer != tid){ - if(battle_config.error_log) - printf("pc_attack_timer %d != %d\n",sd->attacktimer,tid); - return 0; - } - sd->attacktimer=-1; - - if(sd->bl.prev == NULL) - return 0; - - bl=map_id2bl(sd->attacktarget); - if(bl==NULL || bl->prev == NULL) - return 0; - - if(bl->type == BL_PC) { - if (pc_isdead((struct map_session_data *)bl)) - return 0; - else if (pc_ishiding((struct map_session_data *)bl)) - return 0; - } - - // 同じmapでないなら攻?しない - // PCが死んでても攻?しない - if(sd->bl.m != bl->m || pc_isdead(sd)) - return 0; - - //if( sd->opt1>0 || sd->status.option&2 || sd->status.option&16388) // 異常などで攻?できない - if( sd->opt1>0 || sd->status.option&2 || sd->status.option&16384) // 異常などで攻?できない - return 0; - - if (sd->sc_count) { - if(sd->sc_data[SC_AUTOCOUNTER].timer != -1) - return 0; - if(sd->sc_data[SC_BLADESTOP].timer != -1) - return 0; - } - - //if((opt = status_get_option(bl)) != NULL && *opt&0x46) - if((opt = status_get_option(bl)) != NULL && *opt&0x42) - return 0; - if((sc_data = status_get_sc_data(bl)) != NULL) { - if (sc_data[SC_TRICKDEAD].timer != -1 || - sc_data[SC_BASILICA].timer != -1) - return 0; - } - - if(sd->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) <= 0) - return 0; - - if(!battle_config.sdelay_attack_enable && pc_checkskill(sd,SA_FREECAST) <= 0) { - if(DIFF_TICK(tick , sd->canact_tick) < 0) { - clif_skill_fail(sd,1,4,0); - return 0; - } - } - - if(sd->status.weapon == 11 && sd->equip_index[10] < 0) { - clif_arrow_fail(sd,0); - return 0; - } - - dist = distance(sd->bl.x,sd->bl.y,bl->x,bl->y); - range = sd->attackrange; - if(sd->status.weapon != 11) range++; - if( dist > range ){ // ? かないので移動 - if(pc_can_reach(sd,bl->x,bl->y)) - clif_movetoattack(sd,bl); - return 0; - } - - if(dist <= range && !battle_check_range(&sd->bl,bl,range) ) { - if(pc_can_reach(sd,bl->x,bl->y) && sd->canmove_tick < tick && (sd->sc_data[SC_ANKLE].timer == -1 || sd->sc_data[SC_SPIDERWEB].timer == -1)) - pc_walktoxy(sd,bl->x,bl->y); - sd->attackabletime = tick + (sd->aspd<<1); - } - else { - if(battle_config.pc_attack_direction_change) - sd->dir=sd->head_dir=map_calc_dir(&sd->bl, bl->x,bl->y ); // 向き設定 - - if(sd->walktimer != -1) - pc_stop_walking(sd,1); - - if(sd->sc_data[SC_COMBO].timer == -1) { - map_freeblock_lock(); - pc_stop_walking(sd,0); - sd->attacktarget_lv = battle_weapon_attack(&sd->bl,bl,tick,0); - // &2 = ? - Celest - if(!(battle_config.pc_cloak_check_type&2) && sd->sc_data[SC_CLOAKING].timer != -1) - status_change_end(&sd->bl,SC_CLOAKING,-1); - if(sd->status.pet_id > 0 && sd->pd && sd->petDB && battle_config.pet_attack_support) - pet_target_check(sd,bl,0); - map_freeblock_unlock(); - if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0 ) // フリ?キャスト - sd->attackabletime = tick + ((sd->aspd<<1)*(150 - skill*5)/100); - else - sd->attackabletime = tick + (sd->aspd<<1); - } - else if(sd->attackabletime <= tick) { - if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0 ) // フリ?キャスト - sd->attackabletime = tick + ((sd->aspd<<1)*(150 - skill*5)/100); - else - sd->attackabletime = tick + (sd->aspd<<1); - } - if(sd->attackabletime <= tick) sd->attackabletime = tick + (battle_config.max_aspd<<1); - } - - if(sd->state.attack_continue) { - sd->attacktimer=add_timer(sd->attackabletime,pc_attack_timer,sd->bl.id,0); - } - - return 0; -} - -/*========================================== - * 攻?要求 - * typeが1なら??攻? - *------------------------------------------ - */ -int pc_attack(struct map_session_data *sd,int target_id,int type) -{ - struct block_list *bl; - int d; - - - nullpo_retr(0, sd); - - bl=map_id2bl(target_id); - if(bl==NULL) - return 1; - - sd->idletime = tick_; - - if(bl->type==BL_NPC) { // monster npcs [Valaris] - //npc_click(sd,RFIFOL(sd->fd,2)); - npc_click(sd,target_id); // submitted by leinsirk10 [Celest] - return 0; - } - - if(battle_check_target(&sd->bl,bl,BCT_ENEMY) <= 0) - return 1; - if(sd->attacktimer != -1) - pc_stopattack(sd); - sd->attacktarget=target_id; - sd->state.attack_continue=type; - - d=DIFF_TICK(sd->attackabletime,gettick()); - if(d>0 && d<2000){ // 攻?delay中 - sd->attacktimer=add_timer(sd->attackabletime,pc_attack_timer,sd->bl.id,0); - } else { - // 本?timer??なので引?を合わせる - pc_attack_timer(-1,gettick(),sd->bl.id,0); - } - - return 0; -} - -/*========================================== - * ??攻?停止 - *------------------------------------------ - */ -int pc_stopattack(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - if(sd->attacktimer != -1) { - delete_timer(sd->attacktimer,pc_attack_timer); - sd->attacktimer=-1; - } - sd->attacktarget=0; - sd->state.attack_continue=0; - - return 0; -} - -int pc_follow_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd, *bl; - - sd=map_id2sd(id); - - if(sd == NULL || sd->followtimer != tid || pc_isdead(sd)) - return 0; - - sd->followtimer=-1; - - do { - if(sd->bl.prev == NULL) - break; - - bl=(struct map_session_data *) map_id2bl(sd->followtarget); - - if(bl==NULL) - return 0; - - if(bl->bl.prev == NULL) - break; - - if(bl->bl.type == BL_PC && pc_isdead((struct map_session_data *)bl)) - return 0; - - if (sd->skilltimer == -1 && sd->attacktimer == -1 && sd->walktimer == -1) { - if((sd->bl.m == bl->bl.m) && pc_can_reach(sd,bl->bl.x,bl->bl.y)) { - if (distance(sd->bl.x,sd->bl.y,bl->bl.x,bl->bl.y) > 5) - pc_walktoxy(sd,bl->bl.x,bl->bl.y); - } else - pc_setpos((struct map_session_data*)sd, bl->mapname, bl->bl.x, bl->bl.y, 3); - } - } while (0); - - sd->followtimer=add_timer(tick + sd->aspd,pc_follow_timer,sd->bl.id,0); - - return 0; -} - -int pc_follow(struct map_session_data *sd,int target_id) -{ - struct block_list *bl; - - bl=map_id2bl(target_id); - if(bl==NULL) - return 1; - sd->followtarget=target_id; - if(sd->followtimer != -1) { - delete_timer(sd->followtimer,pc_follow_timer); - sd->followtimer = -1; - } - - pc_follow_timer(-1,gettick(),sd->bl.id,0); - - return 0; -} - -int pc_checkbaselevelup(struct map_session_data *sd) -{ - int next = pc_nextbaseexp(sd); - - nullpo_retr(0, sd); - - if(sd->status.base_exp >= next && next > 0){ - struct pc_base_job s_class = pc_calc_base_job(sd->status.class_); - - // base側レベルアップ?理 - sd->status.base_exp -= next; - - sd->status.base_level ++; - sd->status.status_point += (sd->status.base_level+14) / 5 ; - clif_updatestatus(sd,SP_STATUSPOINT); - clif_updatestatus(sd,SP_BASELEVEL); - clif_updatestatus(sd,SP_NEXTBASEEXP); - status_calc_pc(sd,0); - pc_heal(sd,sd->status.max_hp,sd->status.max_sp); - - //スパノビはキリエ、イムポ、マニピ、グロ、サフラLv1がかかる - if(s_class.job == 23){ - status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],1,0,0,0,skill_get_time(PR_KYRIE,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_IMPOSITIO],1,0,0,0,skill_get_time(PR_IMPOSITIO,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],1,0,0,0,skill_get_time(PR_MAGNIFICAT,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_GLORIA],1,0,0,0,skill_get_time(PR_GLORIA,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_SUFFRAGIUM],1,0,0,0,skill_get_time(PR_SUFFRAGIUM,1),0 ); - } - - clif_misceffect(&sd->bl,0); - //レベルアップしたのでパ?ティ?情報を更新する - //(公平範?チェック) - party_send_movemap(sd); - return 1; - } - - return 0; -} - -int pc_checkjoblevelup(struct map_session_data *sd) -{ - int next = pc_nextjobexp(sd); - - nullpo_retr(0, sd); - - if(sd->status.job_exp >= next && next > 0){ - // job側レベルアップ?理 - sd->status.job_exp -= next; - sd->status.job_level ++; - clif_updatestatus(sd,SP_JOBLEVEL); - clif_updatestatus(sd,SP_NEXTJOBEXP); - sd->status.skill_point ++; - clif_updatestatus(sd,SP_SKILLPOINT); - status_calc_pc(sd,0); - - clif_misceffect(&sd->bl,1); - return 1; - } - - return 0; -} - -/*========================================== - * ??値取得 - *------------------------------------------ - */ -int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp) -{ - char output[256]; - float nextbp=0, nextjp=0; - int nextb=0, nextj=0; - nullpo_retr(0, sd); - - if(sd->bl.prev == NULL || pc_isdead(sd)) - return 0; - - if((battle_config.pvp_exp == 0) && map[sd->bl.m].flag.pvp) // [MouseJstr] - return 0; // no exp on pvp maps - - if(sd->sc_data[SC_RICHMANKIM].timer != -1) { // added bounds checking [Vaalris] - base_exp += base_exp*(25 + sd->sc_data[SC_RICHMANKIM].val1*25)/100; - job_exp += job_exp*(25 + sd->sc_data[SC_RICHMANKIM].val1*25)/100; - } - - if(sd->status.guild_id>0){ // ギルドに上納 - base_exp-=guild_payexp(sd,base_exp); - if(base_exp < 0) - base_exp = 0; - } - - if(!battle_config.multi_level_up && pc_nextbaseafter(sd) && sd->status.base_exp+base_exp >= pc_nextbaseafter(sd)) { - base_exp = pc_nextbaseafter(sd) - sd->status.base_exp; - if (base_exp < 0) - base_exp = 0; - } - nextb = pc_nextbaseexp(sd); - nextj = pc_nextjobexp(sd); - if (nextb > 0) - nextbp = (float) base_exp / (float) nextb; - if (nextj > 0) - nextjp = (float) job_exp / (float) nextj; - - sd->status.base_exp += base_exp; - if(sd->status.base_exp < 0) - sd->status.base_exp = 0; - - while(pc_checkbaselevelup(sd)) ; - - clif_updatestatus(sd,SP_BASEEXP); - if(!battle_config.multi_level_up && pc_nextjobafter(sd) && sd->status.job_exp+job_exp >= pc_nextjobafter(sd)) { - job_exp = pc_nextjobafter(sd) - sd->status.job_exp; - if (job_exp < 0) - job_exp = 0; - } - - sd->status.job_exp += job_exp; - if(sd->status.job_exp < 0) - sd->status.job_exp = 0; - - while(pc_checkjoblevelup(sd)) ; - - clif_updatestatus(sd,SP_JOBEXP); - - if(battle_config.disp_experience && !sd->noexp){ - sprintf(output, - "Experienced Gained Base:%d (%.2f%%) Job:%d (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100); - clif_disp_onlyself(sd,output,strlen(output)); - } - - return 0; -} - -/*========================================== - * base level側必要??値計算 - *------------------------------------------ - */ -int pc_nextbaseexp(struct map_session_data *sd) -{ - int i; - - nullpo_retr(0, sd); - - if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0) - return 0; - - if(sd->status.class_==0) i=0; - else if(sd->status.class_<=6) i=1; - else if(sd->status.class_<=22) i=2; - else if(sd->status.class_==23) i=3; - else if(sd->status.class_==4001) i=4; - else if(sd->status.class_<=4007) i=5; - else i=6; - - return exp_table[i][sd->status.base_level-1]; -} - -/*========================================== - * job level側必要??値計算 - *------------------------------------------ - */ -int pc_nextjobexp(struct map_session_data *sd) -{ - int i; - - nullpo_retr(0, sd); - - if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0) - return 0; - - if(sd->status.class_==0) i=7; - else if(sd->status.class_<=6) i=8; - else if(sd->status.class_<=22) i=9; - else if(sd->status.class_==23) i=10; - else if(sd->status.class_==4001) i=11; - else if(sd->status.class_<=4007) i=12; - else i=13; - - return exp_table[i][sd->status.job_level-1]; -} - -/*========================================== - * base level after next [Valaris] - *------------------------------------------ - */ -int pc_nextbaseafter(struct map_session_data *sd) -{ - int i; - - nullpo_retr(0, sd); - - if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0) - return 0; - - if(sd->status.class_==0) i=0; - else if(sd->status.class_<=6) i=1; - else if(sd->status.class_<=22) i=2; - else if(sd->status.class_==23) i=3; - else if(sd->status.class_==4001) i=4; - else if(sd->status.class_<=4007) i=5; - else i=6; - - return exp_table[i][sd->status.base_level]; -} - -/*========================================== - * job level after next [Valaris] - *------------------------------------------ - */ -int pc_nextjobafter(struct map_session_data *sd) -{ - int i; - - nullpo_retr(0, sd); - - if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0) - return 0; - - if(sd->status.class_==0) i=7; - else if(sd->status.class_<=6) i=8; - else if(sd->status.class_<=22) i=9; - else if(sd->status.class_==23) i=10; - else if(sd->status.class_==4001) i=11; - else if(sd->status.class_<=4007) i=12; - else i=13; - - return exp_table[i][sd->status.job_level]; -} -/*========================================== - - * 必要ステ?タスポイント計算 - *------------------------------------------ - */ -int pc_need_status_point(struct map_session_data *sd,int type) -{ - int val; - - nullpo_retr(-1, sd); - - if(type<SP_STR || type>SP_LUK) - return -1; - val = - type==SP_STR ? sd->status.str : - type==SP_AGI ? sd->status.agi : - type==SP_VIT ? sd->status.vit : - type==SP_INT ? sd->status.int_: - type==SP_DEX ? sd->status.dex : sd->status.luk; - - return (val+9)/10+1; -} - -/*========================================== - * 能力値成長 - *------------------------------------------ - */ -int pc_statusup(struct map_session_data *sd,int type) -{ - int max, need,val = 0; - - nullpo_retr(0, sd); - - max = (pc_calc_upper(sd->status.class_)==2) ? 80 : battle_config.max_parameter; - - need=pc_need_status_point(sd,type); - if(type<SP_STR || type>SP_LUK || need<0 || need>sd->status.status_point){ - clif_statusupack(sd,type,0,0); - return 1; - } - switch(type){ - case SP_STR: - if(sd->status.str >= max) { - clif_statusupack(sd,type,0,0); - return 1; - } - val= ++sd->status.str; - break; - case SP_AGI: - if(sd->status.agi >= max) { - clif_statusupack(sd,type,0,0); - return 1; - } - val= ++sd->status.agi; - break; - case SP_VIT: - if(sd->status.vit >= max) { - clif_statusupack(sd,type,0,0); - return 1; - } - val= ++sd->status.vit; - break; - case SP_INT: - if(sd->status.int_ >= max) { - clif_statusupack(sd,type,0,0); - return 1; - } - val= ++sd->status.int_; - break; - case SP_DEX: - if(sd->status.dex >= max) { - clif_statusupack(sd,type,0,0); - return 1; - } - val= ++sd->status.dex; - break; - case SP_LUK: - if(sd->status.luk >= max) { - clif_statusupack(sd,type,0,0); - return 1; - } - val= ++sd->status.luk; - break; - } - sd->status.status_point-=need; - if(need!=pc_need_status_point(sd,type)){ - clif_updatestatus(sd,type-SP_STR+SP_USTR); - } - clif_updatestatus(sd,SP_STATUSPOINT); - clif_updatestatus(sd,type); - status_calc_pc(sd,0); - clif_statusupack(sd,type,1,val); - - return 0; -} - -/*========================================== - * 能力値成長 - *------------------------------------------ - */ -int pc_statusup2(struct map_session_data *sd,int type,int val) -{ - nullpo_retr(0, sd); - - if(type<SP_STR || type>SP_LUK){ - clif_statusupack(sd,type,0,0); - return 1; - } - switch(type){ - case SP_STR: - if(sd->status.str + val >= battle_config.max_parameter) - val = battle_config.max_parameter; - else if(sd->status.str + val < 1) - val = 1; - else - val += sd->status.str; - sd->status.str = val; - break; - case SP_AGI: - if(sd->status.agi + val >= battle_config.max_parameter) - val = battle_config.max_parameter; - else if(sd->status.agi + val < 1) - val = 1; - else - val += sd->status.agi; - sd->status.agi = val; - break; - case SP_VIT: - if(sd->status.vit + val >= battle_config.max_parameter) - val = battle_config.max_parameter; - else if(sd->status.vit + val < 1) - val = 1; - else - val += sd->status.vit; - sd->status.vit = val; - break; - case SP_INT: - if(sd->status.int_ + val >= battle_config.max_parameter) - val = battle_config.max_parameter; - else if(sd->status.int_ + val < 1) - val = 1; - else - val += sd->status.int_; - sd->status.int_ = val; - break; - case SP_DEX: - if(sd->status.dex + val >= battle_config.max_parameter) - val = battle_config.max_parameter; - else if(sd->status.dex + val < 1) - val = 1; - else - val += sd->status.dex; - sd->status.dex = val; - break; - case SP_LUK: - if(sd->status.luk + val >= battle_config.max_parameter) - val = battle_config.max_parameter; - else if(sd->status.luk + val < 1) - val = 1; - else - val = sd->status.luk + val; - sd->status.luk = val; - break; - } - clif_updatestatus(sd,type-SP_STR+SP_USTR); - clif_updatestatus(sd,type); - status_calc_pc(sd,0); - clif_statusupack(sd,type,1,val); - - return 0; -} - -/*========================================== - * スキルポイント割り振り - *------------------------------------------ - */ -int pc_skillup(struct map_session_data *sd,int skill_num) -{ - nullpo_retr(0, sd); - - if( skill_num>=10000 ){ - guild_skillup(sd,skill_num,0); - return 0; - } - - if( sd->status.skill_point>0 && - sd->status.skill[skill_num].id!=0 && - //sd->status.skill[skill_num].lv < skill_get_max(skill_num) ) - celest - sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) ) - { - sd->status.skill[skill_num].lv++; - sd->status.skill_point--; - status_calc_pc(sd,0); - clif_skillup(sd,skill_num); - clif_updatestatus(sd,SP_SKILLPOINT); - clif_skillinfoblock(sd); - } - - return 0; -} - -/*========================================== - * /allskill - *------------------------------------------ - */ -int pc_allskillup(struct map_session_data *sd) -{ - int i,id; - int c=0, s=0; - //?生や養子の場合の元の職業を算出する - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - s_class = pc_calc_base_job(sd->status.class_); - c = s_class.job; - s = (s_class.upper==1) ? 1 : 0 ; //?生以外は通常のスキル? - - for(i=0;i<MAX_SKILL;i++){ - sd->status.skill[i].id=0; - if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、 - sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本?のlvに - sd->status.skill[i].flag=0; // flagは0にしておく - } - } - - if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){ - // 全てのスキル - for(i=1;i<158;i++) - sd->status.skill[i].lv=skill_get_max(i); - for(i=210;i<291;i++) - sd->status.skill[i].lv=skill_get_max(i); - for(i=304;i<338;i++){ - if(i==331) continue; - sd->status.skill[i].lv=skill_get_max(i); - } - for(i=355;i<411;i++) - sd->status.skill[i].lv=skill_get_max(i); - for(i=475;i<480;i++) - sd->status.skill[i].lv=skill_get_max(i); - } - else { - for(i=0;(id=skill_tree[s][c][i].id)>0;i++){ - if(sd->status.skill[id].id==0 && (!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn) ) { - sd->status.skill[id].id = id; // celest - // sd->status.skill[id].lv=skill_get_max(id); - sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_); // celest - } - } - } - status_calc_pc(sd,0); - - return 0; -} - -/*========================================== - * /resetlvl - *------------------------------------------ - */ -int pc_resetlvl(struct map_session_data* sd,int type) -{ - int i; - - nullpo_retr(0, sd); - - for(i=1;i<MAX_SKILL;i++){ - sd->status.skill[i].lv = 0; - } - - if(type == 1){ - sd->status.skill_point=0; - sd->status.base_level=1; - sd->status.job_level=1; - sd->status.base_exp=sd->status.base_exp=0; - sd->status.job_exp=sd->status.job_exp=0; - if(sd->status.option !=0) - sd->status.option = 0; - - sd->status.str=1; - sd->status.agi=1; - sd->status.vit=1; - sd->status.int_=1; - sd->status.dex=1; - sd->status.luk=1; - if(sd->status.class_ == 4001) - sd->status.status_point=100; // not 88 [celest] - // give platinum skills upon changing - pc_skill(sd,142,1,0); - pc_skill(sd,143,1,0); - } - - if(type == 2){ - sd->status.skill_point=0; - sd->status.base_level=1; - sd->status.job_level=1; - sd->status.base_exp=0; - sd->status.job_exp=0; - } - if(type == 3){ - sd->status.base_level=1; - sd->status.base_exp=0; - } - if(type == 4){ - sd->status.job_level=1; - sd->status.job_exp=0; - } - - clif_updatestatus(sd,SP_STATUSPOINT); - clif_updatestatus(sd,SP_STR); - clif_updatestatus(sd,SP_AGI); - clif_updatestatus(sd,SP_VIT); - clif_updatestatus(sd,SP_INT); - clif_updatestatus(sd,SP_DEX); - clif_updatestatus(sd,SP_LUK); - clif_updatestatus(sd,SP_BASELEVEL); - clif_updatestatus(sd,SP_JOBLEVEL); - clif_updatestatus(sd,SP_STATUSPOINT); - clif_updatestatus(sd,SP_NEXTBASEEXP); - clif_updatestatus(sd,SP_NEXTJOBEXP); - clif_updatestatus(sd,SP_SKILLPOINT); - - clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris - clif_updatestatus(sd,SP_UAGI); - clif_updatestatus(sd,SP_UVIT); - clif_updatestatus(sd,SP_UINT); - clif_updatestatus(sd,SP_UDEX); - clif_updatestatus(sd,SP_ULUK); // End Addition - - for(i=0;i<11;i++) { // unequip items that can't be equipped by base 1 [Valaris] - if(sd->equip_index[i] >= 0) - if(!pc_isequip(sd,sd->equip_index[i])) - pc_unequipitem(sd,sd->equip_index[i],2); - } - - clif_skillinfoblock(sd); - status_calc_pc(sd,0); - - return 0; -} -/*========================================== - * /resetstate - *------------------------------------------ - */ -int pc_resetstate(struct map_session_data* sd) -{ - #define sumsp(a) ((a)*((a-2)/10+2) - 5*((a-2)/10)*((a-2)/10) - 6*((a-2)/10) -2) -// int add=0; // Removed by Dexity - int lv; - - nullpo_retr(0, sd); - // allow it to just read the last entry [celest] - lv = sd->status.base_level < MAX_LEVEL ? sd->status.base_level : MAX_LEVEL - 1; - -// New statpoint table used here - Dexity - sd->status.status_point = statp[lv]; - if(sd->status.class_ >= 4001 && sd->status.class_ <= 4024) - sd->status.status_point+=52; // extra 52+48=100 stat points -// End addition - -// Removed by Dexity - old count -// add += sumsp(sd->status.str); -// add += sumsp(sd->status.agi); -// add += sumsp(sd->status.vit); -// add += sumsp(sd->status.int_); -// add += sumsp(sd->status.dex); -// add += sumsp(sd->status.luk); -// sd->status.status_point+=add; - - clif_updatestatus(sd,SP_STATUSPOINT); - - sd->status.str=1; - sd->status.agi=1; - sd->status.vit=1; - sd->status.int_=1; - sd->status.dex=1; - sd->status.luk=1; - - clif_updatestatus(sd,SP_STR); - clif_updatestatus(sd,SP_AGI); - clif_updatestatus(sd,SP_VIT); - clif_updatestatus(sd,SP_INT); - clif_updatestatus(sd,SP_DEX); - clif_updatestatus(sd,SP_LUK); - - clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris - clif_updatestatus(sd,SP_UAGI); - clif_updatestatus(sd,SP_UVIT); - clif_updatestatus(sd,SP_UINT); - clif_updatestatus(sd,SP_UDEX); - clif_updatestatus(sd,SP_ULUK); // End Addition - - status_calc_pc(sd,0); - - return 0; -} - -/*========================================== - * /resetskill - *------------------------------------------ - */ -int pc_resetskill(struct map_session_data* sd) -{ - int i,skill; - - nullpo_retr(0, sd); - - for(i=1;i<MAX_SKILL;i++){ - skill = ( i >= 10000 ) ? pc_checkskill(sd,i) : sd->status.skill[i].lv; - if( skill > 0) { - if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) { - if(!sd->status.skill[i].flag) - sd->status.skill_point += skill; - else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) { - sd->status.skill_point += (sd->status.skill[i].flag - 2); - } - sd->status.skill[i].lv = 0; - } - else if(battle_config.quest_skill_reset) - sd->status.skill[i].lv = 0; - sd->status.skill[i].flag = 0; - } else { - sd->status.skill[i].lv = 0; - } - } - clif_updatestatus(sd,SP_SKILLPOINT); - clif_skillinfoblock(sd); - status_calc_pc(sd,0); - - return 0; -} - -/*========================================== - * pcにダメ?ジを?える - *------------------------------------------ - */ -int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) -{ - int i=0,j=0; - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - //?生や養子の場合の元の職業を算出する - s_class = pc_calc_base_job(sd->status.class_); - // ?に死んでいたら無? - if(pc_isdead(sd)) - return 0; - // 座ってたら立ち上がる - if(pc_issit(sd)) { - pc_setstand(sd); - skill_gangsterparadise(sd,0); - } - - // ? いていたら足を止める - if (sd->sc_data) { - if (sd->sc_data[SC_BERSERK].timer != -1 || - sd->special_state.infinite_endure) - ; // do nothing - else if (sd->sc_data[SC_ENDURE].timer != -1 && (src != NULL && src->type == BL_MOB) && !map[sd->bl.m].flag.gvg) { - if ((--sd->sc_data[SC_ENDURE].val2) < 0) - status_change_end(&sd->bl, SC_ENDURE, -1); - } else pc_stop_walking(sd,3); - } - - // 演奏/ダンスの中? - if(damage > sd->status.max_hp>>2) - skill_stop_dancing(&sd->bl,0); - - sd->status.hp-=damage; - if(sd->status.pet_id > 0 && sd->pd && sd->petDB && battle_config.pet_damage_support) - pet_target_check(sd,src,1); - - if (sd->sc_data[SC_TRICKDEAD].timer != -1) - status_change_end(&sd->bl, SC_TRICKDEAD, -1); - if(sd->status.option&2) - status_change_end(&sd->bl, SC_HIDING, -1); - if(sd->status.option&4) - status_change_end(&sd->bl, SC_CLOAKING, -1); - if(sd->status.option&16384) - status_change_end(&sd->bl, SC_CHASEWALK, -1); - - if(sd->status.hp>0){ - // まだ生きているならHP更新 - clif_updatestatus(sd,SP_HP); - - //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 && - if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 && - (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 )) - // オ?トバ?サ?ク?動 - status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0); - - sd->canlog_tick = gettick(); - - if(sd->status.party_id>0) { // on-the-fly party hp updates [Valaris] - struct party *p=party_search(sd->status.party_id); - if(p!=NULL) clif_party_hp(p,sd); - } // end addition [Valaris] - - return 0; - } - sd->status.hp = 0; - //pc_setdead(sd); - if(sd->vender_id) - vending_closevending(sd); - - if(sd->status.pet_id > 0 && sd->pd) { - if(sd->petDB) { - sd->pet.intimate -= sd->petDB->die; - if(sd->pet.intimate < 0) - sd->pet.intimate = 0; - clif_send_petdata(sd,1,sd->pet.intimate); - } - } - - pc_stop_walking(sd,0); - skill_castcancel(&sd->bl,0); // 詠唱の中止 - clif_clearchar_area(&sd->bl,1); - pc_setdead(sd); - skill_unit_move(&sd->bl,gettick(),0); - if(sd->sc_data[SC_BLADESTOP].timer!=-1)//白刃は事前に解除 - status_change_end(&sd->bl,SC_BLADESTOP,-1); - pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter); //死にカウンタ?書き?み - status_change_clear(&sd->bl,0); // ステ?タス異常を解除する - clif_updatestatus(sd,SP_HP); - status_calc_pc(sd,0); - - if (src && src->type == BL_PC) { - struct map_session_data *ssd = (struct map_session_data *)src; - if (ssd) { - if (sd->state.event_death) - pc_setglobalreg(sd,"killerrid",(ssd->status.account_id)); - if (ssd->state.event_kill) { - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.kill_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCKillNPC - sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.kill_event_name); - ShowStatus(tmp_output); - } - } else { - sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.kill_event_name, sd->bl.id), script_config.kill_event_name); - ShowStatus(tmp_output); - } - } - } - } - - if (sd->state.event_death) { - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.die_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCDeathNPC - sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.die_event_name); - ShowStatus(tmp_output); - } - } else { - sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.die_event_name, sd->bl.id), script_config.die_event_name); - ShowStatus(tmp_output); - } - } - - if(battle_config.bone_drop==2 - || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)){ // ドクロドロップ - struct item item_tmp; - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid=7005; - item_tmp.identify=1; - item_tmp.card[0]=0x00fe; - item_tmp.card[1]=0; - *((unsigned long *)(&item_tmp.card[2]))=sd->char_id; /* キャラID */ - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - - // activate Steel body if a super novice dies at 99+% exp [celest] - if (s_class.job == 23) { - if ((i=pc_nextbaseexp(sd))<=0) - i=sd->status.base_exp; - if (i>0 && (j=sd->status.base_exp*1000/i)>=990 && j<=1000) - sd->state.snovice_flag = 4; - } - - for(i=0;i<5;i++) - if(sd->dev.val1[i]){ - status_change_end(&map_id2sd(sd->dev.val1[i])->bl,SC_DEVOTION,-1); - sd->dev.val1[i] = sd->dev.val2[i]=0; - } - - if(battle_config.death_penalty_type>0) { // changed penalty options, added death by player if pk_mode [Valaris] - if(sd->status.class_ != 0 && !map[sd->bl.m].flag.nopenalty && !map[sd->bl.m].flag.gvg && // only novices will recieve no penalty - !(sd->sc_count && sd->sc_data[SC_BABY].timer!=-1)) { - if(battle_config.death_penalty_type==1 && battle_config.death_penalty_base > 0) - sd->status.base_exp -= (int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000); - if(battle_config.pk_mode && src && src->type==BL_PC) - sd->status.base_exp -= (int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000); - else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_base > 0) { - if(pc_nextbaseexp(sd) > 0) - sd->status.base_exp -= (int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000); - if(battle_config.pk_mode && src && src->type==BL_PC) - sd->status.base_exp -= (int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000); - } - if(sd->status.base_exp < 0) - sd->status.base_exp = 0; - clif_updatestatus(sd,SP_BASEEXP); - - if(battle_config.death_penalty_type==1 && battle_config.death_penalty_job > 0) - sd->status.job_exp -= (int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000); - if(battle_config.pk_mode && src && src->type==BL_PC) - sd->status.job_exp -= (int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000); - else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_job > 0) { - if(pc_nextjobexp(sd) > 0) - sd->status.job_exp -= (int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000); - if(battle_config.pk_mode && src && src->type==BL_PC) - sd->status.job_exp -= (int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000); - } - if(sd->status.job_exp < 0) - sd->status.job_exp = 0; - clif_updatestatus(sd,SP_JOBEXP); - } - } - // monster level up [Valaris] - if(battle_config.mobs_level_up && src && src->type==BL_MOB) { - struct mob_data *md=(struct mob_data *)src; - if(md && md->target_id != 0 && md->target_id==sd->bl.id) { // reset target id when player dies - md->target_id=0; - mob_changestate(md,MS_WALK,0); - } - if(md && md->state.state!=MS_DEAD && md->level < 99) { - clif_misceffect(&md->bl,0); - md->level++; - md->hp+=(int) (sd->status.max_hp*.1); - } - } - - //ナイトメアモ?ドアイテムドロップ - if(map[sd->bl.m].flag.pvp_nightmaredrop){ // Moved this outside so it works when PVP isnt enabled and during pk mode [Ancyker] - for(j=0;j<MAX_DROP_PER_MAP;j++){ - int id = map[sd->bl.m].drop_list[j].drop_id; - int type = map[sd->bl.m].drop_list[j].drop_type; - int per = map[sd->bl.m].drop_list[j].drop_per; - if(id == 0) - continue; - if(id == -1){//ランダムドロップ - int eq_num=0,eq_n[MAX_INVENTORY]; - memset(eq_n,0,sizeof(eq_n)); - //先ず?備しているアイテム?をカウント - for(i=0;i<MAX_INVENTORY;i++){ - int k; - if( (type == 1 && !sd->status.inventory[i].equip) - || (type == 2 && sd->status.inventory[i].equip) - || type == 3){ - //InventoryIndexを格納 - for(k=0;k<MAX_INVENTORY;k++){ - if(eq_n[k] <= 0){ - eq_n[k]=i; - break; - } - } - eq_num++; - } - } - if(eq_num > 0){ - int n = eq_n[rand()%eq_num];//該?アイテムの中からランダム - if(rand()%10000 < per){ - if(sd->status.inventory[n].equip) - pc_unequipitem(sd,n,3); - pc_dropitem(sd,n,1); - } - } - } - else if(id > 0){ - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid == id//ItemIDが一致していて - && rand()%10000 < per//ドロップ率判定もOKで - && ((type == 1 && !sd->status.inventory[i].equip)//タイプ判定もOKならドロップ - || (type == 2 && sd->status.inventory[i].equip) - || type == 3) ){ - if(sd->status.inventory[i].equip) - pc_unequipitem(sd,i,3); - pc_dropitem(sd,i,1); - break; - } - } - } - } - } - // pvp - if( map[sd->bl.m].flag.pvp && !battle_config.pk_mode){ // disable certain pvp functions on pk_mode [Valaris] - //ランキング計算 - if(!map[sd->bl.m].flag.pvp_nocalcrank){ - sd->pvp_point-=5; - if(src && src->type==BL_PC ) - ((struct map_session_data *)src)->pvp_point++; - //} //fixed wrong '{' placement by Lupus - pc_setdead(sd); - } - // ?制送還 - if( sd->pvp_point < 0 ){ - sd->pvp_point=0; - pc_setstand(sd); - pc_setrestartvalue(sd,3); - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,0); - } - } - //GvG - if(map[sd->bl.m].flag.gvg){ - pc_setstand(sd); - pc_setrestartvalue(sd,3); - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,0); - } - - return 0; -} - -// -// script? 連 -// -/*========================================== - * script用PCステ?タス?み出し - *------------------------------------------ - */ -int pc_readparam(struct map_session_data *sd,int type) -{ - int val=0; - struct pc_base_job s_class; - - s_class = pc_calc_base_job(sd->status.class_); - - nullpo_retr(0, sd); - - switch(type){ - case SP_SKILLPOINT: - val= sd->status.skill_point; - break; - case SP_STATUSPOINT: - val= sd->status.status_point; - break; - case SP_ZENY: - val= sd->status.zeny; - break; - case SP_BASELEVEL: - val= sd->status.base_level; - break; - case SP_JOBLEVEL: - val= sd->status.job_level; - break; - case SP_CLASS: - if(val>=24 && val < 45) - val+=3978; - else - val= sd->status.class_; - break; - case SP_BASEJOB: - val= s_class.job; - break; - case SP_UPPER: - val= s_class.upper; - break; - case SP_SEX: - val= sd->sex; - break; - case SP_WEIGHT: - val= sd->weight; - break; - case SP_MAXWEIGHT: - val= sd->max_weight; - break; - case SP_BASEEXP: - val= sd->status.base_exp; - break; - case SP_JOBEXP: - val= sd->status.job_exp; - break; - case SP_NEXTBASEEXP: - val= pc_nextbaseexp(sd); - break; - case SP_NEXTJOBEXP: - val= pc_nextjobexp(sd); - break; - case SP_HP: - val= sd->status.hp; - break; - case SP_MAXHP: - val= sd->status.max_hp; - break; - case SP_SP: - val= sd->status.sp; - break; - case SP_MAXSP: - val= sd->status.max_sp; - break; - case SP_STR: - val= sd->status.str; - break; - case SP_AGI: - val= sd->status.agi; - break; - case SP_VIT: - val= sd->status.vit; - break; - case SP_INT: - val= sd->status.int_; - break; - case SP_DEX: - val= sd->status.dex; - break; - case SP_LUK: - val= sd->status.luk; - break; - case SP_KARMA: // celest - val = sd->status.karma; - break; - case SP_MANNER: - val = sd->status.manner; - break; - case SP_FAME: - val= sd->fame; - break; - } - - return val; -} - -/*========================================== - * script用PCステ?タス設定 - *------------------------------------------ - */ -int pc_setparam(struct map_session_data *sd,int type,int val) -{ - int i = 0,up_level = 50; - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - s_class = pc_calc_base_job(sd->status.class_); - - switch(type){ - case SP_BASELEVEL: - if (val > sd->status.base_level) { - for (i = 1; i <= (val - sd->status.base_level); i++) - sd->status.status_point += (sd->status.base_level + i + 14) / 5 ; - } - sd->status.base_level = val; - sd->status.base_exp = 0; - clif_updatestatus(sd, SP_BASELEVEL); - clif_updatestatus(sd, SP_NEXTBASEEXP); - clif_updatestatus(sd, SP_STATUSPOINT); - clif_updatestatus(sd, SP_BASEEXP); - status_calc_pc(sd, 0); - pc_heal(sd, sd->status.max_hp, sd->status.max_sp); - break; - case SP_JOBLEVEL: - if (s_class.job == 0) - up_level -= 40; - // super novices can go up to 99 [celest] - else if (s_class.job == 23) - up_level += 49; - else if (sd->status.class_ >= 4008 && sd->status.class_ <= 4022) - up_level += 20; - if (val >= sd->status.job_level) { - if (val > up_level)val = up_level; - sd->status.skill_point += (val-sd->status.job_level); - sd->status.job_level = val; - sd->status.job_exp = 0; - clif_updatestatus(sd, SP_JOBLEVEL); - clif_updatestatus(sd, SP_NEXTJOBEXP); - clif_updatestatus(sd, SP_JOBEXP); - clif_updatestatus(sd, SP_SKILLPOINT); - status_calc_pc(sd, 0); - clif_misceffect(&sd->bl, 1); - } else { - sd->status.job_level = val; - sd->status.job_exp = 0; - clif_updatestatus(sd, SP_JOBLEVEL); - clif_updatestatus(sd, SP_NEXTJOBEXP); - clif_updatestatus(sd, SP_JOBEXP); - status_calc_pc(sd, 0); - } - clif_updatestatus(sd,type); - break; - case SP_SKILLPOINT: - sd->status.skill_point = val; - break; - case SP_STATUSPOINT: - sd->status.status_point = val; - break; - case SP_ZENY: - if(val <= MAX_ZENY) { - // MAX_ZENY 以下なら代入 - sd->status.zeny = val; - } else { - if(sd->status.zeny > val) { - // Zeny が減少しているなら代入 - sd->status.zeny = val; - } else if(sd->status.zeny <= MAX_ZENY) { - // Zeny が増加していて、現在の値がMAX_ZENY 以下ならMAX_ZENY - sd->status.zeny = MAX_ZENY; - } else { - // Zeny が増加していて、現在の値がMAX_ZENY より下なら増加分を無視 - ; - } - } - break; - case SP_BASEEXP: - if(pc_nextbaseexp(sd) > 0) { - sd->status.base_exp = val; - if(sd->status.base_exp < 0) - sd->status.base_exp=0; - pc_checkbaselevelup(sd); - } - break; - case SP_JOBEXP: - if(pc_nextjobexp(sd) > 0) { - sd->status.job_exp = val; - if(sd->status.job_exp < 0) - sd->status.job_exp=0; - pc_checkjoblevelup(sd); - } - break; - case SP_SEX: - sd->sex = val; - break; - case SP_WEIGHT: - sd->weight = val; - break; - case SP_MAXWEIGHT: - sd->max_weight = val; - break; - case SP_HP: - sd->status.hp = val; - break; - case SP_MAXHP: - sd->status.max_hp = val; - break; - case SP_SP: - sd->status.sp = val; - break; - case SP_MAXSP: - sd->status.max_sp = val; - break; - case SP_STR: - sd->status.str = val; - break; - case SP_AGI: - sd->status.agi = val; - break; - case SP_VIT: - sd->status.vit = val; - break; - case SP_INT: - sd->status.int_ = val; - break; - case SP_DEX: - sd->status.dex = val; - break; - case SP_LUK: - sd->status.luk = val; - break; - case SP_KARMA: - sd->status.karma = val; - break; - case SP_MANNER: - sd->status.manner = val; - break; - case SP_FAME: - sd->fame = val; - break; - } - clif_updatestatus(sd,type); - - return 0; -} - -/*========================================== - * HP/SP回復 - *------------------------------------------ - */ -int pc_heal(struct map_session_data *sd,int hp,int sp) -{ -// if(battle_config.battle_log) -// printf("heal %d %d\n",hp,sp); - - nullpo_retr(0, sd); - - if(pc_checkoverhp(sd)) { - if(hp > 0) - hp = 0; - } - if(pc_checkoversp(sd)) { - if(sp > 0) - sp = 0; - } - - if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1) //バ?サ?ク中は回復させないらしい - return 0; - - if(hp+sd->status.hp>sd->status.max_hp) - hp=sd->status.max_hp-sd->status.hp; - if(sp+sd->status.sp>sd->status.max_sp) - sp=sd->status.max_sp-sd->status.sp; - sd->status.hp+=hp; - if(sd->status.hp <= 0) { - sd->status.hp = 0; - pc_damage(NULL,sd,1); - hp = 0; - } - sd->status.sp+=sp; - if(sd->status.sp <= 0) - sd->status.sp = 0; - if(hp) - clif_updatestatus(sd,SP_HP); - if(sp) - clif_updatestatus(sd,SP_SP); - - if(sd->status.party_id>0) { // on-the-fly party hp updates [Valaris] - struct party *p=party_search(sd->status.party_id); - if(p!=NULL) clif_party_hp(p,sd); - } // end addition [Valaris] - - return hp + sp; -} - -/*========================================== - * HP/SP回復 - *------------------------------------------ - */ -int pc_itemheal(struct map_session_data *sd,int hp,int sp) -{ - int bonus, type = 0; -// if(battle_config.battle_log) -// printf("heal %d %d\n",hp,sp); - - nullpo_retr(0, sd); - - if(sd->sc_count && sd->sc_data[SC_GOSPEL].timer!=-1) //バ?サ?ク中は回復させないらしい - return 0; - - if(sd->state.potionpitcher_flag) { - sd->potion_hp = hp; - sd->potion_sp = sp; - return 0; - } - - if(pc_checkoverhp(sd)) { - if(hp > 0) - hp = 0; - } - if(pc_checkoversp(sd)) { - if(sp > 0) - sp = 0; - } - - if (sd->itemid >= 501 && sd->itemid <= 505) - type = 1; // potions - else if (sd->itemid >= 507 && sd->itemid <= 510) - type = 2; // herbs - else if (sd->itemid >= 512 && sd->itemid <= 516) - type = 3; // fruits - else if (sd->itemid == 517 || sd->itemid == 528) - type = 4; // meat - else if (sd->itemid == 529 || sd->itemid == 530) - type = 5; // candy - else if (sd->itemid >= 531 && sd->itemid <= 534) - type = 6; // juice - else if (sd->itemid == 544 || sd->itemid == 551) - type = 7; // sashimi - - if(hp > 0) { - bonus = (sd->paramc[2]<<1) + 100 + pc_checkskill(sd,SM_RECOVERY)*10 - + pc_checkskill(sd,AM_LEARNINGPOTION)*5; - if (type > 0) - bonus += sd->itemhealrate[type - 1]; - if(bonus != 100) - hp = hp * bonus / 100; - } - if(sp > 0) { - bonus = (sd->paramc[3]<<1) + 100 + pc_checkskill(sd,MG_SRECOVERY)*10 - + pc_checkskill(sd,AM_LEARNINGPOTION)*5; - if(bonus != 100) - sp = sp * bonus / 100; - } - if(hp+sd->status.hp>sd->status.max_hp) - hp=sd->status.max_hp-sd->status.hp; - if(sp+sd->status.sp>sd->status.max_sp) - sp=sd->status.max_sp-sd->status.sp; - sd->status.hp+=hp; - if(sd->status.hp <= 0) { - sd->status.hp = 0; - pc_damage(NULL,sd,1); - hp = 0; - } - sd->status.sp+=sp; - if(sd->status.sp <= 0) - sd->status.sp = 0; - if(hp) - clif_updatestatus(sd,SP_HP); - if(sp) - clif_updatestatus(sd,SP_SP); - - return 0; -} - -/*========================================== - * HP/SP回復 - *------------------------------------------ - */ -int pc_percentheal(struct map_session_data *sd,int hp,int sp) -{ - nullpo_retr(0, sd); - - if(sd->state.potionpitcher_flag) { - sd->potion_per_hp = hp; - sd->potion_per_sp = sp; - return 0; - } - - if(pc_checkoverhp(sd)) { - if(hp > 0) - hp = 0; - } - if(pc_checkoversp(sd)) { - if(sp > 0) - sp = 0; - } - if(hp) { - if(hp >= 100) { - sd->status.hp = sd->status.max_hp; - } - else if(hp <= -100) { - sd->status.hp = 0; - pc_damage(NULL,sd,1); - } - else { - sd->status.hp += sd->status.max_hp*hp/100; - if(sd->status.hp > sd->status.max_hp) - sd->status.hp = sd->status.max_hp; - if(sd->status.hp <= 0) { - sd->status.hp = 0; - pc_damage(NULL,sd,1); - hp = 0; - } - } - } - if(sp) { - if(sp >= 100) { - sd->status.sp = sd->status.max_sp; - } - else if(sp <= -100) { - sd->status.sp = 0; - } - else { - sd->status.sp += sd->status.max_sp*sp/100; - if(sd->status.sp > sd->status.max_sp) - sd->status.sp = sd->status.max_sp; - if(sd->status.sp < 0) - sd->status.sp = 0; - } - } - if(hp) - clif_updatestatus(sd,SP_HP); - if(sp) - clif_updatestatus(sd,SP_SP); - - return 0; -} - -/*========================================== - * 職?更 - * 引? job 職業 0〜23 - * upper 通常 0, ?生 1, 養子 2, そのまま -1 - * Rewrote to make it tidider [Celest] - *------------------------------------------ - */ -int pc_jobchange(struct map_session_data *sd,int job, int upper) -{ - int i; - int b_class = 0; - //?生や養子の場合の元の職業を算出する - struct pc_base_job s_class = pc_calc_base_job(sd->status.class_); - - nullpo_retr(0, sd); - - if (upper < 0 || upper > 2) //現在?生かどうかを判?する - upper = s_class.upper; - - b_class = job; //通常職ならjobそのまんま - if (job < 23) { - if (upper == 1) - b_class += 4001; - else if (upper == 2) //養子に結婚はないけどどうせ次で蹴られるからいいや - b_class += 4023; - } else if (job == 23) { - if (upper == 1) //?生にスパノビは存在しないのでお?り - return 1; - else if (upper == 2) - b_class += 4022; - } else if (job > 23 && job < 69) { - b_class += 3977; - } else if ((job >= 69 && job < 4001) || (job > 4045)) - return 1; - - job = pc_calc_base_job2 (b_class); // check base class [celest] - - if((sd->status.sex == 0 && job == 19) || (sd->status.sex == 1 && job == 20) || - // not needed [celest] - //(sd->status.sex == 0 && job == 4020) || (sd->status.sex == 1 && job == 4021) || - job == 22 || sd->status.class_ == b_class) //♀はバ?ドになれない、♂はダンサ?になれない、結婚衣裳もお?り - return 1; - - // check if we are changing from 1st to 2nd job - if (job >= 7 && job <= 21) { - if (s_class.job > 0 && s_class.job < 7) - sd->change_level = sd->status.job_level; - else - sd->change_level = 40; - } - else - sd->change_level = 0; - - pc_setglobalreg (sd, "jobchange_level", sd->change_level); - - sd->status.class_ = sd->view_class = b_class; - - sd->status.job_level=1; - sd->status.job_exp=0; - clif_updatestatus(sd,SP_JOBLEVEL); - clif_updatestatus(sd,SP_JOBEXP); - clif_updatestatus(sd,SP_NEXTJOBEXP); - - for(i=0;i<11;i++) { - if(sd->equip_index[i] >= 0) - if(!pc_isequip(sd,sd->equip_index[i])) - pc_unequipitem(sd,sd->equip_index[i],2); // ?備外し - } - - clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); // move sprite update to prevent client crashes with incompatible equipment [Valaris] - if(sd->status.clothes_color > 0) - clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color); - if(battle_config.muting_players && sd->status.manner < 0) - clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner); - - status_calc_pc(sd,0); - pc_checkallowskill(sd); - pc_equiplookall(sd); - clif_equiplist(sd); - - if(pc_isriding(sd)) { // remove peco status if changing into invalid class [Valaris] - if(!(pc_checkskill(sd,KN_RIDING))) - pc_setoption(sd,sd->status.option|-0x0000); - if(pc_checkskill(sd,KN_RIDING)>0) - pc_setriding(sd); - } - - return 0; -} - -/*========================================== - * 見た目?更 - *------------------------------------------ - */ -int pc_equiplookall(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - -#if PACKETVER < 4 - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); -#else - clif_changelook(&sd->bl,LOOK_WEAPON,0); - clif_changelook(&sd->bl,LOOK_SHOES,0); -#endif - clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); - clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); - clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); - - return 0; -} - -/*========================================== - * 見た目?更 - *------------------------------------------ - */ -int pc_changelook(struct map_session_data *sd,int type,int val) -{ - nullpo_retr(0, sd); - - switch(type){ - case LOOK_HAIR: - sd->status.hair=val; - break; - case LOOK_WEAPON: - sd->status.weapon=val; - break; - case LOOK_HEAD_BOTTOM: - sd->status.head_bottom=val; - break; - case LOOK_HEAD_TOP: - sd->status.head_top=val; - break; - case LOOK_HEAD_MID: - sd->status.head_mid=val; - break; - case LOOK_HAIR_COLOR: - sd->status.hair_color=val; - break; - case LOOK_CLOTHES_COLOR: - sd->status.clothes_color=val; - break; - case LOOK_SHIELD: - sd->status.shield=val; - break; - case LOOK_SHOES: - break; - } - clif_changelook(&sd->bl,type,val); - - return 0; -} - -/*========================================== - * 付?品(鷹,ペコ,カ?ト)設定 - *------------------------------------------ - */ -int pc_setoption(struct map_session_data *sd,int type) -{ - nullpo_retr(0, sd); - - sd->status.option=type; - clif_changeoption(&sd->bl); - status_calc_pc(sd,0); - - return 0; -} - -/*========================================== - * カ?ト設定 - *------------------------------------------ - */ -int pc_setcart(struct map_session_data *sd,int type) -{ - int cart[6]={0x0000,0x0008,0x0080,0x0100,0x0200,0x0400}; - - nullpo_retr(0, sd); - - if(pc_checkskill(sd,MC_PUSHCART)>0){ // プッシュカ?トスキル所持 - if(!pc_iscarton(sd)){ // カ?トを付けていない - pc_setoption(sd,cart[type]); - clif_cart_itemlist(sd); - clif_cart_equiplist(sd); - clif_updatestatus(sd,SP_CARTINFO); - clif_status_change(&sd->bl,0x0c,0); - } - else{ - pc_setoption(sd,cart[type]); - } - } - - return 0; -} - -/*========================================== - * 鷹設定 - *------------------------------------------ - */ -int pc_setfalcon(struct map_session_data *sd) -{ - if(pc_checkskill(sd,HT_FALCON)>0){ // ファルコンマスタリ?スキル所持 - pc_setoption(sd,sd->status.option|0x0010); - } - - return 0; -} - -/*========================================== - * ペコペコ設定 - *------------------------------------------ - */ -int pc_setriding(struct map_session_data *sd) -{ - if(sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] - clif_displaymessage(sd->fd, "Cannot mount a Peco while in disguise."); - return 0; - } - - if((pc_checkskill(sd,KN_RIDING)>0)){ // ライディングスキル所持 - pc_setoption(sd,sd->status.option|0x0020); - - if(sd->status.class_==7) - sd->status.class_=sd->view_class=13; - - if(sd->status.class_==14) - sd->status.class_=sd->view_class=21; - - if(sd->status.class_==4008) - sd->status.class_=sd->view_class=4014; - - if(sd->status.class_==4015) - sd->status.class_=sd->view_class=4022; - } - - return 0; -} - -/*========================================== - * アイテムドロップ可不可判定 - *------------------------------------------ - */ -int pc_candrop(struct map_session_data *sd,int item_id) -{ - int level; - if((level=pc_isGM(sd))>0 && level < battle_config.gm_can_drop_lv) // search only once [Celest] - return 1; - return 0; -} - -/*========================================== - * script用??の値を?む - *------------------------------------------ - */ -int pc_readreg(struct map_session_data *sd,int reg) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<sd->reg_num;i++) - if(sd->reg[i].index==reg) - return sd->reg[i].data; - - return 0; -} -/*========================================== - * script用??の値を設定 - *------------------------------------------ - */ -int pc_setreg(struct map_session_data *sd,int reg,int val) -{ - int i; - - nullpo_retr(0, sd); - - for (i = 0; i < sd->reg_num; i++) { - if (sd->reg[i].index == reg){ - sd->reg[i].data = val; - return 0; - } - } - sd->reg_num++; - sd->reg = (struct script_reg *) aRealloc(sd->reg, sizeof(*(sd->reg)) * sd->reg_num); - sd->reg[i].index = reg; - sd->reg[i].data = val; - - return 0; -} - -/*========================================== - * script用文字列??の値を?む - *------------------------------------------ - */ -char *pc_readregstr(struct map_session_data *sd,int reg) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<sd->regstr_num;i++) - if(sd->regstr[i].index==reg) - return sd->regstr[i].data; - - return NULL; -} -/*========================================== - * script用文字列??の値を設定 - *------------------------------------------ - */ -int pc_setregstr(struct map_session_data *sd,int reg,char *str) -{ - int i; - - nullpo_retr(0, sd); - - if(strlen(str)+1 >= sizeof(sd->regstr[0].data)){ - printf("pc_setregstr: string too long !\n"); - return 0; - } - - for(i=0;i<sd->regstr_num;i++) - if(sd->regstr[i].index==reg){ - strcpy(sd->regstr[i].data,str); - return 0; - } - sd->regstr_num++; - sd->regstr = (struct script_regstr *) aRealloc(sd->regstr, sizeof(sd->regstr[0]) * sd->regstr_num); - if(sd->regstr==NULL){ - printf("out of memory : pc_setreg\n"); - exit(1); - } -/* memset(sd->reg + (sd->reg_num - 1) * sizeof(*(sd->reg)), 0, - sizeof(*(sd->reg))); -*/ - sd->regstr[i].index=reg; - strcpy(sd->regstr[i].data,str); - - return 0; -} - -/*========================================== - * script用グロ?バル??の値を?む - *------------------------------------------ - */ -int pc_readglobalreg(struct map_session_data *sd,char *reg) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<sd->status.global_reg_num;i++){ - if(strcmp(sd->status.global_reg[i].str,reg)==0) - return sd->status.global_reg[i].value; - } - - return 0; -} - -/*========================================== - * script用グロ?バル??の値を設定 - *------------------------------------------ - */ -int pc_setglobalreg(struct map_session_data *sd,char *reg,int val) -{ - int i; - - nullpo_retr(0, sd); - - //PC_DIE_COUNTERがスクリプトなどで?更された暫フ?理 - if(strcmp(reg,"PC_DIE_COUNTER") == 0 && sd->die_counter != val){ - sd->die_counter = val; - status_calc_pc(sd,0); - } else if(strcmp(reg,script_config.die_event_name) == 0){ - sd->state.event_death = val; - } else if(strcmp(reg,script_config.kill_event_name) == 0){ - sd->state.event_kill = val; - } else if(strcmp(reg,script_config.logout_event_name) == 0){ - sd->state.event_disconnect = val; - } - - if(val==0){ - for(i=0;i<sd->status.global_reg_num;i++){ - if(strcmp(sd->status.global_reg[i].str,reg)==0){ - sd->status.global_reg[i]=sd->status.global_reg[sd->status.global_reg_num-1]; - sd->status.global_reg_num--; - break; - } - } - return 0; - } - for(i=0;i<sd->status.global_reg_num;i++){ - if(strcmp(sd->status.global_reg[i].str,reg)==0){ - sd->status.global_reg[i].value=val; - return 0; - } - } - if(sd->status.global_reg_num<GLOBAL_REG_NUM){ - strcpy(sd->status.global_reg[i].str,reg); - sd->status.global_reg[i].value=val; - sd->status.global_reg_num++; - return 0; - } - if(battle_config.error_log) - printf("pc_setglobalreg : couldn't set %s (GLOBAL_REG_NUM = %d)\n", reg, GLOBAL_REG_NUM); - - return 1; -} - -/*========================================== - * script用アカウント??の値を?む - *------------------------------------------ - */ -int pc_readaccountreg(struct map_session_data *sd,char *reg) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<sd->status.account_reg_num;i++){ - if(strcmp(sd->status.account_reg[i].str,reg)==0) - return sd->status.account_reg[i].value; - } - - return 0; -} -/*========================================== - * script用アカウント??の値を設定 - *------------------------------------------ - */ -int pc_setaccountreg(struct map_session_data *sd,char *reg,int val) -{ - int i; - - nullpo_retr(0, sd); - - if (sd->status.account_reg_num == -1) { - if(battle_config.error_log) - printf("pc_setaccountreg : refusing to set until vars are received\n"); - return 1; - } - - if(val==0){ - for(i=0;i<sd->status.account_reg_num;i++){ - if(strcmp(sd->status.account_reg[i].str,reg)==0){ - sd->status.account_reg[i]=sd->status.account_reg[sd->status.account_reg_num-1]; - sd->status.account_reg_num--; - break; - } - } - intif_saveaccountreg(sd); - return 0; - } - for(i=0;i<sd->status.account_reg_num;i++){ - if(strcmp(sd->status.account_reg[i].str,reg)==0){ - sd->status.account_reg[i].value=val; - intif_saveaccountreg(sd); - return 0; - } - } - if(sd->status.account_reg_num<ACCOUNT_REG_NUM){ - strcpy(sd->status.account_reg[i].str,reg); - sd->status.account_reg[i].value=val; - sd->status.account_reg_num++; - intif_saveaccountreg(sd); - return 0; - } - if(battle_config.error_log) - printf("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %d)\n", reg, ACCOUNT_REG_NUM); - - return 1; -} -/*========================================== - * script用アカウント??2の値を?む - *------------------------------------------ - */ -int pc_readaccountreg2(struct map_session_data *sd,char *reg) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<sd->status.account_reg2_num;i++){ - if(strcmp(sd->status.account_reg2[i].str,reg)==0) - return sd->status.account_reg2[i].value; - } - - return 0; -} -/*========================================== - * script用アカウント??2の値を設定 - *------------------------------------------ - */ -int pc_setaccountreg2(struct map_session_data *sd,char *reg,int val) -{ - int i; - - nullpo_retr(1, sd); - - if(val==0){ - for(i=0;i<sd->status.account_reg2_num;i++){ - if(strcmp(sd->status.account_reg2[i].str,reg)==0){ - sd->status.account_reg2[i]=sd->status.account_reg2[sd->status.account_reg2_num-1]; - sd->status.account_reg2_num--; - break; - } - } - chrif_saveaccountreg2(sd); - return 0; - } - for(i=0;i<sd->status.account_reg2_num;i++){ - if(strcmp(sd->status.account_reg2[i].str,reg)==0){ - sd->status.account_reg2[i].value=val; - chrif_saveaccountreg2(sd); - return 0; - } - } - if(sd->status.account_reg2_num<ACCOUNT_REG2_NUM){ - strcpy(sd->status.account_reg2[i].str,reg); - sd->status.account_reg2[i].value=val; - sd->status.account_reg2_num++; - chrif_saveaccountreg2(sd); - return 0; - } - if(battle_config.error_log) - printf("pc_setaccountreg2 : couldn't set %s (ACCOUNT_REG2_NUM = %d)\n", reg, ACCOUNT_REG2_NUM); - - return 1; -} - -/*========================================== - * イベントタイマ??理 - *------------------------------------------ - */ -int pc_eventtimer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd=map_id2sd(id); - char *p = (char *)data; - int i; - if(sd==NULL) - return 0; - - for(i=0;i<MAX_EVENTTIMER;i++){ - if( sd->eventtimer[i]==tid ){ - sd->eventtimer[i]=-1; - npc_event(sd,p,0); - break; - } - } - aFree(p); - if(i==MAX_EVENTTIMER) { - if(battle_config.error_log) - printf("pc_eventtimer: no such event timer\n"); - } - - return 0; -} - -/*========================================== - * イベントタイマ?追加 - *------------------------------------------ - */ -int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<MAX_EVENTTIMER;i++) - if( sd->eventtimer[i]==-1 ) - break; - if(i<MAX_EVENTTIMER){ - char *evname=strdup(name); - //char *evname=(char *)aMallocA((strlen(name)+1)*sizeof(char)); - //memcpy(evname,name,(strlen(name)+1)); - sd->eventtimer[i]=add_timer(gettick()+tick, - pc_eventtimer,sd->bl.id,(int)evname); - sd->eventcount++; - } - - return 0; -} - -/*========================================== - * イベントタイマ?削除 - *------------------------------------------ - */ -int pc_deleventtimer(struct map_session_data *sd,const char *name) -{ - int i; - - nullpo_retr(0, sd); - - if (sd->eventcount <= 0) - return 0; - - for(i=0;i<MAX_EVENTTIMER;i++) - if( sd->eventtimer[i]!=-1 ) { - char *p = (char *)(get_timer(sd->eventtimer[i])->data); - if(strcmp(p, name)==0) { - delete_timer(sd->eventtimer[i],pc_eventtimer); - sd->eventtimer[i]=-1; - sd->eventcount--; - aFree(p); - break; - } - } - - return 0; -} - -/*========================================== - * イベントタイマ?カウント値追加 - *------------------------------------------ - */ -int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick) -{ - int i; - - nullpo_retr(0, sd); - - for(i=0;i<MAX_EVENTTIMER;i++) - if( sd->eventtimer[i]!=-1 && strcmp( - (char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){ - addtick_timer(sd->eventtimer[i],tick); - break; - } - - return 0; -} - -/*========================================== - * イベントタイマ?全削除 - *------------------------------------------ - */ -int pc_cleareventtimer(struct map_session_data *sd) -{ - int i; - - nullpo_retr(0, sd); - - if (sd->eventcount <= 0) - return 0; - - for(i=0;i<MAX_EVENTTIMER;i++) - if( sd->eventtimer[i]!=-1 ){ - char *p = (char *)(get_timer(sd->eventtimer[i])->data); - delete_timer(sd->eventtimer[i],pc_eventtimer); - sd->eventtimer[i]=-1; - aFree(p); - } - - return 0; -} - -// -// ? 備物 -// -/*========================================== - * アイテムを?備する - *------------------------------------------ - */ -int pc_equipitem(struct map_session_data *sd,int n,int pos) -{ - int i,nameid, arrow; - struct item_data *id; - //?生や養子の場合の元の職業を算出する - - nullpo_retr(0, sd); - - nameid = sd->status.inventory[n].nameid; - id = sd->inventory_data[n]; - pos = pc_equippoint(sd,n); - if(battle_config.battle_log) - printf("equip %d(%d) %x:%x\n",nameid,n,id->equip,pos); - if(!pc_isequip(sd,n) || !pos || sd->status.inventory[n].attribute==1 ) { // [Valaris] - clif_equipitemack(sd,n,0,0); // fail - return 0; - } - -// -- moonsoul (if player is berserk then cannot equip) -// - if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1){ - clif_equipitemack(sd,n,0,0); // fail - return 0; - } - - if(pos==0x88){ // アクセサリ用例外?理 - int epor=0; - if(sd->equip_index[0] >= 0) - epor |= sd->status.inventory[sd->equip_index[0]].equip; - if(sd->equip_index[1] >= 0) - epor |= sd->status.inventory[sd->equip_index[1]].equip; - epor &= 0x88; - pos = epor == 0x08 ? 0x80 : 0x08; - } - - // 二刀流?理 - if ((pos==0x22) // 一?、?備要求箇所が二刀流武器かチェックする - && (id->equip==2) // ? 手武器 - && (pc_checkskill(sd, AS_LEFT) > 0 || pc_calc_base_job2(sd->status.class_) == 12) ) // 左手修?有 - { - int tpos=0; - if(sd->equip_index[8] >= 0) - tpos |= sd->status.inventory[sd->equip_index[8]].equip; - if(sd->equip_index[9] >= 0) - tpos |= sd->status.inventory[sd->equip_index[9]].equip; - tpos &= 0x02; - pos = tpos == 0x02 ? 0x20 : 0x02; - } - - arrow=pc_search_inventory(sd,pc_checkequip(sd,9)); // Added by RoVeRT - for(i=0;i<11;i++) { - if(sd->equip_index[i] >= 0 && sd->status.inventory[sd->equip_index[i]].equip&pos) { - pc_unequipitem(sd,sd->equip_index[i],2); - } - } - // 弓矢?備 - if(pos==0x8000){ - clif_arrowequip(sd,n); - clif_arrow_fail(sd,3); // 3=矢が?備できました - } - else - clif_equipitemack(sd,n,pos,1); - - for(i=0;i<11;i++) { - if(pos & equip_pos[i]) - sd->equip_index[i] = n; - } - sd->status.inventory[n].equip=pos; - - if(sd->status.inventory[n].equip & 0x0002) { - if(sd->inventory_data[n]) - sd->weapontype1 = sd->inventory_data[n]->look; - else - sd->weapontype1 = 0; - pc_calcweapontype(sd); - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - } - if(sd->status.inventory[n].equip & 0x0020) { - if(sd->inventory_data[n]) { - if(sd->inventory_data[n]->type == 4) { - sd->status.shield = 0; - if(sd->status.inventory[n].equip == 0x0020) - sd->weapontype2 = sd->inventory_data[n]->look; - else - sd->weapontype2 = 0; - } - else if(sd->inventory_data[n]->type == 5) { - sd->status.shield = sd->inventory_data[n]->look; - sd->weapontype2 = 0; - } - } - else - sd->status.shield = sd->weapontype2 = 0; - pc_calcweapontype(sd); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); - } - if(sd->status.inventory[n].equip & 0x0001) { - if(sd->inventory_data[n]) - sd->status.head_bottom = sd->inventory_data[n]->look; - else - sd->status.head_bottom = 0; - clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); - } - if(sd->status.inventory[n].equip & 0x0100) { - if(sd->inventory_data[n]) - sd->status.head_top = sd->inventory_data[n]->look; - else - sd->status.head_top = 0; - clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); - } - if(sd->status.inventory[n].equip & 0x0200) { - if(sd->inventory_data[n]) - sd->status.head_mid = sd->inventory_data[n]->look; - else - sd->status.head_mid = 0; - clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); - } - if(sd->status.inventory[n].equip & 0x0040) - clif_changelook(&sd->bl,LOOK_SHOES,0); - - pc_checkallowskill(sd); // ?備品でスキルか解除されるかチェック - if (itemdb_look(sd->status.inventory[n].nameid) == 11 && (arrow >= 0)){ // Added by RoVeRT - clif_arrowequip(sd,arrow); - sd->status.inventory[arrow].equip=32768; - } - status_calc_pc(sd,0); - - if(sd->special_state.infinite_endure) { - if(sd->sc_data[SC_ENDURE].timer == -1) - status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0); - } - else { - if(sd->sc_count && sd->sc_data[SC_ENDURE].timer != -1 && sd->sc_data[SC_ENDURE].val2) - status_change_end(&sd->bl,SC_ENDURE,-1); - } - - if(sd->sc_count) { - if (sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele)) - status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1); - if(sd->sc_data[SC_DANCING].timer!=-1 && (sd->status.weapon != 13 && sd->status.weapon !=14)) - skill_stop_dancing(&sd->bl,0); - } - - return 0; -} - -/*========================================== - * ? 備した物を外す - * type: - * 0 - only unequip - * 1 - calculate status after unequipping - * 2 - force unequip - *------------------------------------------ - */ -int pc_unequipitem(struct map_session_data *sd,int n,int flag) -{ - short hp = 0, sp = 0; - nullpo_retr(0, sd); - -// -- moonsoul (if player is berserk then cannot unequip) -// - if(flag<2 && sd->sc_count && (sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1)){ - clif_unequipitemack(sd,n,0,0); - return 0; - } - - if(battle_config.battle_log) - printf("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip); - if(sd->status.inventory[n].equip){ - int i; - for(i=0;i<11;i++) { - if(sd->status.inventory[n].equip & equip_pos[i]) { - sd->equip_index[i] = -1; - if(sd->unequip_losehp[i] > 0) { - hp += sd->unequip_losehp[i]; - sd->unequip_losehp[i] = 0; - } - if(sd->unequip_losesp[i] > 0) { - sp += sd->unequip_losesp[i]; - sd->unequip_losesp[i] = 0; - } - } - } - if(sd->status.inventory[n].equip & 0x0002) { - sd->weapontype1 = 0; - sd->status.weapon = sd->weapontype2; - pc_calcweapontype(sd); - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - } - if(sd->status.inventory[n].equip & 0x0020) { - sd->status.shield = sd->weapontype2 = 0; - pc_calcweapontype(sd); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); - } - if(sd->status.inventory[n].equip & 0x0001) { - sd->status.head_bottom = 0; - clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); - } - if(sd->status.inventory[n].equip & 0x0100) { - sd->status.head_top = 0; - clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); - } - if(sd->status.inventory[n].equip & 0x0200) { - sd->status.head_mid = 0; - clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); - } - if(sd->status.inventory[n].equip & 0x0040) - clif_changelook(&sd->bl,LOOK_SHOES,0); - - if(sd->sc_count) { - if (sd->sc_data[SC_BROKNWEAPON].timer != -1 && sd->status.inventory[n].equip & 0x0002 && - sd->status.inventory[n].attribute == 1) - status_change_end(&sd->bl,SC_BROKNWEAPON,-1); - if(sd->sc_data[SC_BROKNARMOR].timer != -1 && sd->status.inventory[n].equip & 0x0010 && - sd->status.inventory[n].attribute == 1) - status_change_end(&sd->bl,SC_BROKNARMOR,-1); - } - - clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1); - sd->status.inventory[n].equip=0; - if(flag&1) - pc_checkallowskill(sd); - if(sd->weapontype1 == 0 && sd->weapontype2 == 0) - skill_enchant_elemental_end(&sd->bl,-1); //武器持ち誓えは無?件で?性付?解除 - } else { - clif_unequipitemack(sd,n,0,0); - } - - if(flag&1) { - status_calc_pc(sd,0); - if(sd->sc_count && sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele)) - status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1); - } - - if (hp > 0 || sp > 0) { - if (hp > sd->status.hp) - hp = sd->status.hp; - if (sp > sd->status.sp) - sp = sd->status.sp; - pc_heal(sd,-hp,-sp); - } - - return 0; -} - -/*========================================== - * アイテムのindex番?を詰めたり - * ? 備品の?備可能チェックを行なう - *------------------------------------------ - */ -int pc_checkitem(struct map_session_data *sd) -{ - int i,j,k,id,calc_flag = 0; - struct item_data *it=NULL; - - nullpo_retr(0, sd); - - // 所持品空き詰め - for(i=j=0;i<MAX_INVENTORY;i++){ - if( (id=sd->status.inventory[i].nameid)==0) - continue; - if( battle_config.item_check && !itemdb_available(id) ){ - if(battle_config.error_log) - printf("illeagal item id %d in %d[%s] inventory.\n",id,sd->bl.id,sd->status.name); - pc_delitem(sd,i,sd->status.inventory[i].amount,3); - continue; - } - if(i>j){ - memcpy(&sd->status.inventory[j],&sd->status.inventory[i],sizeof(struct item)); - sd->inventory_data[j] = sd->inventory_data[i]; - } - j++; - } - if(j < MAX_INVENTORY) - memset(&sd->status.inventory[j],0,sizeof(struct item)*(MAX_INVENTORY-j)); - for(k=j;k<MAX_INVENTORY;k++) - sd->inventory_data[k] = NULL; - - // カ?ト?空き詰め - for(i=j=0;i<MAX_CART;i++){ - if( (id=sd->status.cart[i].nameid)==0 ) - continue; - if( battle_config.item_check && !itemdb_available(id) ){ - if(battle_config.error_log) - printf("illeagal item id %d in %d[%s] cart.\n",id,sd->bl.id,sd->status.name); - pc_cart_delitem(sd,i,sd->status.cart[i].amount,1); - continue; - } - if(i>j){ - memcpy(&sd->status.cart[j],&sd->status.cart[i],sizeof(struct item)); - } - j++; - } - if(j < MAX_CART) - memset(&sd->status.cart[j],0,sizeof(struct item)*(MAX_CART-j)); - - // ? 備位置チェック - - for(i=0;i<MAX_INVENTORY;i++){ - - it=sd->inventory_data[i]; - - if(sd->status.inventory[i].nameid==0) - continue; - if(sd->status.inventory[i].equip & ~pc_equippoint(sd,i)) { - sd->status.inventory[i].equip=0; - calc_flag = 1; - } - //?備制限チェック - if(sd->status.inventory[i].equip && map[sd->bl.m].flag.pvp && (it->flag.no_equip&1)){//PVP check for forbiden items. optimized by [Lupus] - sd->status.inventory[i].equip=0; - calc_flag = 1; - }else if(sd->status.inventory[i].equip && map[sd->bl.m].flag.gvg && (it->flag.no_equip>1)){//GvG optimized by [Lupus] - sd->status.inventory[i].equip=0; - calc_flag = 1; - } - } - - pc_setequipindex(sd); - if(calc_flag) - status_calc_pc(sd,2); - - return 0; -} - -int pc_checkoverhp(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - if(sd->status.hp == sd->status.max_hp) - return 1; - if(sd->status.hp > sd->status.max_hp) { - sd->status.hp = sd->status.max_hp; - clif_updatestatus(sd,SP_HP); - return 2; - } - - return 0; -} - -int pc_checkoversp(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - if(sd->status.sp == sd->status.max_sp) - return 1; - if(sd->status.sp > sd->status.max_sp) { - sd->status.sp = sd->status.max_sp; - clif_updatestatus(sd,SP_SP); - return 2; - } - - return 0; -} - -/*========================================== - * PVP順位計算用(foreachinarea) - *------------------------------------------ - */ -int pc_calc_pvprank_sub(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd1,*sd2=NULL; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd1=(struct map_session_data *)bl); - nullpo_retr(0, sd2=va_arg(ap,struct map_session_data *)); - - if( sd1->pvp_point > sd2->pvp_point ) - sd2->pvp_rank++; - return 0; -} -/*========================================== - * PVP順位計算 - *------------------------------------------ - */ -int pc_calc_pvprank(struct map_session_data *sd) -{ - int old; - struct map_data *m; - - nullpo_retr(0, sd); - nullpo_retr(0, m=&map[sd->bl.m]); - - old=sd->pvp_rank; - - if( !(m->flag.pvp) ) - return 0; - sd->pvp_rank=1; - map_foreachinarea(pc_calc_pvprank_sub,sd->bl.m,0,0,m->xs,m->ys,BL_PC,sd); - if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users) - clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users,0); - return sd->pvp_rank; -} -/*========================================== - * PVP順位計算(timer) - *------------------------------------------ - */ -int pc_calc_pvprank_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd=NULL; - if(battle_config.pk_mode) // disable pvp ranking if pk_mode on [Valaris] - return 0; - - sd=map_id2sd(id); - if(sd==NULL) - return 0; - sd->pvp_timer=-1; - if( pc_calc_pvprank(sd)>0 ) - sd->pvp_timer=add_timer( - gettick()+PVP_CALCRANK_INTERVAL, - pc_calc_pvprank_timer,id,data); - return 0; -} - -/*========================================== - * sdは結婚しているか(?婚の場合は相方のchar_idを返す) - *------------------------------------------ - */ -int pc_ismarried(struct map_session_data *sd) -{ - if(sd == NULL) - return -1; - if(sd->status.partner_id > 0) - return sd->status.partner_id; - else - return 0; -} -/*========================================== - * sdがdstsdと結婚(dstsd→sdの結婚?理も同暫ノ行う) - *------------------------------------------ - */ -int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd) -{ - if(sd == NULL || dstsd == NULL || sd->status.partner_id > 0 || dstsd->status.partner_id > 0 || pc_calc_upper(sd->status.class_)==2) - return -1; - sd->status.partner_id=dstsd->status.char_id; - dstsd->status.partner_id=sd->status.char_id; - return 0; -} - -/*========================================== - * sdが離婚(相手はsd->status.partner_idに依る)(相手も同暫ノ離婚?結婚指輪自動?奪) - *------------------------------------------ - */ -int pc_divorce(struct map_session_data *sd) -{ - struct map_session_data *p_sd=NULL; - if(sd == NULL || !pc_ismarried(sd)) - return -1; - - if( (p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) !=NULL){ - int i; - if(p_sd->status.partner_id != sd->status.char_id || sd->status.partner_id != p_sd->status.char_id){ - printf("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n",sd->status.partner_id,p_sd->status.partner_id); - return -1; - } - sd->status.partner_id=0; - p_sd->status.partner_id=0; - for(i=0;i<MAX_INVENTORY;i++) - if(sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) - pc_delitem(sd,i,1,0); - for(i=0;i<MAX_INVENTORY;i++) - if(p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F) - pc_delitem(p_sd,i,1,0); - - }else{ - printf("pc_divorce: p_sd nullpo\n"); - return -1; - } - return 0; -} - -/*========================================== - * sd - father dstsd - mother jasd - child - */ -int pc_adoption(struct map_session_data *sd,struct map_session_data *dstsd, struct map_session_data *jasd) -{ - int j; - if(sd == NULL || dstsd == NULL || jasd == NULL || sd->status.partner_id <= 0 || dstsd->status.partner_id <= 0 || sd->status.partner_id != dstsd->status.char_id || dstsd->status.partner_id != sd->status.char_id || sd->status.child > 0 || dstsd->status.child || jasd->status.father > 0 || jasd->status.mother > 0) - return -1; - jasd->status.father=sd->status.char_id; - jasd->status.mother=dstsd->status.char_id; - sd->status.child=jasd->status.char_id; - dstsd->status.child=jasd->status.char_id; - for (j=0; j < MAX_INVENTORY; j++) { - if(jasd->status.inventory[j].nameid>0 && jasd->status.inventory[j].equip!=0) - pc_unequipitem(jasd, j, 3); - } - if (pc_jobchange(jasd, 4023, 0) == 0) - clif_displaymessage(jasd->fd, msg_table[12]); // Your job has been changed. - else { - clif_displaymessage(jasd->fd, msg_table[155]); // Impossible to change your job. - return -1; - } - return 0; -} - -/*========================================== - * sdの相方のmap_session_dataを返す - *------------------------------------------ - */ -struct map_session_data *pc_get_partner(struct map_session_data *sd) -{ - //struct map_session_data *p_sd = NULL; - //char *nick; - //if(sd == NULL || !pc_ismarried(sd)) - // return NULL; - //nick=map_charid2nick(sd->status.partner_id); - //if (nick==NULL) - // return NULL; - //if((p_sd=map_nick2sd(nick)) == NULL ) - // return NULL; - - if (sd && pc_ismarried(sd)) - // charid2sd returns NULL if not found - return map_charid2sd(sd->status.partner_id); - - return NULL; -} - -struct map_session_data *pc_get_father (struct map_session_data *sd) -{ - if (sd && pc_calc_upper(sd->status.class_) == 2 && sd->status.father > 0) - // charid2sd returns NULL if not found - return map_charid2sd(sd->status.father); - - return NULL; -} - -struct map_session_data *pc_get_mother (struct map_session_data *sd) -{ - if (sd && pc_calc_upper(sd->status.class_) == 2 && sd->status.mother > 0) - // charid2sd returns NULL if not found - return map_charid2sd(sd->status.mother); - - return NULL; -} - -struct map_session_data *pc_get_child (struct map_session_data *sd) -{ - if (sd && pc_ismarried(sd) && sd->status.child > 0) - // charid2sd returns NULL if not found - return map_charid2sd(sd->status.child); - - return NULL; -} - -// -// 自然回復物 -// -/*========================================== - * SP回復量計算 - *------------------------------------------ - */ -static int natural_heal_tick,natural_heal_prev_tick,natural_heal_diff_tick; -static int pc_spheal(struct map_session_data *sd) -{ - int a, skill; - struct guild_castle *gc = NULL; - - nullpo_retr(0, sd); - - a = natural_heal_diff_tick; - if(pc_issit(sd)) a += a; - if (sd->sc_count) { - if (sd->sc_data[SC_MAGNIFICAT].timer!=-1) // マグニフィカ?ト - a += a; - if (sd->sc_data[SC_REGENERATION].timer != -1) - a *= sd->sc_data[SC_REGENERATION].val1; - } - if((skill = pc_checkskill(sd,HP_MEDITATIO)) > 0) //Increase natural SP regen with Meditatio [DracoRPG] - a += a*skill*3/100; - - gc=guild_mapname2gc(sd->mapname); // Increased guild castle regen [Valaris] - if(gc) { - struct guild *g; - g=guild_search(sd->status.guild_id); - if(g && g->guild_id == gc->guild_id) - a += a; - } // end addition [Valaris] - - return a; -} - -/*========================================== - * HP回復量計算 - *------------------------------------------ - */ -static int pc_hpheal(struct map_session_data *sd) -{ - int a; - struct guild_castle *gc; - - nullpo_retr(0, sd); - - a = natural_heal_diff_tick; - if(pc_issit(sd)) a += a; - if (sd->sc_count) { - if( sd->sc_data[SC_MAGNIFICAT].timer!=-1 ) // Modified by RoVeRT - a += a; - if (sd->sc_data[SC_REGENERATION].timer != -1) - a *= sd->sc_data[SC_REGENERATION].val1; - } - gc=guild_mapname2gc(sd->mapname); // Increased guild castle regen [Valaris] - if(gc) { - struct guild *g; - g=guild_search(sd->status.guild_id); - if(g && g->guild_id == gc->guild_id) - a += a; - } // end addition [Valaris] - - return a; -} - -static int pc_natural_heal_hp(struct map_session_data *sd) -{ - int bhp; - int inc_num,bonus,skill,hp_flag; - - nullpo_retr(0, sd); - - if (sd->sc_count && sd->sc_data[SC_TRICKDEAD].timer != -1) // Modified by RoVeRT - return 0; - - if (sd->no_regen & 1) - return 0; - - if(pc_checkoverhp(sd)) { - sd->hp_sub = sd->inchealhptick = 0; - return 0; - } - - bhp=sd->status.hp; - hp_flag = (pc_checkskill(sd,SM_MOVINGRECOVERY) > 0 && sd->walktimer != -1); - - if(sd->walktimer == -1) { - inc_num = pc_hpheal(sd); - if(sd->sc_data[SC_TENSIONRELAX].timer!=-1 ){ // テンションリラックス - sd->hp_sub += 2*inc_num; - sd->inchealhptick += 3*natural_heal_diff_tick; - } else { - sd->hp_sub += inc_num; - sd->inchealhptick += natural_heal_diff_tick; - } - } - else if(hp_flag) { - inc_num = pc_hpheal(sd); - sd->hp_sub += inc_num; - sd->inchealhptick = 0; - } - else { - sd->hp_sub = sd->inchealhptick = 0; - return 0; - } - - if(sd->hp_sub >= battle_config.natural_healhp_interval) { - bonus = sd->nhealhp; - if(hp_flag) { - bonus >>= 2; - if(bonus <= 0) bonus = 1; - } - while(sd->hp_sub >= battle_config.natural_healhp_interval) { - sd->hp_sub -= battle_config.natural_healhp_interval; - if(sd->status.hp + bonus <= sd->status.max_hp) - sd->status.hp += bonus; - else { - sd->status.hp = sd->status.max_hp; - sd->hp_sub = sd->inchealhptick = 0; - } - } - } - if(bhp!=sd->status.hp) - clif_updatestatus(sd,SP_HP); - - if(sd->nshealhp > 0) { - if(sd->inchealhptick >= battle_config.natural_heal_skill_interval && sd->status.hp < sd->status.max_hp) { - bonus = sd->nshealhp; - while(sd->inchealhptick >= battle_config.natural_heal_skill_interval) { - sd->inchealhptick -= battle_config.natural_heal_skill_interval; - if(sd->status.hp + bonus <= sd->status.max_hp) - sd->status.hp += bonus; - else { - bonus = sd->status.max_hp - sd->status.hp; - sd->status.hp = sd->status.max_hp; - sd->hp_sub = sd->inchealhptick = 0; - } - clif_heal(sd->fd,SP_HP,bonus); - } - } - } - else sd->inchealhptick = 0; - - return 0; - - if(sd->sc_count && sd->sc_data[SC_APPLEIDUN].timer!=-1 && sd->sc_data[SC_BERSERK].timer==-1) { // Apple of Idun - if(sd->inchealhptick >= 6000 && sd->status.hp < sd->status.max_hp) { - bonus = skill*20; - while(sd->inchealhptick >= 6000) { - sd->inchealhptick -= 6000; - if(sd->status.hp + bonus <= sd->status.max_hp) - sd->status.hp += bonus; - else { - bonus = sd->status.max_hp - sd->status.hp; - sd->status.hp = sd->status.max_hp; - sd->hp_sub = sd->inchealhptick = 0; - } - clif_heal(sd->fd,SP_HP,bonus); - } - } - } - else sd->inchealhptick = 0; - - return 0; -} - -static int pc_natural_heal_sp(struct map_session_data *sd) -{ - int bsp; - int inc_num,bonus; - - nullpo_retr(0, sd); - - if (sd->sc_count && (sd->sc_data[SC_TRICKDEAD].timer != -1 || // Modified by RoVeRT - sd->sc_data[SC_BERSERK].timer != -1 || - sd->sc_data[SC_BLEEDING].timer != -1)) - return 0; - - if (sd->no_regen & 2) - return 0; - - if(pc_checkoversp(sd)) { - sd->sp_sub = sd->inchealsptick = 0; - return 0; - } - - bsp=sd->status.sp; - - inc_num = pc_spheal(sd); - if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer == -1) - sd->sp_sub += inc_num; - if(sd->walktimer == -1) - sd->inchealsptick += natural_heal_diff_tick; - else sd->inchealsptick = 0; - - if(sd->sp_sub >= battle_config.natural_healsp_interval){ - bonus = sd->nhealsp;; - while(sd->sp_sub >= battle_config.natural_healsp_interval){ - sd->sp_sub -= battle_config.natural_healsp_interval; - if(sd->status.sp + bonus <= sd->status.max_sp) - sd->status.sp += bonus; - else { - sd->status.sp = sd->status.max_sp; - sd->sp_sub = sd->inchealsptick = 0; - } - } - } - - if(bsp != sd->status.sp) - clif_updatestatus(sd,SP_SP); - - if(sd->nshealsp > 0) { - if(sd->inchealsptick >= battle_config.natural_heal_skill_interval && sd->status.sp < sd->status.max_sp) { - struct pc_base_job s_class = pc_calc_base_job(sd->status.class_); - if(sd->doridori_counter && s_class.job == 23) - bonus = sd->nshealsp*2; - else - bonus = sd->nshealsp; - sd->doridori_counter = 0; - while(sd->inchealsptick >= battle_config.natural_heal_skill_interval) { - sd->inchealsptick -= battle_config.natural_heal_skill_interval; - if(sd->status.sp + bonus <= sd->status.max_sp) - sd->status.sp += bonus; - else { - bonus = sd->status.max_sp - sd->status.sp; - sd->status.sp = sd->status.max_sp; - sd->sp_sub = sd->inchealsptick = 0; - } - clif_heal(sd->fd,SP_SP,bonus); - } - } - } - else sd->inchealsptick = 0; - - return 0; -} - -static int pc_spirit_heal_hp(struct map_session_data *sd) -{ - int bonus_hp,interval = battle_config.natural_heal_skill_interval; - - nullpo_retr(0, sd); - - if(pc_checkoverhp(sd)) { - sd->inchealspirithptick = 0; - return 0; - } - - sd->inchealspirithptick += natural_heal_diff_tick; - - if(sd->weight*100/sd->max_weight >= battle_config.natural_heal_weight_rate) - interval += interval; - - if(sd->inchealspirithptick >= interval) { - bonus_hp = sd->nsshealhp; - while(sd->inchealspirithptick >= interval) { - if(pc_issit(sd)) { - sd->inchealspirithptick -= interval; - if(sd->status.hp < sd->status.max_hp) { - if(sd->status.hp + bonus_hp <= sd->status.max_hp) - sd->status.hp += bonus_hp; - else { - bonus_hp = sd->status.max_hp - sd->status.hp; - sd->status.hp = sd->status.max_hp; - } - clif_heal(sd->fd,SP_HP,bonus_hp); - sd->inchealspirithptick = 0; - } - }else{ - sd->inchealspirithptick -= natural_heal_diff_tick; - break; - } - } - } - - return 0; -} -static int pc_spirit_heal_sp(struct map_session_data *sd) -{ - int bonus_sp,interval = battle_config.natural_heal_skill_interval; - - nullpo_retr(0, sd); - - if(pc_checkoversp(sd)) { - sd->inchealspiritsptick = 0; - return 0; - } - - sd->inchealspiritsptick += natural_heal_diff_tick; - - if(sd->weight*100/sd->max_weight >= battle_config.natural_heal_weight_rate) - interval += interval; - - if(sd->inchealspiritsptick >= interval) { - bonus_sp = sd->nsshealsp; - while(sd->inchealspiritsptick >= interval) { - if(pc_issit(sd)) { - sd->inchealspiritsptick -= interval; - if(sd->status.sp < sd->status.max_sp) { - if(sd->status.sp + bonus_sp <= sd->status.max_sp) - sd->status.sp += bonus_sp; - else { - bonus_sp = sd->status.max_sp - sd->status.sp; - sd->status.sp = sd->status.max_sp; - } - clif_heal(sd->fd,SP_SP,bonus_sp); - sd->inchealspiritsptick = 0; - } - }else{ - sd->inchealspiritsptick -= natural_heal_diff_tick; - break; - } - } - } - - return 0; -} - -static int pc_bleeding (struct map_session_data *sd) -{ - int interval, hp; - - nullpo_retr(0, sd); - interval = sd->hp_loss_rate; - hp = sd->hp_loss_value; - - sd->hp_loss_tick += natural_heal_diff_tick; - if(sd->hp_loss_tick >= interval) { - while(sd->hp_loss_tick >= interval) { - sd->hp_loss_tick -= interval; - if (sd->status.hp < hp) - hp = sd->status.hp; - if (sd->hp_loss_type == 1) { - clif_damage(&sd->bl,&sd->bl,gettick(),0,0,hp,0,0,0); - } - pc_heal(sd,-hp,0); - sd->hp_loss_tick = 0; - } - } - return 0; -} - -/*========================================== - * HP/SP 自然回復 各クライアント - *------------------------------------------ - */ - -static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) { - int skill; - int tick; - - nullpo_retr(0, sd); - tick = va_arg(ap,int); - -// -- moonsoul (if conditions below altered to disallow natural healing if under berserk status) - if ((battle_config.natural_heal_weight_rate > 100 || sd->weight*100/sd->max_weight < battle_config.natural_heal_weight_rate) && - !pc_isdead(sd) && - !pc_ishiding(sd) && - //-- cannot regen for 5 minutes after using Berserk --- [Celest] - DIFF_TICK (tick, sd->canregen_tick)>=0 && - (sd->sc_data && !(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) && - sd->sc_data[SC_BERSERK].timer == -1 )) { - pc_natural_heal_hp(sd); - if( sd->sc_data && sd->sc_data[SC_EXTREMITYFIST].timer == -1 && //阿修羅?態ではSPが回復しない - sd->sc_data[SC_DANCING].timer == -1 && //ダンス?態ではSPが回復しない - sd->sc_data[SC_BERSERK].timer == -1 ) //バ?サ?ク?態ではSPが回復しない - pc_natural_heal_sp(sd); - sd->canregen_tick = tick; - } else { - sd->hp_sub = sd->inchealhptick = 0; - sd->sp_sub = sd->inchealsptick = 0; - } - if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 && !pc_ishiding(sd) && - sd->sc_data[SC_POISON].timer == -1 && sd->sc_data[SC_BERSERK].timer == -1){ - pc_spirit_heal_hp(sd); - pc_spirit_heal_sp(sd); - } - else { - sd->inchealspirithptick = 0; - sd->inchealspiritsptick = 0; - } - if (sd->hp_loss_value > 0) - pc_bleeding(sd); - else - sd->hp_loss_tick = 0; - - return 0; -} - -/*========================================== - * HP/SP自然回復 (interval timer??) - *------------------------------------------ - */ -int pc_natural_heal(int tid,unsigned int tick,int id,int data) -{ - natural_heal_tick = tick; - natural_heal_diff_tick = DIFF_TICK(natural_heal_tick,natural_heal_prev_tick); - clif_foreachclient(pc_natural_heal_sub, tick); - - natural_heal_prev_tick = tick; - return 0; -} - -/*========================================== - * セ?ブポイントの保存 - *------------------------------------------ - */ -int pc_setsavepoint(struct map_session_data *sd,char *mapname,int x,int y) -{ - nullpo_retr(0, sd); - - strncpy(sd->status.save_point.map,mapname,24); - sd->status.save_point.x = x; - sd->status.save_point.y = y; - - return 0; -} - -/*========================================== - * 自動セ?ブ 各クライアント - *------------------------------------------ - */ -static int last_save_fd,save_flag; -static int pc_autosave_sub(struct map_session_data *sd,va_list ap) -{ - nullpo_retr(0, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(save_flag==0 && sd->fd>last_save_fd && !sd->state.waitingdisconnect){ - -// if(battle_config.save_log) -// printf("autosave %d\n",sd->fd); - // pet - if(sd->status.pet_id > 0 && sd->pd) - intif_save_petdata(sd->status.account_id,&sd->pet); - pc_makesavestatus(sd); - chrif_save(sd); - storage_storage_save(sd); - - save_flag=1; - last_save_fd = sd->fd; - } - - return 0; -} - -/*========================================== - * 自動セ?ブ (timer??) - *------------------------------------------ - */ -int pc_autosave(int tid,unsigned int tick,int id,int data) -{ - int interval; - - save_flag=0; - clif_foreachclient(pc_autosave_sub); - if(save_flag==0) - last_save_fd=0; - - interval = autosave_interval/(clif_countusers()+1); - if(interval <= 0) - interval = 1; - add_timer(gettick()+interval,pc_autosave,0,0); - - return 0; -} - -int pc_read_gm_account(int fd) -{ -#ifdef TXT_ONLY - int i = 0; -#endif - if (gm_account != NULL) - aFree(gm_account); - GM_num = 0; -#ifdef TXT_ONLY - gm_account = (struct gm_account *) aCallocA(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1); - for (i = 4; i < RFIFOW(fd,2); i = i + 5) { - gm_account[GM_num].account_id = RFIFOL(fd,i); - gm_account[GM_num].level = (int)RFIFOB(fd,i+4); - //printf("GM account: %d -> level %d\n", gm_account[GM_num].account_id, gm_account[GM_num].level); - GM_num++; - } -#else - sprintf (tmp_lsql, "SELECT `%s`,`%s` FROM `%s` WHERE `%s`>='%d'",gm_db_account_id,gm_db_level,gm_db,gm_db_level,lowest_gm_level); - if(mysql_query(&lmysql_handle, tmp_lsql) ) { - printf("DB server Error (select %s to Memory)- %s\n",login_db,mysql_error(&lmysql_handle) ); - } - lsql_res = mysql_store_result(&lmysql_handle); - if (lsql_res) { - gm_account = (struct gm_account *) aCallocA(sizeof(struct gm_account) * mysql_num_rows(lsql_res), 1); - while ((lsql_row = mysql_fetch_row(lsql_res))) { - gm_account[GM_num].account_id = atoi(lsql_row[0]); - gm_account[GM_num].level = atoi(lsql_row[1]); - printf("GM account: %d -> level %d\n", gm_account[GM_num].account_id, gm_account[GM_num].level); - GM_num++; - } - } - - mysql_free_result(lsql_res); -#endif /* TXT_ONLY */ - return GM_num; -} - -/*========================================== - * timer to do the day - *------------------------------------------ - */ -int map_day_timer(int tid, unsigned int tick, int id, int data) { // by [yor] - struct map_session_data *pl_sd = NULL; - int i; - char tmpstr[1024]; - - if (battle_config.day_duration > 0) { // if we want a day - if (night_flag != 0) { - strcpy(tmpstr, msg_txt(502)); // The day has arrived! - night_flag = 0; // 0=day, 1=night [Yor] - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) { - if (battle_config.night_darkness_level > 0) - clif_refresh (pl_sd); - else { - pl_sd->opt2 &= ~STATE_BLIND; - clif_changeoption(&pl_sd->bl); - } - clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1); - } - } - } - } - - return 0; -} - -/*========================================== - * timer to do the night - *------------------------------------------ - */ -int map_night_timer(int tid, unsigned int tick, int id, int data) { // by [yor] - struct map_session_data *pl_sd = NULL; - int i; - char tmpstr[1024]; - - if (battle_config.night_duration > 0) { // if we want a night - if (night_flag == 0) { - strcpy(tmpstr, msg_txt(503)); // The night has fallen... - night_flag = 1; // 0=day, 1=night [Yor] - for(i = 0; i < fd_max; i++) { - if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && !map[pl_sd->bl.m].flag.indoors) { - if (battle_config.night_darkness_level > 0) - clif_specialeffect(&pl_sd->bl, 474 + battle_config.night_darkness_level, 0); - else { - //clif_specialeffect(&pl_sd->bl, 483, 0); // default darkness level - pl_sd->opt2 |= STATE_BLIND; - clif_changeoption(&pl_sd->bl); - } - clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1); - } - } - } - } - - return 0; -} - -void pc_setstand(struct map_session_data *sd){ - nullpo_retv(sd); - - if(sd->sc_count && sd->sc_data[SC_TENSIONRELAX].timer!=-1) - status_change_end(&sd->bl,SC_TENSIONRELAX,-1); - - sd->state.dead_sit = 0; -} - -// -// 初期化物 -// -/*========================================== - * 設定ファイル?み?む - * exp.txt 必要??値 - * job_db1.txt 重量,hp,sp,攻?速度 - * job_db2.txt job能力値ボ?ナス - * skill_tree.txt 各職?のスキルツリ? - * attr_fix.txt ?性修正テ?ブル - * size_fix.txt サイズ補正テ?ブル - * refine_db.txt 精?デ?タテ?ブル - *------------------------------------------ - */ -int pc_readdb(void) -{ - int i,j,k,u; - struct pc_base_job s_class; - FILE *fp; - char line[1024],*p; - - // 必要??値?み?み - memset(exp_table,0,sizeof(exp_table)); - fp=fopen("db/exp.txt","r"); - if(fp==NULL){ - printf("can't read db/exp.txt\n"); - return 1; - } - i=0; - while(fgets(line, sizeof(line)-1, fp)){ - int bn,b1,b2,b3,b4,b5,b6,jn,j1,j2,j3,j4,j5,j6; - if(line[0]=='/' && line[1]=='/') - continue; - if(sscanf(line,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&bn,&b1,&b2,&b3,&b4,&b5,&b6,&jn,&j1,&j2,&j3,&j4,&j5,&j6)!=14) - continue; - exp_table[0][i]=bn; - exp_table[1][i]=b1; - exp_table[2][i]=b2; - exp_table[3][i]=b3; - exp_table[4][i]=b4; - exp_table[5][i]=b5; - exp_table[6][i]=b6; - exp_table[7][i]=jn; - exp_table[8][i]=j1; - exp_table[9][i]=j2; - exp_table[10][i]=j3; - exp_table[11][i]=j4; - exp_table[12][i]=j5; - exp_table[13][i]=j6; - i++; - if(i >= battle_config.maximum_level) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/exp.txt"); - ShowStatus(tmp_output); - - // スキルツリ? - memset(skill_tree,0,sizeof(skill_tree)); - fp=fopen("db/skill_tree.txt","r"); - if(fp==NULL){ - printf("can't read db/skill_tree.txt\n"); - return 1; - } - - while(fgets(line, sizeof(line)-1, fp)){ - char *split[50]; - int f=0, m=3; - if(line[0]=='/' && line[1]=='/') - continue; - for(j=0,p=line;j<14 && p;j++){ - split[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if(j<13) - continue; - if (j == 14) { - f=1; // MinJobLvl has been added - m++; - } - s_class = pc_calc_base_job(atoi(split[0])); - i = s_class.job; - u = s_class.upper; - // check for bounds [celest] - if (i > 25 || u > 3) - continue; - for(j = 0; skill_tree[u][i][j].id && j < MAX_SKILL_TREE; j++); - if (j == MAX_SKILL_TREE) - continue; - skill_tree[u][i][j].id=atoi(split[1]); - skill_tree[u][i][j].max=atoi(split[2]); - if (f) skill_tree[u][i][j].joblv=atoi(split[3]); - - for(k=0;k<5;k++){ - skill_tree[u][i][j].need[k].id=atoi(split[k*2+m]); - skill_tree[u][i][j].need[k].lv=atoi(split[k*2+m+1]); - } - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_tree.txt"); - ShowStatus(tmp_output); - - // ?性修正テ?ブル - for(i=0;i<4;i++) - for(j=0;j<10;j++) - for(k=0;k<10;k++) - attr_fix_table[i][j][k]=100; - fp=fopen("db/attr_fix.txt","r"); - if(fp==NULL){ - printf("can't read db/attr_fix.txt\n"); - return 1; - } - while(fgets(line, sizeof(line)-1, fp)){ - char *split[10]; - int lv,n; - if(line[0]=='/' && line[1]=='/') - continue; - for(j=0,p=line;j<3 && p;j++){ - split[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - lv=atoi(split[0]); - n=atoi(split[1]); -// printf("%d %d\n",lv,n); - - for(i=0;i<n;){ - if( !fgets(line, sizeof(line)-1, fp) ) - break; - if(line[0]=='/' && line[1]=='/') - continue; - - for(j=0,p=line;j<n && p;j++){ - while(*p==32 && *p>0) - p++; - attr_fix_table[lv-1][i][j]=atoi(p); - if(battle_config.attr_recover == 0 && attr_fix_table[lv-1][i][j] < 0) - attr_fix_table[lv-1][i][j] = 0; - p=strchr(p,','); - if(p) *p++=0; - } - - i++; - } - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/attr_fix.txt"); - ShowStatus(tmp_output); - - // スキルツリ? - memset(statp,0,sizeof(statp)); - i=1; - j=45; // base points - fp=fopen("db/statpoint.txt","r"); - if(fp == NULL){ - sprintf(tmp_output,"Can't read '"CL_WHITE"%s"CL_RESET"'... Generating DB.\n","db/statpoint.txt"); - //return 1; - } else { - while(fgets(line, sizeof(line)-1, fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - if ((j=atoi(line))<0) - j=0; - if (i >= MAX_LEVEL) - break; - statp[i]=j; - i++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/statpoint.txt"); - } - // generate the remaining parts of the db if necessary - for (; i < MAX_LEVEL; i++) { - j += (i+15)/5; - statp[i] = j; - } - ShowStatus(tmp_output); - - return 0; -} - -/*========================================== - * pc? 係初期化 - *------------------------------------------ - */ -void do_final_pc(void) { - if (gm_account) - aFree(gm_account); - return; -} -int do_init_pc(void) { - pc_readdb(); - -// gm_account_db = numdb_init(); - - add_timer_func_list(pc_walk, "pc_walk"); - add_timer_func_list(pc_attack_timer, "pc_attack_timer"); - add_timer_func_list(pc_natural_heal, "pc_natural_heal"); - add_timer_func_list(pc_invincible_timer, "pc_invincible_timer"); - add_timer_func_list(pc_eventtimer, "pc_eventtimer"); - add_timer_func_list(pc_calc_pvprank_timer, "pc_calc_pvprank_timer"); - add_timer_func_list(pc_autosave, "pc_autosave"); - add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer"); - add_timer_interval((natural_heal_prev_tick = gettick() + NATURAL_HEAL_INTERVAL), pc_natural_heal, 0, 0, NATURAL_HEAL_INTERVAL); - add_timer(gettick() + autosave_interval, pc_autosave, 0, 0); - -#ifndef TXT_ONLY - pc_read_gm_account(0); -#endif /* not TXT_ONLY */ - - if (battle_config.day_duration > 0 && battle_config.night_duration > 0) { - int day_duration = battle_config.day_duration; - int night_duration = battle_config.night_duration; - // add night/day timer (by [yor]) - add_timer_func_list(map_day_timer, "map_day_timer"); // by [yor] - add_timer_func_list(map_night_timer, "map_night_timer"); // by [yor] - - if (battle_config.night_at_start == 0) { - night_flag = 0; // 0=day, 1=night [Yor] - day_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_day_timer, 0, 0, day_duration + night_duration); - night_timer_tid = add_timer_interval(gettick() + day_duration, map_night_timer, 0, 0, day_duration + night_duration); - } else { - night_flag = 1; // 0=day, 1=night [Yor] - day_timer_tid = add_timer_interval(gettick() + night_duration, map_day_timer, 0, 0, day_duration + night_duration); - night_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_night_timer, 0, 0, day_duration + night_duration); - } - } - - return 0; -} diff --git a/src/map/pc.h b/src/map/pc.h deleted file mode 100644 index 6aec36d38..000000000 --- a/src/map/pc.h +++ /dev/null @@ -1,224 +0,0 @@ -// $Id: pc.h,v 1.4 2004/09/25 05:32:18 MouseJstr Exp $ - -#ifndef _PC_H_ -#define _PC_H_ - -#include "map.h" - -#define OPTION_MASK 0xd7b8 -#define CART_MASK 0x788 -#define STATE_BLIND 0x10 - -#define MAX_SKILL_TREE 51 - -#define pc_setdead(sd) ((sd)->state.dead_sit = 1) -#define pc_setsit(sd) ((sd)->state.dead_sit = 2) -//#define pc_setstand(sd) ((sd)->state.dead_sit = 0) -#define pc_isdead(sd) ((sd)->state.dead_sit == 1) -#define pc_issit(sd) ((sd)->state.dead_sit == 2) -#define pc_setdir(sd,b,h) ((sd)->dir = (b) ,(sd)->head_dir = (h) ) -#define pc_setchatid(sd,n) ((sd)->chatID = n) -#define pc_ishiding(sd) ((sd)->status.option&0x4006) -#define pc_iscarton(sd) ((sd)->status.option&CART_MASK) -#define pc_isfalcon(sd) ((sd)->status.option&0x0010) -#define pc_isriding(sd) ((sd)->status.option&0x0020) -#define pc_isinvisible(sd) ((sd)->status.option&0x0040) -#define pc_is50overweight(sd) (sd->weight*2 >= sd->max_weight) -#define pc_is90overweight(sd) (sd->weight*10 >= sd->max_weight*9) - -int pc_isGM(struct map_session_data *sd); -int pc_iskiller(struct map_session_data *src, struct map_session_data *target); // [MouseJstr] -int pc_getrefinebonus(int lv,int type); - -int pc_counttargeted(struct map_session_data *sd,struct block_list *src,int target_lv); -int pc_setrestartvalue(struct map_session_data *sd,int type); -int pc_makesavestatus(struct map_session_data *); -int pc_setnewpc(struct map_session_data*,int,int,int,int,int,int); -int pc_authok(int, int, time_t, struct mmo_charstatus *); -int pc_authfail(int); - -int pc_isequip(struct map_session_data *sd,int n); -int pc_equippoint(struct map_session_data *sd,int n); - -int pc_break_equip(struct map_session_data *, unsigned short); -#define pc_breakweapon(sd) (pc_break_equip(sd, EQP_WEAPON)) -#define pc_breakarmor(sd) (pc_break_equip(sd, EQP_ARMOR)) -#define pc_breakshield(sd) (pc_break_equip(sd, EQP_SHIELD)) -#define pc_breakhelm(sd) (pc_break_equip(sd, EQP_HELM)) - -int pc_checkskill(struct map_session_data *sd,int skill_id); -int pc_checkallowskill(struct map_session_data *sd); -int pc_checkequip(struct map_session_data *sd,int pos); - -int pc_calc_skilltree(struct map_session_data *sd); -int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd); -int pc_clean_skilltree(struct map_session_data *sd); - -int pc_checkoverhp(struct map_session_data*); -int pc_checkoversp(struct map_session_data*); - -int pc_can_reach(struct map_session_data*,int,int); -int pc_walktoxy(struct map_session_data*,int,int); -int pc_stop_walking(struct map_session_data*,int); -int pc_movepos(struct map_session_data*,int,int); -int pc_setpos(struct map_session_data*,char*,int,int,int); -int pc_setsavepoint(struct map_session_data*,char*,int,int); -int pc_randomwarp(struct map_session_data *sd,int type); -int pc_memo(struct map_session_data *sd,int i); -int pc_randomwalk(struct map_session_data*,int tick); -int pc_remove_map(struct map_session_data *sd,int clrtype); - -int pc_checkadditem(struct map_session_data*,int,int); -int pc_inventoryblank(struct map_session_data*); -int pc_search_inventory(struct map_session_data *sd,int item_id); -int pc_payzeny(struct map_session_data*,int); -int pc_additem(struct map_session_data*,struct item*,int); -int pc_getzeny(struct map_session_data*,int); -int pc_delitem(struct map_session_data*,int,int,int); -int pc_checkitem(struct map_session_data*); - -int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount); -int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type); -int pc_putitemtocart(struct map_session_data *sd,int idx,int amount); -int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount); -int pc_cartitem_amount(struct map_session_data *sd,int idx,int amount); - -int pc_takeitem(struct map_session_data*,struct flooritem_data*); -int pc_dropitem(struct map_session_data*,int,int); - -int pc_checkweighticon(struct map_session_data *sd); - -int pc_bonus(struct map_session_data*,int,int); -int pc_bonus2(struct map_session_data *sd,int,int,int); -int pc_bonus3(struct map_session_data *sd,int,int,int,int); -int pc_bonus4(struct map_session_data *sd,int,int,int,int,int); -int pc_skill(struct map_session_data*,int,int,int); - -int pc_blockskill_start (struct map_session_data*,int,int); // [celest] - -int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip); - -int pc_item_identify(struct map_session_data *sd,int idx); -int pc_item_repair(struct map_session_data *sd,int idx); // [Celest] -int pc_item_refine(struct map_session_data *sd,int idx); // [Celest] -int pc_steal_item(struct map_session_data *sd,struct block_list *bl); -int pc_steal_coin(struct map_session_data *sd,struct block_list *bl); - -int pc_modifybuyvalue(struct map_session_data*,int); -int pc_modifysellvalue(struct map_session_data*,int); - -int pc_attack(struct map_session_data*,int,int); -int pc_stopattack(struct map_session_data*); - -int pc_follow(struct map_session_data*, int); // [MouseJstr] - -int pc_checkbaselevelup(struct map_session_data *sd); -int pc_checkjoblevelup(struct map_session_data *sd); -int pc_gainexp(struct map_session_data*,int,int); -int pc_nextbaseexp(struct map_session_data *); -int pc_nextbaseafter(struct map_session_data *); // [Valaris] -int pc_nextjobexp(struct map_session_data *); -int pc_nextjobafter(struct map_session_data *); // [Valaris] -int pc_need_status_point(struct map_session_data *,int); -int pc_statusup(struct map_session_data*,int); -int pc_statusup2(struct map_session_data*,int,int); -int pc_skillup(struct map_session_data*,int); -int pc_allskillup(struct map_session_data*); -int pc_resetlvl(struct map_session_data*,int type); -int pc_resetstate(struct map_session_data*); -int pc_resetskill(struct map_session_data*); -int pc_equipitem(struct map_session_data*,int,int); -int pc_unequipitem(struct map_session_data*,int,int); -int pc_checkitem(struct map_session_data*); -int pc_useitem(struct map_session_data*,int); - -int pc_damage(struct block_list *,struct map_session_data*,int); -int pc_heal(struct map_session_data *,int,int); -int pc_itemheal(struct map_session_data *sd,int hp,int sp); -int pc_percentheal(struct map_session_data *sd,int,int); -int pc_jobchange(struct map_session_data *,int, int); -int pc_setoption(struct map_session_data *,int); -int pc_setcart(struct map_session_data *sd,int type); -int pc_setfalcon(struct map_session_data *sd); -int pc_setriding(struct map_session_data *sd); -int pc_changelook(struct map_session_data *,int,int); -int pc_equiplookall(struct map_session_data *sd); - -int pc_readparam(struct map_session_data*,int); -int pc_setparam(struct map_session_data*,int,int); -int pc_readreg(struct map_session_data*,int); -int pc_setreg(struct map_session_data*,int,int); -char *pc_readregstr(struct map_session_data *sd,int reg); -int pc_setregstr(struct map_session_data *sd,int reg,char *str); -int pc_readglobalreg(struct map_session_data*,char*); -int pc_setglobalreg(struct map_session_data*,char*,int); -int pc_readaccountreg(struct map_session_data*,char*); -int pc_setaccountreg(struct map_session_data*,char*,int); -int pc_readaccountreg2(struct map_session_data*,char*); -int pc_setaccountreg2(struct map_session_data*,char*,int); - -int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name); -int pc_deleventtimer(struct map_session_data *sd,const char *name); -int pc_cleareventtimer(struct map_session_data *sd); -int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick); - -int pc_calc_pvprank(struct map_session_data *sd); -int pc_calc_pvprank_timer(int tid,unsigned int tick,int id,int data); - -int pc_ismarried(struct map_session_data *sd); -int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd); -int pc_divorce(struct map_session_data *sd); -int pc_adoption(struct map_session_data *sd,struct map_session_data *dstsd,struct map_session_data *jasd); -struct map_session_data *pc_get_partner(struct map_session_data *sd); -struct map_session_data *pc_get_father(struct map_session_data *sd); -struct map_session_data *pc_get_mother(struct map_session_data *sd); -struct map_session_data *pc_get_child(struct map_session_data *sd); - -int pc_set_gm_level(int account_id, int level); -void pc_setstand(struct map_session_data *sd); -int pc_break_equip(struct map_session_data *sd, unsigned short where); -int pc_candrop(struct map_session_data *sd,int item_id); - -struct pc_base_job{ - int job; //職業、ただし転生職や養子職の場合は元の職業を返す(廃プリ→プリ) - int type; //ノビ 0, 一次職 1, 二次職 2, スパノビ 3 - int upper; //通常 0, 転生 1, 養子 2 -}; - -struct pc_base_job pc_calc_base_job(int b_class);//転生や養子職の元の職業を返す -int pc_calc_base_job2(int b_class); // Celest -int pc_calc_upper(int b_class); - -struct skill_tree_entry { - short id; - unsigned char max; - unsigned char joblv; - struct { - short id; - unsigned char lv; - } need[5]; -}; // Celest -extern struct skill_tree_entry skill_tree[3][25][MAX_SKILL_TREE]; - -int pc_read_gm_account(int fd); -int pc_setinvincibletimer(struct map_session_data *sd,int); -int pc_delinvincibletimer(struct map_session_data *sd); -int pc_addspiritball(struct map_session_data *sd,int,int); -int pc_delspiritball(struct map_session_data *sd,int,int); - -int pc_eventtimer(int tid,unsigned int tick,int id,int data); // for npc_dequeue - -int pc_readdb(void); -int do_init_pc(void); -void do_final_pc(void); - -enum {ADDITEM_EXIST,ADDITEM_NEW,ADDITEM_OVERAMOUNT}; - -// timer for night.day -extern int day_timer_tid; -extern int night_timer_tid; -int map_day_timer(int,unsigned int,int,int); // by [yor] -int map_night_timer(int,unsigned int,int,int); // by [yor] - -#endif - diff --git a/src/map/pet.c b/src/map/pet.c deleted file mode 100644 index 6f4713d75..000000000 --- a/src/map/pet.c +++ /dev/null @@ -1,1694 +0,0 @@ -// $Id: pet.c,v 1.4 2004/09/25 05:32:18 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "db.h" -#include "timer.h" -#include "socket.h" -#include "nullpo.h" -#include "malloc.h" -#include "pc.h" -#include "status.h" -#include "map.h" -#include "intif.h" -#include "clif.h" -#include "chrif.h" -#include "pet.h" -#include "itemdb.h" -#include "battle.h" -#include "mob.h" -#include "npc.h" -#include "script.h" -#include "skill.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define MIN_PETTHINKTIME 100 - -struct pet_db pet_db[MAX_PET_DB]; - -static int dirx[8]={0,-1,-1,-1,0,1,1,1}; -static int diry[8]={1,1,0,-1,-1,-1,0,1}; - -static int pet_timer(int tid,unsigned int tick,int id,int data); -static int pet_walktoxy_sub(struct pet_data *pd); - -static int distance(int x0,int y0,int x1,int y1) -{ - int dx,dy; - - dx=abs(x0-x1); - dy=abs(y0-y1); - return dx>dy ? dx : dy; -} - -static int calc_next_walk_step(struct pet_data *pd) -{ - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(pd->walkpath.path_pos>=pd->walkpath.path_len) - return -1; - if(pd->walkpath.path[pd->walkpath.path_pos]&1) - return pd->speed*14/10; - return pd->speed; -} - -static int pet_performance_val(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->pet.intimate > 900) - return (sd->petDB->s_perfor > 0)? 4:3; - else if(sd->pet.intimate > 750) - return 2; - else - return 1; -} - -int pet_hungry_val(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->pet.hungry > 90) - return 4; - else if(sd->pet.hungry > 75) - return 3; - else if(sd->pet.hungry > 25) - return 2; - else if(sd->pet.hungry > 10) - return 1; - else - return 0; -} - -static int pet_can_reach(struct pet_data *pd,int x,int y) -{ - struct walkpath_data wpd; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if( pd->bl.x==x && pd->bl.y==y ) // 同じマス - return 1; - - // 障害物判定 - wpd.path_len=0; - wpd.path_pos=0; - wpd.path_half=0; - return (path_search(&wpd,pd->bl.m,pd->bl.x,pd->bl.y,x,y,0)!=-1)?1:0; -} - -static int pet_calc_pos(struct pet_data *pd,int tx,int ty,int dir) -{ - int x,y,dx,dy; - int i,j=0,k; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - pd->to_x = tx; - pd->to_y = ty; - - if(dir >= 0 && dir < 8) { - dx = -dirx[dir]*2; - dy = -diry[dir]*2; - x = tx + dx; - y = ty + dy; - if(!(j=pet_can_reach(pd,x,y))) { - if(dx > 0) x--; - else if(dx < 0) x++; - if(dy > 0) y--; - else if(dy < 0) y++; - if(!(j=pet_can_reach(pd,x,y))) { - for(i=0;i<12;i++) { - k = rand()%8; - dx = -dirx[k]*2; - dy = -diry[k]*2; - x = tx + dx; - y = ty + dy; - if((j=pet_can_reach(pd,x,y))) - break; - else { - if(dx > 0) x--; - else if(dx < 0) x++; - if(dy > 0) y--; - else if(dy < 0) y++; - if((j=pet_can_reach(pd,x,y))) - break; - } - } - if(!j) { - x = tx; - y = ty; - if(!pet_can_reach(pd,x,y)) - return 1; - } - } - } - } - else - return 1; - - pd->to_x = x; - pd->to_y = y; - return 0; -} - -static int pet_attack(struct pet_data *pd,unsigned int tick,int data) -{ - struct mob_data *md; - int mode,race,range; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - pd->state.state=MS_IDLE; - - md=(struct mob_data *)map_id2bl(pd->target_id); - if(md == NULL || md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL || - distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13 || - (!agit_flag && md->class_ >= 1285 && md->class_ <= 1288)) // Cannot attack Guardians outside of WoE - { - pd->target_id=0; - return 0; - } - - mode=mob_db[pd->class_].mode; - race=mob_db[pd->class_].race; - if(mob_db[pd->class_].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race != 4 && race != 6) ) { - pd->target_id=0; - return 0; - } - - range = mob_db[pd->class_].range + 1; - if(distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > range) - return 0; - if(battle_config.monster_attack_direction_change) - pd->dir=map_calc_dir(&pd->bl, md->bl.x,md->bl.y ); - - clif_fixpetpos(pd); - - pd->target_lv = battle_weapon_attack(&pd->bl,&md->bl,tick,0); - - pd->attackabletime = tick + status_get_adelay(&pd->bl); - - pd->timer=add_timer(pd->attackabletime,pet_timer,pd->bl.id,0); - pd->state.state=MS_ATTACK; - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static int pet_walk(struct pet_data *pd,unsigned int tick,int data) -{ - int moveblock; - int i; - int x,y,dx,dy; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - pd->state.state=MS_IDLE; - if(pd->walkpath.path_pos >= pd->walkpath.path_len || pd->walkpath.path_pos != data) - return 0; - - pd->walkpath.path_half ^= 1; - if(pd->walkpath.path_half==0){ - pd->walkpath.path_pos++; - if(pd->state.change_walk_target){ - pet_walktoxy_sub(pd); - return 0; - } - } - else { - if(pd->walkpath.path[pd->walkpath.path_pos] >= 8) - return 1; - - x = pd->bl.x; - y = pd->bl.y; -/* ctype = map_getcell(pd->bl.m,x,y); - if(ctype == 1 || ctype == 5) { - pet_stop_walking(pd,1); - return 0; - }*/ - pd->dir=pd->walkpath.path[pd->walkpath.path_pos]; - dx = dirx[pd->dir]; - dy = diry[pd->dir]; - - if(map_getcell(pd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)){ - pet_walktoxy_sub(pd); - return 0; - } - - moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE); - - pd->state.state=MS_WALK; - map_foreachinmovearea(clif_petoutsight,pd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,pd); - - x += dx; - y += dy; - - if(moveblock) map_delblock(&pd->bl); - pd->bl.x = x; - pd->bl.y = y; - if(moveblock) map_addblock(&pd->bl); - - map_foreachinmovearea(clif_petinsight,pd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,pd); - pd->state.state=MS_IDLE; - } - if((i=calc_next_walk_step(pd))>0){ - i = i>>1; - if(i < 1 && pd->walkpath.path_half == 0) - i = 1; - pd->timer=add_timer(tick+i,pet_timer,pd->bl.id,pd->walkpath.path_pos); - pd->state.state=MS_WALK; - - if(pd->walkpath.path_pos >= pd->walkpath.path_len) - clif_fixpetpos(pd); - } - return 0; -} - -int pet_stopattack(struct pet_data *pd) -{ - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - pd->target_id=0; - if(pd->state.state == MS_ATTACK) - pet_changestate(pd,MS_IDLE,0); - - return 0; -} - -int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type) -{ - struct pet_data *pd; - struct mob_data *md; - int rate,mode,race; - - nullpo_retr(0, sd); - - pd = sd->pd; - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(bl && pd && bl->type == BL_MOB && sd->pet.intimate > 900 && sd->pet.hungry > 0 && pd->class_ != status_get_class(bl) - && pd->state.state != MS_DELAY) { - mode=mob_db[pd->class_].mode; - race=mob_db[pd->class_].race; - md=(struct mob_data *)bl; - if(md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL || - distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13) - return 0; - if(mob_db[pd->class_].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race!=4 && race!=6) ) - return 0; - if(!type) { - rate = sd->petDB->attack_rate; - rate = rate * (150 - (sd->pet.intimate - 1000))/100; - if(battle_config.pet_support_rate != 100) - rate = rate*battle_config.pet_support_rate/100; - if(sd->petDB->attack_rate > 0 && rate <= 0) - rate = 1; - } - else { - rate = sd->petDB->defence_attack_rate; - rate = rate * (150 - (sd->pet.intimate - 1000))/100; - if(battle_config.pet_support_rate != 100) - rate = rate*battle_config.pet_support_rate/100; - if(sd->petDB->defence_attack_rate > 0 && rate <= 0) - rate = 1; - } - if(rand()%10000 < rate) { - if(pd->target_id == 0 || rand()%10000 < sd->petDB->change_target_rate) - pd->target_id = bl->id; - } - } - return 0; -} - -int pet_changestate(struct pet_data *pd,int state,int type) -{ - unsigned int tick; - int i; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(pd->timer != -1) - delete_timer(pd->timer,pet_timer); - pd->timer=-1; - pd->state.state=state; - - switch(state) { - case MS_WALK: - if((i=calc_next_walk_step(pd)) > 0){ - i = i>>2; - pd->timer=add_timer(gettick()+i,pet_timer,pd->bl.id,0); - } else - pd->state.state=MS_IDLE; - break; - case MS_ATTACK: - tick = gettick(); - i=DIFF_TICK(pd->attackabletime,tick); - if(i>0 && i<2000) - pd->timer=add_timer(pd->attackabletime,pet_timer,pd->bl.id,0); - else - pd->timer=add_timer(tick+1,pet_timer,pd->bl.id,0); - break; - case MS_DELAY: - pd->timer=add_timer(gettick()+type,pet_timer,pd->bl.id,0); - break; - } - - return 0; -} - -static int pet_timer(int tid,unsigned int tick,int id,int data) -{ - struct pet_data *pd; - - pd=(struct pet_data*)map_id2bl(id); - if(pd == NULL || pd->bl.type != BL_PET) - return 1; - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(pd->timer != tid){ - if(battle_config.error_log) - printf("pet_timer %d != %d\n",pd->timer,tid); - return 0; - } - pd->timer=-1; - - if(pd->bl.prev == NULL) - return 1; - - switch(pd->state.state){ - case MS_WALK: - pet_walk(pd,tick,data); - break; - case MS_ATTACK: - pet_attack(pd,tick,data); - break; - case MS_DELAY: - pet_changestate(pd,MS_IDLE,0); - break; - default: - if(battle_config.error_log) - printf("pet_timer : %d ?\n",pd->state.state); - break; - } - - return 0; -} - -static int pet_walktoxy_sub(struct pet_data *pd) -{ - struct walkpath_data wpd; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(path_search(&wpd,pd->bl.m,pd->bl.x,pd->bl.y,pd->to_x,pd->to_y,0)) - return 1; - memcpy(&pd->walkpath,&wpd,sizeof(wpd)); - - pd->state.change_walk_target=0; - pet_changestate(pd,MS_WALK,0); - clif_movepet(pd); -// if(battle_config.etc_log) -// printf("walkstart\n"); - - return 0; -} - -int pet_walktoxy(struct pet_data *pd,int x,int y) -{ - struct walkpath_data wpd; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(pd->state.state == MS_WALK && path_search(&wpd,pd->bl.m,pd->bl.x,pd->bl.y,x,y,0)) - return 1; - - pd->to_x=x; - pd->to_y=y; - - if(pd->state.state == MS_WALK) { - pd->state.change_walk_target=1; - } else { - return pet_walktoxy_sub(pd); - } - - return 0; -} - -int pet_stop_walking(struct pet_data *pd,int type) -{ - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - if(pd->state.state == MS_WALK || pd->state.state == MS_IDLE) { - pd->walkpath.path_len=0; - pd->to_x=pd->bl.x; - pd->to_y=pd->bl.y; - } - if(type&0x01) - clif_fixpetpos(pd); - if(type&~0xff) - pet_changestate(pd,MS_DELAY,type>>8); - else - pet_changestate(pd,MS_IDLE,0); - - return 0; -} - -static int pet_hungry(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd; - int interval,t; - - - sd=map_id2sd(id); - if(sd==NULL) - return 1; - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->pet_hungry_timer != tid){ - if(battle_config.error_log) - printf("pet_hungry_timer %d != %d\n",sd->pet_hungry_timer,tid); - return 0; - } - sd->pet_hungry_timer = -1; - if(!sd->status.pet_id || !sd->pd || !sd->petDB) - return 1; - - sd->pet.hungry--; - t = sd->pet.intimate; - if(sd->pet.hungry < 0) { - if(sd->pd->target_id > 0) - pet_stopattack(sd->pd); - sd->pet.hungry = 0; - sd->pet.intimate -= battle_config.pet_hungry_friendly_decrease; - if(sd->pet.intimate <= 0) { - sd->pet.intimate = 0; - if(battle_config.pet_status_support && t > 0) { - if(sd->bl.prev != NULL) - status_calc_pc(sd,0); - else - status_calc_pc(sd,2); - } - } - clif_send_petdata(sd,1,sd->pet.intimate); - } - clif_send_petdata(sd,2,sd->pet.hungry); - - if(battle_config.pet_hungry_delay_rate != 100) - interval = (sd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100; - else - interval = sd->petDB->hungry_delay; - if(interval <= 0) - interval = 1; - sd->pet_hungry_timer = add_timer(tick+interval,pet_hungry,sd->bl.id,0); - - return 0; -} - -int search_petDB_index(int key,int type) -{ - int i; - - for(i=0;i<MAX_PET_DB;i++) { - if(pet_db[i].class_ <= 0) - continue; - switch(type) { - case PET_CLASS: - if(pet_db[i].class_ == key) - return i; - break; - case PET_CATCH: - if(pet_db[i].itemID == key) - return i; - break; - case PET_EGG: - if(pet_db[i].EggID == key) - return i; - break; - case PET_EQUIP: - if(pet_db[i].AcceID == key) - return i; - break; - case PET_FOOD: - if(pet_db[i].FoodID == key) - return i; - break; - default: - return -1; - } - } - return -1; -} - -int pet_hungry_timer_delete(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - if(sd->pet_hungry_timer != -1) { - delete_timer(sd->pet_hungry_timer,pet_hungry); - sd->pet_hungry_timer = -1; - } - - return 0; -} - -int pet_remove_map(struct map_session_data *sd) -{ - nullpo_retr(0, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->status.pet_id && sd->pd) { - - struct pet_data *pd=sd->pd; // [Valaris] - if(pd->skillbonustimer!=-1) pd->skillbonustimer=-1; - pd->skilltype=0; - pd->skillval=0; - if(pd->skilltimer!=-1) pd->skilltimer=-1; - pd->state.skillbonus=-1; - pd->skillduration=0; - pd->skillbonustype=0; - pd->skillbonusval=0; - if(sd->perfect_hiding==1) sd->perfect_hiding=0; // end additions - - pet_changestate(sd->pd,MS_IDLE,0); - if(sd->pet_hungry_timer != -1) - pet_hungry_timer_delete(sd); - clif_clearchar_area(&sd->pd->bl,0); - map_delblock(&sd->pd->bl); - if (sd->pd->lootitem) - aFree(sd->pd->lootitem); - map_deliddb(&sd->pd->bl); - } - return 0; -} -struct delay_item_drop { - int m,x,y; - int nameid,amount; - struct map_session_data *first_sd,*second_sd,*third_sd; -}; - -struct delay_item_drop2 { - int m,x,y; - struct item item_data; - struct map_session_data *first_sd,*second_sd,*third_sd; -}; - -int pet_performance(struct map_session_data *sd) -{ - struct pet_data *pd; - - nullpo_retr(0, sd); - nullpo_retr(0, pd=sd->pd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - pet_stop_walking(pd,2000<<8); - clif_pet_performance(&pd->bl,rand()%pet_performance_val(sd) + 1); - // ルートしたItemを落とさせる - pet_lootitem_drop(pd,NULL); - - return 0; -} - -int pet_return_egg(struct map_session_data *sd) -{ - struct item tmp_item; - int flag; - - nullpo_retr(0, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->status.pet_id && sd->pd) { - // ルートしたItemを落とさせる - pet_lootitem_drop(sd->pd,sd); - pet_remove_map(sd); - sd->status.pet_id = 0; - sd->pd = NULL; - - if(sd->petDB == NULL) - return 1; - sd->pet.incuvate = 1; - memset(&tmp_item,0,sizeof(tmp_item)); - tmp_item.nameid = sd->petDB->EggID; - tmp_item.identify = 1; - tmp_item.card[0] = 0xff00; - *((long *)(&tmp_item.card[1])) = sd->pet.pet_id; - tmp_item.card[3] = sd->pet.rename_flag; - if((flag = pc_additem(sd,&tmp_item,1))) { - clif_additem(sd,0,0,flag); - map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - if(battle_config.pet_status_support && sd->pet.intimate > 0) { - if(sd->bl.prev != NULL) - status_calc_pc(sd,0); - else - status_calc_pc(sd,2); - } - - intif_save_petdata(sd->status.account_id,&sd->pet); - pc_makesavestatus(sd); - chrif_save(sd); - storage_storage_save(sd); - - sd->petDB = NULL; - } - - return 0; -} - -int pet_data_init(struct map_session_data *sd) -{ - struct pet_data *pd; - int i=0,interval=0; - - nullpo_retr(1, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->status.account_id != sd->pet.account_id || sd->status.char_id != sd->pet.char_id || - sd->status.pet_id != sd->pet.pet_id) { - sd->status.pet_id = 0; - return 1; - } - - i = search_petDB_index(sd->pet.class_,PET_CLASS); - if(i < 0) { - sd->status.pet_id = 0; - return 1; - } - sd->petDB = &pet_db[i]; - sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data)); - - pd->bl.m = sd->bl.m; - pd->bl.prev = pd->bl.next = NULL; - pd->bl.x = pd->to_x = sd->bl.x; - pd->bl.y = pd->to_y = sd->bl.y; - pet_calc_pos(pd,sd->bl.x,sd->bl.y,sd->dir); - pd->bl.x = pd->to_x; - pd->bl.y = pd->to_y; - pd->bl.id = npc_get_new_npc_id(); - memcpy(pd->name,sd->pet.name,24); - pd->class_ = sd->pet.class_; - pd->equip = sd->pet.equip; - pd->dir = sd->dir; - pd->speed = sd->petDB->speed; - pd->bl.subtype = MONS; - pd->bl.type = BL_PET; - memset(&pd->state,0,sizeof(pd->state)); - pd->state.state = MS_IDLE; - pd->state.change_walk_target = 0; - pd->timer = -1; - pd->target_id = 0; - pd->move_fail_count = 0; - pd->next_walktime = pd->attackabletime = pd->last_thinktime = gettick(); - pd->msd = sd; - - map_addiddb(&pd->bl); - - // initialise - pd->state.skillbonus = -1; - run_script(pet_db[i].script,0,sd->bl.id,0); - - if(sd->pet_hungry_timer != -1) - pet_hungry_timer_delete(sd); - if(battle_config.pet_hungry_delay_rate != 100) - interval = (sd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100; - else - interval = sd->petDB->hungry_delay; - if(interval <= 0) - interval = 1; - sd->pet_hungry_timer = add_timer(gettick()+interval,pet_hungry,sd->bl.id,0); - pd->lootitem=(struct item *)aCalloc(PETLOOT_SIZE,sizeof(struct item)); - pd->lootitem_count = 0; - pd->lootitem_weight = 0; - pd->lootitem_timer = gettick(); - return 0; -} - -int pet_birth_process(struct map_session_data *sd) -{ - nullpo_retr(1, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->status.pet_id && sd->pet.incuvate == 1) { - sd->status.pet_id = 0; - return 1; - } - - sd->pet.incuvate = 0; - sd->pet.account_id = sd->status.account_id; - sd->pet.char_id = sd->status.char_id; - sd->status.pet_id = sd->pet.pet_id; - if(pet_data_init(sd)) { - sd->status.pet_id = 0; - sd->pet.incuvate = 1; - sd->pet.account_id = 0; - sd->pet.char_id = 0; - return 1; - } - - intif_save_petdata(sd->status.account_id,&sd->pet); - pc_makesavestatus(sd); - chrif_save(sd); - storage_storage_save(sd); - map_addblock(&sd->pd->bl); - clif_spawnpet(sd->pd); - clif_send_petdata(sd,0,0); - clif_send_petdata(sd,5,0x14); - clif_pet_equip(sd->pd,sd->pet.equip); - clif_send_petstatus(sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - return 0; -} - -int pet_recv_petdata(int account_id,struct s_pet *p,int flag) -{ - struct map_session_data *sd; - - sd = map_id2sd(account_id); - if(sd == NULL) - return 1; - if(flag == 1) { - sd->status.pet_id = 0; - return 1; - } - memcpy(&sd->pet,p,sizeof(struct s_pet)); - if(sd->pet.incuvate == 1) - pet_birth_process(sd); - else { - pet_data_init(sd); - if(sd->pd && sd->bl.prev != NULL) { - map_addblock(&sd->pd->bl); - clif_spawnpet(sd->pd); - clif_send_petdata(sd,0,0); - clif_send_petdata(sd,5,0x14); -// clif_pet_equip(sd->pd,sd->pet.equip); - clif_send_petstatus(sd); - } - } - if(battle_config.pet_status_support && sd->pet.intimate > 0) { - if(sd->bl.prev != NULL) - status_calc_pc(sd,0); - else - status_calc_pc(sd,2); - } - - return 0; -} - -int pet_select_egg(struct map_session_data *sd,short egg_index) -{ - nullpo_retr(0, sd); - - if(sd->status.inventory[egg_index].card[0] == (short)0xff00) - intif_request_petdata(sd->status.account_id,sd->status.char_id,*((long *)&sd->status.inventory[egg_index].card[1])); - else { - if(battle_config.error_log) - printf("wrong egg item inventory %d\n",egg_index); - } - pc_delitem(sd,egg_index,1,0); - - return 0; -} - -int pet_catch_process1(struct map_session_data *sd,int target_class) -{ - nullpo_retr(0, sd); - - sd->catch_target_class = target_class; - clif_catch_process(sd); - - return 0; -} - -int pet_catch_process2(struct map_session_data *sd,int target_id) -{ - struct mob_data *md; - int i=0,pet_catch_rate=0; - - nullpo_retr(1, sd); - - md=(struct mob_data*)map_id2bl(target_id); - if(!md){ - clif_pet_rulet(sd,0); - return 1; - } - - i = search_petDB_index(md->class_,PET_CLASS); - if(md == NULL || md->bl.type != BL_MOB || md->bl.prev == NULL || i < 0 || sd->catch_target_class != md->class_) { - clif_pet_rulet(sd,0); - return 1; - } - - //target_idによる敵→卵判定 -// if(battle_config.etc_log) -// printf("mob_id = %d, mob_class = %d\n",md->bl.id,md->class_); - //成功の場合 - pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - mob_db[md->class_].lv)*30 + sd->paramc[5]*20)*(200 - md->hp*100/mob_db[md->class_].max_hp)/100; - if(pet_catch_rate < 1) pet_catch_rate = 1; - if(battle_config.pet_catch_rate != 100) - pet_catch_rate = (pet_catch_rate*battle_config.pet_catch_rate)/100; - - if(rand()%10000 < pet_catch_rate) { - mob_remove_map(md,0); - mob_setdelayspawn(md->bl.id); - clif_pet_rulet(sd,1); -// if(battle_config.etc_log) -// printf("rulet success %d\n",target_id); - intif_create_pet(sd->status.account_id,sd->status.char_id,pet_db[i].class_,mob_db[pet_db[i].class_].lv, - pet_db[i].EggID,0,pet_db[i].intimate,100,0,1,pet_db[i].jname); - } - else - clif_pet_rulet(sd,0); - - return 0; -} - -int pet_get_egg(int account_id,int pet_id,int flag) -{ - struct map_session_data *sd; - struct item tmp_item; - int i=0,ret=0; - - if(!flag) { - sd = map_id2sd(account_id); - if(sd == NULL) - return 1; - - i = search_petDB_index(sd->catch_target_class,PET_CLASS); - if(i >= 0) { - memset(&tmp_item,0,sizeof(tmp_item)); - tmp_item.nameid = pet_db[i].EggID; - tmp_item.identify = 1; - tmp_item.card[0] = 0xff00; - tmp_item.card[1] = pet_id; - tmp_item.card[3] = sd->pet.rename_flag; - if((ret = pc_additem(sd,&tmp_item,1))) { - clif_additem(sd,0,0,ret); - map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - else - intif_delete_petdata(pet_id); - } - - return 0; -} - -int pet_menu(struct map_session_data *sd,int menunum) -{ - nullpo_retr(0, sd); - - switch(menunum) { - case 0: - clif_send_petstatus(sd); - break; - case 1: - pet_food(sd); - break; - case 2: - pet_performance(sd); - break; - case 3: - pet_return_egg(sd); - break; - case 4: - pet_unequipitem(sd); - break; - } - return 0; -} - -int pet_change_name(struct map_session_data *sd,char *name) -{ - int i; - - nullpo_retr(1, sd); - - if((sd->pd == NULL) || (sd->pet.rename_flag == 1 && battle_config.pet_rename == 0)) - return 1; - - for(i=0;i<24 && name[i];i++){ - if( !(name[i]&0xe0) || name[i]==0x7f) - return 1; - } - - pet_stop_walking(sd->pd,1); - memcpy(sd->pet.name,name,24); - memcpy(sd->pd->name,name,24); - clif_clearchar_area(&sd->pd->bl,0); - clif_spawnpet(sd->pd); - clif_send_petdata(sd,0,0); - clif_send_petdata(sd,5,0x14); - sd->pet.rename_flag = 1; - clif_pet_equip(sd->pd,sd->pet.equip); - clif_send_petstatus(sd); - - return 0; -} - -int pet_equipitem(struct map_session_data *sd,int index) -{ - int nameid; - - nullpo_retr(1, sd); - - nameid = sd->status.inventory[index].nameid; - if(sd->petDB == NULL) - return 1; - if(sd->petDB->AcceID == 0 || nameid != sd->petDB->AcceID || sd->pet.equip != 0) { - clif_equipitemack(sd,0,0,0); - return 1; - } - else { - pc_delitem(sd,index,1,0); - sd->pet.equip = sd->pd->equip = nameid; - status_calc_pc(sd,0); - clif_pet_equip(sd->pd,nameid); - } - - return 0; -} - -int pet_unequipitem(struct map_session_data *sd) -{ - struct item tmp_item; - int nameid,flag; - - nullpo_retr(1, sd); - - if(sd->petDB == NULL) - return 1; - if(sd->pet.equip == 0) - return 1; - - nameid = sd->pet.equip; - sd->pet.equip = sd->pd->equip = 0; - status_calc_pc(sd,0); - clif_pet_equip(sd->pd,0); - memset(&tmp_item,0,sizeof(tmp_item)); - tmp_item.nameid = nameid; - tmp_item.identify = 1; - if((flag = pc_additem(sd,&tmp_item,1))) { - clif_additem(sd,0,0,flag); - map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - - return 0; -} - -int pet_food(struct map_session_data *sd) -{ - int i,k,t; - - nullpo_retr(1, sd); - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(sd->petDB == NULL) - return 1; - i=pc_search_inventory(sd,sd->petDB->FoodID); - if(i < 0) { - clif_pet_food(sd,sd->petDB->FoodID,0); - return 1; - } - pc_delitem(sd,i,1,0); - t = sd->pet.intimate; - if(sd->pet.hungry > 90) - sd->pet.intimate -= sd->petDB->r_full; - else if(sd->pet.hungry > 75) { - if(battle_config.pet_friendly_rate != 100) - k = (sd->petDB->r_hungry * battle_config.pet_friendly_rate)/100; - else - k = sd->petDB->r_hungry; - k = k >> 1; - if(k <= 0) - k = 1; - sd->pet.intimate += k; - } - else { - if(battle_config.pet_friendly_rate != 100) - k = (sd->petDB->r_hungry * battle_config.pet_friendly_rate)/100; - else - k = sd->petDB->r_hungry; - sd->pet.intimate += k; - } - if(sd->pet.intimate <= 0) { - sd->pet.intimate = 0; - if(battle_config.pet_status_support && t > 0) { - if(sd->bl.prev != NULL) - status_calc_pc(sd,0); - else - status_calc_pc(sd,2); - } - } - else if(sd->pet.intimate > 1000) - sd->pet.intimate = 1000; - sd->pet.hungry += sd->petDB->fullness; - if(sd->pet.hungry > 100) - sd->pet.hungry = 100; - - clif_send_petdata(sd,2,sd->pet.hungry); - clif_send_petdata(sd,1,sd->pet.intimate); - clif_pet_food(sd,sd->petDB->FoodID,1); - - return 0; -} - -static int pet_randomwalk(struct pet_data *pd,int tick) -{ - const int retrycount=20; - int speed; - - nullpo_retr(0, pd); - - Assert((pd->msd == 0) || (pd->msd->pd == pd)); - - speed = status_get_speed(&pd->bl); - - if(DIFF_TICK(pd->next_walktime,tick) < 0){ - int i,x,y,c,d=12-pd->move_fail_count; - if(d<5) d=5; - for(i=0;i<retrycount;i++){ - int r=rand(); - x=pd->bl.x+r%(d*2+1)-d; - y=pd->bl.y+r/(d*2+1)%(d*2+1)-d; - if((map_getcell(pd->bl.m,x,y,CELL_CHKPASS))&&( pet_walktoxy(pd,x,y)==0)){ - pd->move_fail_count=0; - break; - } - if(i+1>=retrycount){ - pd->move_fail_count++; - if(pd->move_fail_count>1000){ - if(battle_config.error_log) - printf("PET cant move. hold position %d, class = %d\n",pd->bl.id,pd->class_); - pd->move_fail_count=0; - pet_changestate(pd,MS_DELAY,60000); - return 0; - } - } - } - for(i=c=0;i<pd->walkpath.path_len;i++){ - if(pd->walkpath.path[i]&1) - c+=speed*14/10; - else - c+=speed; - } - pd->next_walktime = tick+rand()%3000+3000+c; - - return 1; - } - return 0; -} - -static int pet_unlocktarget(struct pet_data *pd) -{ - nullpo_retr(0, pd); - - pd->target_id=0; - - return 0; -} - -static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick) -{ - struct map_session_data *sd = pd->msd; - struct mob_data *md = NULL; - int dist,i=0,dx,dy,ret; - int mode,race; - - nullpo_retr(0, pd); - - sd = pd->msd; - - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); - - if(pd->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL) - return 0; - - if(DIFF_TICK(tick,pd->last_thinktime) < MIN_PETTHINKTIME) - return 0; - pd->last_thinktime=tick; - - if(pd->state.state == MS_DELAY || pd->bl.m != sd->bl.m) - return 0; - // ペットによるルート - if(!pd->target_id && pd->lootitem_count < PETLOOT_SIZE && pd->lootitem_count < pd->lootmax && pd->loot==1 && DIFF_TICK(gettick(),pd->lootitem_timer)>0) - map_foreachinarea(pet_ai_sub_hard_lootsearch,pd->bl.m, - pd->bl.x-AREA_SIZE*2,pd->bl.y-AREA_SIZE*2, - pd->bl.x+AREA_SIZE*2,pd->bl.y+AREA_SIZE*2, - BL_ITEM,pd,&i); - - if(sd->pet.intimate > 0) { - dist = distance(sd->bl.x,sd->bl.y,pd->bl.x,pd->bl.y); - if(dist > 12) { - if(pd->target_id > 0) - pet_unlocktarget(pd); - if(pd->timer != -1 && pd->state.state == MS_WALK && distance(pd->to_x,pd->to_y,sd->bl.x,sd->bl.y) < 3) - return 0; - pd->speed = (sd->speed>>1); - if(pd->speed <= 0) - pd->speed = 1; - pet_calc_pos(pd,sd->bl.x,sd->bl.y,sd->dir); - if(pet_walktoxy(pd,pd->to_x,pd->to_y)) - pet_randomwalk(pd,tick); - } - else if(pd->target_id - MAX_FLOORITEM > 0) { - mode=mob_db[pd->class_].mode; - race=mob_db[pd->class_].race; - md=(struct mob_data *)map_id2bl(pd->target_id); - if(md == NULL || md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL || - distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13) - pet_unlocktarget(pd); - else if(mob_db[pd->class_].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race!=4 && race!=6) ) - pet_unlocktarget(pd); - else if(!battle_check_range(&pd->bl,&md->bl,mob_db[pd->class_].range)){ - if(pd->timer != -1 && pd->state.state == MS_WALK && distance(pd->to_x,pd->to_y,md->bl.x,md->bl.y) < 2) - return 0; - if( !pet_can_reach(pd,md->bl.x,md->bl.y)) - pet_unlocktarget(pd); - else { - i=0; - pd->speed = status_get_speed(&pd->bl); - do { - if(i==0) { // 最初はAEGISと同じ方法で検索 - dx=md->bl.x - pd->bl.x; - dy=md->bl.y - pd->bl.y; - if(dx<0) dx++; - else if(dx>0) dx--; - if(dy<0) dy++; - else if(dy>0) dy--; - } - else { // だめならAthena式(ランダム) - dx=md->bl.x - pd->bl.x + rand()%3 - 1; - dy=md->bl.y - pd->bl.y + rand()%3 - 1; - } - ret=pet_walktoxy(pd,pd->bl.x+dx,pd->bl.y+dy); - i++; - } while(ret && i<5); - - if(ret) { // 移動不可能な所からの攻撃なら2歩下る - if(dx<0) dx=2; - else if(dx>0) dx=-2; - if(dy<0) dy=2; - else if(dy>0) dy=-2; - pet_walktoxy(pd,pd->bl.x+dx,pd->bl.y+dy); - } - } - } - else { - if(pd->state.state==MS_WALK) - pet_stop_walking(pd,1); - if(pd->state.state==MS_ATTACK) - return 0; - pet_changestate(pd,MS_ATTACK,0); - } - } - else if(pd->target_id > 0){ // ルート処理 - struct block_list *bl_item; - struct flooritem_data *fitem; - - bl_item = map_id2bl(pd->target_id); - if(bl_item == NULL || bl_item->type != BL_ITEM ||bl_item->m != pd->bl.m || - (dist=distance(pd->bl.x,pd->bl.y,bl_item->x,bl_item->y))>=5){ - // 遠すぎるかアイテムがなくなった - pet_unlocktarget(pd); - } - else if(dist){ - if(pd->timer != -1 && pd->state.state!=MS_ATTACK && (DIFF_TICK(pd->next_walktime,tick)<0 || distance(pd->to_x,pd->to_y,bl_item->x,bl_item->y) <= 0)) - return 0; // 既に移動中 - - pd->next_walktime=tick+500; - dx=bl_item->x - pd->bl.x; - dy=bl_item->y - pd->bl.y; - - ret=pet_walktoxy(pd,pd->bl.x+dx,pd->bl.y+dy); - } - else{ // アイテムまでたどり着いた - fitem = (struct flooritem_data *)bl_item; - if(pd->state.state==MS_ATTACK) - return 0; // 攻撃中 - if(pd->state.state==MS_WALK){ // 歩行中なら停止 - pet_stop_walking(pd,1); - } - if(pd->lootitem_count < PETLOOT_SIZE && pd->lootitem_count < pd->lootmax){ - memcpy(&pd->lootitem[pd->lootitem_count++],&fitem->item_data,sizeof(pd->lootitem[0])); - pd->lootitem_weight += itemdb_search(fitem->item_data.nameid)->weight*fitem->item_data.amount; - } - else if(pd->lootitem_count >= PETLOOT_SIZE || pd->lootitem_count >=pd->lootmax) { - pet_unlocktarget(pd); - return 0; - } - else { - if(pd->lootitem[0].card[0] == (short)0xff00) - intif_delete_petdata(*((long *)(&pd->lootitem[0].card[1]))); - for(i=0;i<PETLOOT_SIZE-1;i++) - memcpy(&pd->lootitem[i],&pd->lootitem[i+1],sizeof(pd->lootitem[0])); - memcpy(&pd->lootitem[PETLOOT_SIZE-1],&fitem->item_data,sizeof(pd->lootitem[0])); - } - map_clearflooritem(bl_item->id); - pet_unlocktarget(pd); - } - } - else { - if(dist <= 3 || (pd->timer != -1 && pd->state.state == MS_WALK && distance(pd->to_x,pd->to_y,sd->bl.x,sd->bl.y) < 3) ) - return 0; - pd->speed = status_get_speed(&pd->bl); - pet_calc_pos(pd,sd->bl.x,sd->bl.y,sd->dir); - if(pet_walktoxy(pd,pd->to_x,pd->to_y)) - pet_randomwalk(pd,tick); - } - } - else { - pd->speed = status_get_speed(&pd->bl); - if(pd->state.state == MS_ATTACK) - pet_stopattack(pd); - pet_randomwalk(pd,tick); - } - - return 0; -} - -static int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) -{ - unsigned int tick; - - nullpo_retr(0, sd); - nullpo_retr(0, ap); - - tick=va_arg(ap,unsigned int); - if(sd->status.pet_id && sd->pd && sd->petDB) - pet_ai_sub_hard(sd->pd,tick); - - return 0; -} - -static int pet_ai_hard(int tid,unsigned int tick,int id,int data) -{ - clif_foreachclient(pet_ai_sub_foreachclient,tick); - - return 0; -} - -int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap) -{ - struct pet_data* pd; - int dist,*itc; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, pd=va_arg(ap,struct pet_data *)); - nullpo_retr(0, itc=va_arg(ap,int *)); - - if(!pd->target_id){ - struct flooritem_data *fitem = (struct flooritem_data *)bl; - struct map_session_data *sd = NULL; - // ルート権無し - if(fitem && fitem->first_get_id>0) - sd = map_id2sd(fitem->first_get_id); - // Removed [Valaris] - //if((pd->lootitem_weight + (itemdb_search(fitem->item_data.))->weight * fitem->item_data.amount) > battle_config.pet_weight) - // return 0; - - if(!pd->lootitem || (pd->lootitem_count >= PETLOOT_SIZE) || (pd->lootitem_count >= pd->lootmax) || (sd && sd->pd != pd)) - return 0; - if(bl->m == pd->bl.m && (dist=distance(pd->bl.x,pd->bl.y,bl->x,bl->y))<5){ - if( pet_can_reach(pd,bl->x,bl->y) // 到達可能性判定 - && rand()%1000<1000/(++(*itc)) ){ // 範囲内PCで等確率にする - pd->target_id=bl->id; - } - } - } - return 0; -} -int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd) -{ - int i,flag=0; - - if(pd){ - if(pd->lootitem) { - for(i=0;i<pd->lootitem_count;i++) { - struct delay_item_drop2 *ditem; - - ditem=(struct delay_item_drop2 *)aCalloc(1,sizeof(struct delay_item_drop2)); - memcpy(&ditem->item_data,&pd->lootitem[i],sizeof(pd->lootitem[0])); - ditem->m = pd->bl.m; - ditem->x = pd->bl.x; - ditem->y = pd->bl.y; - ditem->first_sd = 0; - ditem->second_sd = 0; - ditem->third_sd = 0; - // 落とさないで直接PCのItem欄へ - if(sd){ - if((flag = pc_additem(sd,&ditem->item_data,ditem->item_data.amount))){ - clif_additem(sd,0,0,flag); - map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0); - } - aFree(ditem); - } - else - add_timer(gettick()+540+i,pet_delay_item_drop2,(int)ditem,0); - } - memset(pd->lootitem,0,LOOTITEM_SIZE * sizeof(struct item)); - pd->lootitem_count = 0; - pd->lootitem_weight = 0; - pd->lootitem_timer = gettick()+10000; // 10*1000msの間拾わない - } - } - return 1; -} - -int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data) -{ - struct delay_item_drop2 *ditem; - - ditem=(struct delay_item_drop2 *)id; - - map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0); - - aFree(ditem); - return 0; -} - -/*========================================== - * pet bonus giving skills [Valaris] - *------------------------------------------ - */ -int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd=map_id2sd(id); - struct pet_data *pd; - int timer = 0; - - if(sd==NULL) - return 1; - - pd=sd->pd; - - if(pd==NULL || pd->bl.type!=BL_PET) - return 1; - - if(pd->skillbonustimer != tid) - return 0; - - // determine the time for the next timer - if (pd->state.skillbonus == 0) { - // pet bonuses are not active at the moment, so, - pd->state.skillbonus = 1; - timer = pd->skillduration; // the duration for pet bonuses to be in effect - } else if (pd->state.skillbonus == 1) { - // pet bonuses are already active, so, - pd->state.skillbonus = 0; - timer = pd->skilltimer; // the duration which pet bonuses will be reactivated again - } - - if (pd->state.skillbonus == 1 && sd->petDB) - run_script(sd->petDB->script,0,sd->bl.id,0); - - // add/remove our bonuses, which will be handled by sd->petbonus[] - status_calc_pc(sd, 0); - - // wait for the next timer - if (timer) pd->skillbonustimer=add_timer(gettick()+timer,pet_skill_bonus_timer,sd->bl.id,0); - - return 0; -} - -int pet_recovery_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd=(struct map_session_data*)map_id2bl(id); - struct pet_data *pd; - - if(sd==NULL || sd->bl.type!=BL_PC) - return 1; - - pd=sd->pd; - - if(pd==NULL || pd->bl.type!=BL_PET) - return 1; - - if(pd->skillbonustimer != tid) - return 0; - - if(sd->sc_data[pd->skilltype].timer != -1) - status_change_end(&sd->bl,pd->skilltype,-1); - - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_recovery_timer,sd->bl.id,0); - - return 0; -} - -int pet_heal_timer(int tid,unsigned int tick,int id,int data) -{ - struct map_session_data *sd=(struct map_session_data*)map_id2bl(id); - struct pet_data *pd; - - if(sd==NULL || sd->bl.type!=BL_PC) - return 1; - - pd=sd->pd; - - if(pd==NULL || pd->bl.type!=BL_PET) - return 1; - - if(pd->skillbonustimer != tid) - return 0; - - if(sd->status.hp < sd->status.max_hp * pd->skilltype/100) { - clif_skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->skillval,1); - pc_heal(sd,pd->skillval,0); - } - - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_heal_timer,sd->bl.id,0); - - return 0; -} - -int pet_mag_timer(int tid,unsigned int tick,int id,int data) -{ - struct pet_data *pd; - struct map_session_data *sd=(struct map_session_data*)map_id2bl(id); - - if(sd==NULL || sd->bl.type!=BL_PC) - return 1; - - pd=sd->pd; - - if(pd==NULL || pd->bl.type!=BL_PET) - return 1; - - if(pd->skillbonustimer != tid) - return 0; - - if(sd->status.hp < sd->status.max_hp * pd->skilltype/100 && sd->status.sp < sd->status.max_sp * pd->skillduration/100) { - clif_skill_nodamage(&pd->bl,&sd->bl,PR_MAGNIFICAT,pd->skillval,1); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],pd->skillval,0,0,0,skill_get_time(PR_MAGNIFICAT,pd->skillval),0 ); - } - - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_mag_timer,sd->bl.id,0); - - return 0; -} - -int pet_skillattack_timer(int tid,unsigned int tick,int id,int data) -{ - struct mob_data *md; - struct map_session_data *sd=(struct map_session_data*)map_id2bl(id); - struct pet_data *pd; - - if(sd==NULL || sd->bl.type!=BL_PC) - return 1; - - pd=sd->pd; - - if(pd==NULL || pd->bl.type!=BL_PET) - return 1; - - if(pd->skillbonustimer != tid) - return 0; - - md=(struct mob_data *)map_id2bl(sd->attacktarget); - if(md == NULL || md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL || - distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 6) { - pd->target_id=0; - pd->skillbonustimer=add_timer(gettick()+100,pet_skillattack_timer,sd->bl.id,pd->skillduration); - return 0; - } - - if(md && rand()%100 < sd->pet.intimate*pd->skilltimer/100 ) { - switch(pd->skilltype) - { - case SM_PROVOKE: - //case NPC_POISON: poison is not handled there - skill_castend_nodamage_id(&pd->bl,&md->bl,pd->skilltype,pd->skillval,tick,0); - break; - case BS_HAMMERFALL: - skill_castend_pos2(&pd->bl,md->bl.x,md->bl.y,pd->skilltype,pd->skillval,tick,0); - break; - case WZ_HEAVENDRIVE: - skill_castend_pos2(&pd->bl,md->bl.x,md->bl.y,pd->skilltype,pd->skillval+rand()%100,tick,0); - break; - default: - skill_castend_damage_id(&pd->bl,&md->bl,pd->skilltype,pd->skillval,tick,0); - break; - } - pd->skillbonustimer=add_timer(gettick()+1000,pet_skillattack_timer,sd->bl.id,0); - return 0; - } - - pd->skillbonustimer=add_timer(gettick()+100,pet_skillattack_timer,sd->bl.id,0); - - return 0; -} - -/*========================================== - *ペットデータ読み込み - *------------------------------------------ - */ -int read_petdb() -{ - FILE *fp; - char line[1024]; - int nameid,i,k; - int j=0; - int lines; - char *filename[]={"db/pet_db.txt","db/pet_db2.txt"}; - char *str[32],*p,*np; - - memset(pet_db,0,sizeof(pet_db)); - for(i=0;i<2;i++){ - fp=fopen(filename[i],"r"); - if(fp==NULL){ - if(i>0) - continue; - printf("can't read %s\n",filename[i]); - return -1; - } - lines = 0; - while(fgets(line,1020,fp)){ - - lines++; - - if(line[0] == '/' && line[1] == '/') - continue; - - for(k=0,p=line;k<20;k++){ - if((np=strchr(p,','))!=NULL){ - str[k]=p; - *np=0; - p=np+1; - } else { - str[k]=p; - p+=strlen(p); - } - } - - nameid=atoi(str[0]); - if(nameid<=0 || nameid>2000) - continue; - - //MobID,Name,JName,ItemID,EggID,AcceID,FoodID,"Fullness (1回の餌での満腹度増加率%)","HungryDeray (/min)","R_Hungry (空腹時餌やり親密度増加率%)","R_Full (とても満腹時餌やり親密度減少率%)","Intimate (捕獲時親密度%)","Die (死亡時親密度減少率%)","Capture (捕獲率%)",(Name) - pet_db[j].class_ = nameid; - memcpy(pet_db[j].name,str[1],24); - memcpy(pet_db[j].jname,str[2],24); - pet_db[j].itemID=atoi(str[3]); - pet_db[j].EggID=atoi(str[4]); - pet_db[j].AcceID=atoi(str[5]); - pet_db[j].FoodID=atoi(str[6]); - pet_db[j].fullness=atoi(str[7]); - pet_db[j].hungry_delay=atoi(str[8])*1000; - pet_db[j].r_hungry=atoi(str[9]); - if(pet_db[j].r_hungry <= 0) - pet_db[j].r_hungry=1; - pet_db[j].r_full=atoi(str[10]); - pet_db[j].intimate=atoi(str[11]); - pet_db[j].die=atoi(str[12]); - pet_db[j].capture=atoi(str[13]); - pet_db[j].speed=atoi(str[14]); - pet_db[j].s_perfor=(char)atoi(str[15]); - pet_db[j].talk_convert_class=atoi(str[16]); - pet_db[j].attack_rate=atoi(str[17]); - pet_db[j].defence_attack_rate=atoi(str[18]); - pet_db[j].change_target_rate=atoi(str[19]); - pet_db[j].script = NULL; - if((np=strchr(p,'{'))==NULL) - continue; - pet_db[j].script = parse_script((unsigned char *) np,lines); - j++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n",j,filename[i]); - ShowStatus(tmp_output); - } - return 0; -} - -/*========================================== - * スキル関係初期化処理 - *------------------------------------------ - */ -int do_init_pet(void) -{ - read_petdb(); - - add_timer_func_list(pet_timer,"pet_timer"); - add_timer_func_list(pet_hungry,"pet_hungry"); - add_timer_func_list(pet_ai_hard,"pet_ai_hard"); - add_timer_func_list(pet_skill_bonus_timer,"pet_skill_bonus_timer"); // [Valaris] - add_timer_func_list(pet_recovery_timer,"pet_recovery_timer"); // [Valaris] - add_timer_func_list(pet_mag_timer,"pet_mag_timer"); // [Valaris] - add_timer_func_list(pet_heal_timer,"pet_heal_timer"); // [Valaris] - add_timer_func_list(pet_skillattack_timer,"pet_skillattack_timer"); // [Valaris] - add_timer_interval(gettick()+MIN_PETTHINKTIME,pet_ai_hard,0,0,MIN_PETTHINKTIME); - - return 0; -} - -int do_final_pet(void) { - int i; - for(i = 0;i < MAX_PET_DB; i++) { - if(pet_db[i].script) { - aFree(pet_db[i].script); - } - } - return 0; -} diff --git a/src/map/pet.h b/src/map/pet.h deleted file mode 100644 index 4d81583b1..000000000 --- a/src/map/pet.h +++ /dev/null @@ -1,69 +0,0 @@ -// $Id: pet.h,v 1.2 2004/09/25 05:32:18 MouseJstr Exp $ -#ifndef _PET_H_ -#define _PET_H_ - -#define MAX_PET_DB 300 -#define PETLOOT_SIZE 20 // [Valaris] - -struct pet_db { - int class_; - char name[24],jname[24]; - int itemID; - int EggID; - int AcceID; - int FoodID; - int fullness; - int hungry_delay; - int r_hungry; - int r_full; - int intimate; - int die; - int capture; - int speed; - char s_perfor; - int talk_convert_class; - int attack_rate; - int defence_attack_rate; - int change_target_rate; - char *script; -}; -extern struct pet_db pet_db[MAX_PET_DB]; - -enum { PET_CLASS,PET_CATCH,PET_EGG,PET_EQUIP,PET_FOOD }; - -int pet_hungry_val(struct map_session_data *sd); -int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type); -int pet_stopattack(struct pet_data *pd); -int pet_changestate(struct pet_data *pd,int state,int type); -int pet_walktoxy(struct pet_data *pd,int x,int y); -int pet_stop_walking(struct pet_data *pd,int type); -int search_petDB_index(int key,int type); -int pet_hungry_timer_delete(struct map_session_data *sd); -int pet_remove_map(struct map_session_data *sd); -int pet_data_init(struct map_session_data *sd); -int pet_birth_process(struct map_session_data *sd); -int pet_recv_petdata(int account_id,struct s_pet *p,int flag); -int pet_select_egg(struct map_session_data *sd,short egg_index); -int pet_catch_process1(struct map_session_data *sd,int target_class); -int pet_catch_process2(struct map_session_data *sd,int target_id); -int pet_get_egg(int account_id,int pet_id,int flag); -int pet_menu(struct map_session_data *sd,int menunum); -int pet_change_name(struct map_session_data *sd,char *name); -int pet_equipitem(struct map_session_data *sd,int index); -int pet_unequipitem(struct map_session_data *sd); -int pet_food(struct map_session_data *sd); -int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd); -int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data); -int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap); -int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data); // [Valaris] -int pet_recovery_timer(int tid,unsigned int tick,int id,int data); // [Valaris] -int pet_mag_timer(int tid,unsigned int tick,int id,int data); // [Valaris] -int pet_heal_timer(int tid,unsigned int tick,int id,int data); // [Valaris] -int pet_skillattack_timer(int tid,unsigned int tick,int id,int data); // [Valaris] - -int read_petdb(); -int do_init_pet(void); -int do_final_pet(void); - -#endif - diff --git a/src/map/script.c b/src/map/script.c deleted file mode 100644 index 9602f3505..000000000 --- a/src/map/script.c +++ /dev/null @@ -1,7862 +0,0 @@ -// $Id: script.c 148 2004-09-30 14:05:37Z MouseJstr $ -//#define DEBUG_FUNCIN -//#define DEBUG_DISP -//#define DEBUG_RUN - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#ifndef _WIN32 -#include <sys/time.h> -#endif - -#include <time.h> - -#include "../common/socket.h" -#include "../common/timer.h" -#include "../common/malloc.h" -#include "../common/lock.h" -#include "../common/db.h" - -#include "map.h" -#include "clif.h" -#include "chrif.h" -#include "itemdb.h" -#include "pc.h" -#include "status.h" -#include "script.h" -#include "storage.h" -#include "mob.h" -#include "npc.h" -#include "pet.h" -#include "intif.h" -#include "skill.h" -#include "chat.h" -#include "battle.h" -#include "party.h" -#include "guild.h" -#include "atcommand.h" -#include "log.h" -#include "showmsg.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define SCRIPT_BLOCK_SIZE 256 - -#define FETCH(n, t) \ - if(st->end>st->start+(n)) \ - (t)=conv_num(st,&(st->stack->stack_data[st->start+(n)])); - -enum { LABEL_NEXTLINE=1,LABEL_START }; -static unsigned char * script_buf = NULL; -static int script_pos,script_size; - -char *str_buf; -int str_pos,str_size; -static struct str_data_struct { - int type; - int str; - int backpatch; - int label; - int (*func)(struct script_state *); - int val; - int next; -} *str_data = NULL; -int str_num=LABEL_START,str_data_size; -int str_hash[16]; - -static struct dbt *mapreg_db=NULL; -static struct dbt *mapregstr_db=NULL; -static int mapreg_dirty=-1; -char mapreg_txt[256]="save/mapreg.txt"; -#define MAPREG_AUTOSAVE_INTERVAL (10*1000) - -static struct dbt *scriptlabel_db=NULL; -static struct dbt *userfunc_db=NULL; - -struct dbt* script_get_label_db(){ return scriptlabel_db; } -struct dbt* script_get_userfunc_db(){ if(!userfunc_db) userfunc_db=strdb_init(50); return userfunc_db; } - -int scriptlabel_final(void *k,void *d,va_list ap){ return 0; } -static char pos[11][100] = {"頭","体","左手","右手","ローブ","靴","アクセサリー1","アクセサリー2","頭2","頭3","装着していない"}; - -struct Script_Config script_config; - -static int parse_cmd_if=0; -static int parse_cmd; - -extern int current_equip_item_index; //for New CARS Scripts. It contains Inventory Index of the EQUIP_SCRIPT caller item. [Lupus] - -/*========================================== - * ローカルプロトタイプ宣言 (必要な物のみ) - *------------------------------------------ - */ -unsigned char* parse_subexpr(unsigned char *,int); -int buildin_mes(struct script_state *st); -int buildin_goto(struct script_state *st); -int buildin_callsub(struct script_state *st); -int buildin_callfunc(struct script_state *st); -int buildin_return(struct script_state *st); -int buildin_getarg(struct script_state *st); -int buildin_next(struct script_state *st); -int buildin_close(struct script_state *st); -int buildin_close2(struct script_state *st); -int buildin_menu(struct script_state *st); -int buildin_rand(struct script_state *st); -int buildin_warp(struct script_state *st); -int buildin_areawarp(struct script_state *st); -int buildin_heal(struct script_state *st); -int buildin_itemheal(struct script_state *st); -int buildin_percentheal(struct script_state *st); -int buildin_jobchange(struct script_state *st); -int buildin_input(struct script_state *st); -int buildin_setlook(struct script_state *st); -int buildin_set(struct script_state *st); -int buildin_setarray(struct script_state *st); -int buildin_cleararray(struct script_state *st); -int buildin_copyarray(struct script_state *st); -int buildin_getarraysize(struct script_state *st); -int buildin_deletearray(struct script_state *st); -int buildin_getelementofarray(struct script_state *st); -int buildin_if(struct script_state *st); -int buildin_getitem(struct script_state *st); -int buildin_getitem2(struct script_state *st); -int buildin_makeitem(struct script_state *st); -int buildin_delitem(struct script_state *st); -int buildin_viewpoint(struct script_state *st); -int buildin_countitem(struct script_state *st); -int buildin_checkweight(struct script_state *st); -int buildin_readparam(struct script_state *st); -int buildin_getcharid(struct script_state *st); -int buildin_getpartyname(struct script_state *st); -int buildin_getpartymember(struct script_state *st); -int buildin_getguildname(struct script_state *st); -int buildin_getguildmaster(struct script_state *st); -int buildin_getguildmasterid(struct script_state *st); -int buildin_strcharinfo(struct script_state *st); -int buildin_getequipid(struct script_state *st); -int buildin_getequipname(struct script_state *st); -int buildin_getbrokenid(struct script_state *st); // [Valaris] -int buildin_repair(struct script_state *st); // [Valaris] -int buildin_getequipisequiped(struct script_state *st); -int buildin_getequipisenableref(struct script_state *st); -int buildin_getequipisidentify(struct script_state *st); -int buildin_getequiprefinerycnt(struct script_state *st); -int buildin_getequipweaponlv(struct script_state *st); -int buildin_getequippercentrefinery(struct script_state *st); -int buildin_successrefitem(struct script_state *st); -int buildin_failedrefitem(struct script_state *st); -int buildin_cutin(struct script_state *st); -int buildin_cutincard(struct script_state *st); -int buildin_statusup(struct script_state *st); -int buildin_statusup2(struct script_state *st); -int buildin_bonus(struct script_state *st); -int buildin_bonus2(struct script_state *st); -int buildin_bonus3(struct script_state *st); -int buildin_bonus4(struct script_state *st); -int buildin_skill(struct script_state *st); -int buildin_addtoskill(struct script_state *st); // [Valaris] -int buildin_guildskill(struct script_state *st); -int buildin_getskilllv(struct script_state *st); -int buildin_getgdskilllv(struct script_state *st); -int buildin_basicskillcheck(struct script_state *st); -int buildin_getgmlevel(struct script_state *st); -int buildin_end(struct script_state *st); -int buildin_checkoption(struct script_state *st); -int buildin_setoption(struct script_state *st); -int buildin_setcart(struct script_state *st); -int buildin_checkcart(struct script_state *st); // check cart [Valaris] -int buildin_setfalcon(struct script_state *st); -int buildin_checkfalcon(struct script_state *st); // check falcon [Valaris] -int buildin_setriding(struct script_state *st); -int buildin_checkriding(struct script_state *st); // check for pecopeco [Valaris] -int buildin_savepoint(struct script_state *st); -int buildin_gettimetick(struct script_state *st); -int buildin_gettime(struct script_state *st); -int buildin_gettimestr(struct script_state *st); -int buildin_openstorage(struct script_state *st); -int buildin_guildopenstorage(struct script_state *st); -int buildin_itemskill(struct script_state *st); -int buildin_produce(struct script_state *st); -int buildin_monster(struct script_state *st); -int buildin_areamonster(struct script_state *st); -int buildin_killmonster(struct script_state *st); -int buildin_killmonsterall(struct script_state *st); -int buildin_doevent(struct script_state *st); -int buildin_donpcevent(struct script_state *st); -int buildin_addtimer(struct script_state *st); -int buildin_deltimer(struct script_state *st); -int buildin_addtimercount(struct script_state *st); -int buildin_initnpctimer(struct script_state *st); -int buildin_stopnpctimer(struct script_state *st); -int buildin_startnpctimer(struct script_state *st); -int buildin_setnpctimer(struct script_state *st); -int buildin_getnpctimer(struct script_state *st); -int buildin_attachnpctimer(struct script_state *st); // [celest] -int buildin_detachnpctimer(struct script_state *st); // [celest] -int buildin_announce(struct script_state *st); -int buildin_mapannounce(struct script_state *st); -int buildin_areaannounce(struct script_state *st); -int buildin_getusers(struct script_state *st); -int buildin_getmapusers(struct script_state *st); -int buildin_getareausers(struct script_state *st); -int buildin_getareadropitem(struct script_state *st); -int buildin_enablenpc(struct script_state *st); -int buildin_disablenpc(struct script_state *st); -int buildin_enablearena(struct script_state *st); // Added by RoVeRT -int buildin_disablearena(struct script_state *st); // Added by RoVeRT -int buildin_hideoffnpc(struct script_state *st); -int buildin_hideonnpc(struct script_state *st); -int buildin_sc_start(struct script_state *st); -int buildin_sc_start2(struct script_state *st); -int buildin_sc_end(struct script_state *st); -int buildin_getscrate(struct script_state *st); -int buildin_debugmes(struct script_state *st); -int buildin_catchpet(struct script_state *st); -int buildin_birthpet(struct script_state *st); -int buildin_resetlvl(struct script_state *st); -int buildin_resetstatus(struct script_state *st); -int buildin_resetskill(struct script_state *st); -int buildin_changebase(struct script_state *st); -int buildin_changesex(struct script_state *st); -int buildin_waitingroom(struct script_state *st); -int buildin_delwaitingroom(struct script_state *st); -int buildin_enablewaitingroomevent(struct script_state *st); -int buildin_disablewaitingroomevent(struct script_state *st); -int buildin_getwaitingroomstate(struct script_state *st); -int buildin_warpwaitingpc(struct script_state *st); -int buildin_attachrid(struct script_state *st); -int buildin_detachrid(struct script_state *st); -int buildin_isloggedin(struct script_state *st); -int buildin_setmapflagnosave(struct script_state *st); -int buildin_setmapflag(struct script_state *st); -int buildin_removemapflag(struct script_state *st); -int buildin_pvpon(struct script_state *st); -int buildin_pvpoff(struct script_state *st); -int buildin_gvgon(struct script_state *st); -int buildin_gvgoff(struct script_state *st); -int buildin_emotion(struct script_state *st); -int buildin_maprespawnguildid(struct script_state *st); -int buildin_agitstart(struct script_state *st); // <Agit> -int buildin_agitend(struct script_state *st); -int buildin_agitcheck(struct script_state *st); // <Agitcheck> -int buildin_flagemblem(struct script_state *st); // Flag Emblem -int buildin_getcastlename(struct script_state *st); -int buildin_getcastledata(struct script_state *st); -int buildin_setcastledata(struct script_state *st); -int buildin_requestguildinfo(struct script_state *st); -int buildin_getequipcardcnt(struct script_state *st); -int buildin_successremovecards(struct script_state *st); -int buildin_failedremovecards(struct script_state *st); -int buildin_marriage(struct script_state *st); -int buildin_wedding_effect(struct script_state *st); -int buildin_divorce(struct script_state *st); -int buildin_ispartneron(struct script_state *st); // MouseJstr -int buildin_getpartnerid(struct script_state *st); // MouseJstr -int buildin_warppartner(struct script_state *st); // MouseJstr -int buildin_getitemname(struct script_state *st); -int buildin_makepet(struct script_state *st); -int buildin_getexp(struct script_state *st); -int buildin_getinventorylist(struct script_state *st); -int buildin_getskilllist(struct script_state *st); -int buildin_clearitem(struct script_state *st); -int buildin_classchange(struct script_state *st); -int buildin_misceffect(struct script_state *st); -int buildin_soundeffect(struct script_state *st); -int buildin_soundeffectall(struct script_state *st); -int buildin_setcastledata(struct script_state *st); -int buildin_mapwarp(struct script_state *st); -int buildin_inittimer(struct script_state *st); -int buildin_stoptimer(struct script_state *st); -int buildin_cmdothernpc(struct script_state *st); -int buildin_mobcount(struct script_state *st); -int buildin_strmobinfo(struct script_state *st); // Script for displaying mob info [Valaris] -int buildin_guardian(struct script_state *st); // Script for displaying mob info [Valaris] -int buildin_guardianinfo(struct script_state *st); // Script for displaying mob info [Valaris] -int buildin_petskillbonus(struct script_state *st); // petskillbonus [Valaris] -int buildin_petrecovery(struct script_state *st); // pet skill for curing status [Valaris] -int buildin_petloot(struct script_state *st); // pet looting [Valaris] -int buildin_petheal(struct script_state *st); // pet healing [Valaris] -int buildin_petmag(struct script_state *st); // pet magnificat [Valaris] -int buildin_petskillattack(struct script_state *st); // pet skill attacks [Valaris] -int buildin_skilleffect(struct script_state *st); // skill effects [Celest] -int buildin_npcskilleffect(struct script_state *st); // skill effects for npcs [Valaris] -int buildin_specialeffect(struct script_state *st); // special effect script [Valaris] -int buildin_specialeffect2(struct script_state *st); // special effect script [Valaris] -int buildin_nude(struct script_state *st); // nude [Valaris] -int buildin_gmcommand(struct script_state *st); // [MouseJstr] -int buildin_movenpc(struct script_state *st); // [MouseJstr] -int buildin_message(struct script_state *st); // [MouseJstr] -int buildin_npctalk(struct script_state *st); // [Valaris] -int buildin_hasitems(struct script_state *st); // [Valaris] -int buildin_getlook(struct script_state *st); //Lorky [Lupus] -int buildin_getsavepoint(struct script_state *st); //Lorky [Lupus] -int buildin_npcspeed(struct script_state *st); // [Valaris] -int buildin_npcwalkto(struct script_state *st); // [Valaris] -int buildin_npcstop(struct script_state *st); // [Valaris] -int buildin_getmapxy(struct script_state *st); //get map position for player/npc/pet/mob by Lorky [Lupus] -int buildin_checkoption1(struct script_state *st); // [celest] -int buildin_checkoption2(struct script_state *st); // [celest] -int buildin_guildgetexp(struct script_state *st); // [celest] -int buildin_skilluseid(struct script_state *st); // originally by Qamera [celest] -int buildin_skillusepos(struct script_state *st); // originally by Qamera [celest] -int buildin_logmes(struct script_state *st); // [Lupus] -int buildin_summon(struct script_state *st); // [celest] -int buildin_isnight(struct script_state *st); // [celest] -int buildin_isday(struct script_state *st); // [celest] -int buildin_isequipped(struct script_state *st); // [celest] -int buildin_isequippedcnt(struct script_state *st); // [celest] -int buildin_cardscnt(struct script_state *st); // [Lupus] -int buildin_getrefine(struct script_state *st); // [celest] -int buildin_getusersname(struct script_state *st); //jA commands added [Lupus] -int buildin_dispbottom(struct script_state *st); -int buildin_recovery(struct script_state *st); -int buildin_getpetinfo(struct script_state *st); -int buildin_checkequipedcard(struct script_state *st); -int buildin_globalmes(struct script_state *st); -int buildin_jump_zero(struct script_state *st); -int buildin_select(struct script_state *st); -int buildin_getmapmobs(struct script_state *st); //jA addition end - - -void push_val(struct script_stack *stack,int type,int val); -int run_func(struct script_state *st); - -int mapreg_setreg(int num,int val); -int mapreg_setregstr(int num,const char *str); - -#ifdef PCRE_SUPPORT -int buildin_defpattern(struct script_state *st); // MouseJstr -int buildin_activatepset(struct script_state *st); // MouseJstr -int buildin_deactivatepset(struct script_state *st); // MouseJstr -int buildin_deletepset(struct script_state *st); // MouseJstr -#endif - -struct { - int (*func)(struct script_state *); - char *name; - char *arg; -} buildin_func[]={ - {buildin_mes,"mes","s"}, - {buildin_next,"next",""}, - {buildin_close,"close",""}, - {buildin_close2,"close2",""}, - {buildin_menu,"menu","*"}, - {buildin_goto,"goto","l"}, - {buildin_callsub,"callsub","i*"}, - {buildin_callfunc,"callfunc","s*"}, - {buildin_return,"return","*"}, - {buildin_getarg,"getarg","i"}, - {buildin_jobchange,"jobchange","i*"}, - {buildin_input,"input","*"}, - {buildin_warp,"warp","sii"}, - {buildin_areawarp,"areawarp","siiiisii"}, - {buildin_setlook,"setlook","ii"}, - {buildin_set,"set","ii"}, - {buildin_setarray,"setarray","ii*"}, - {buildin_cleararray,"cleararray","iii"}, - {buildin_copyarray,"copyarray","iii"}, - {buildin_getarraysize,"getarraysize","i"}, - {buildin_deletearray,"deletearray","ii"}, - {buildin_getelementofarray,"getelementofarray","ii"}, - {buildin_if,"if","i*"}, - {buildin_getitem,"getitem","ii**"}, - {buildin_getitem2,"getitem2","iiiiiiiii*"}, - {buildin_makeitem,"makeitem","iisii"}, - {buildin_delitem,"delitem","ii"}, - {buildin_cutin,"cutin","si"}, - {buildin_cutincard,"cutincard","i"}, - {buildin_viewpoint,"viewpoint","iiiii"}, - {buildin_heal,"heal","ii"}, - {buildin_itemheal,"itemheal","ii"}, - {buildin_percentheal,"percentheal","ii"}, - {buildin_rand,"rand","i*"}, - {buildin_countitem,"countitem","i"}, - {buildin_checkweight,"checkweight","ii"}, - {buildin_readparam,"readparam","i*"}, - {buildin_getcharid,"getcharid","i*"}, - {buildin_getpartyname,"getpartyname","i"}, - {buildin_getpartymember,"getpartymember","i"}, - {buildin_getguildname,"getguildname","i"}, - {buildin_getguildmaster,"getguildmaster","i"}, - {buildin_getguildmasterid,"getguildmasterid","i"}, - {buildin_strcharinfo,"strcharinfo","i"}, - {buildin_getequipid,"getequipid","i"}, - {buildin_getequipname,"getequipname","i"}, - {buildin_getbrokenid,"getbrokenid","i"}, // [Valaris] - {buildin_repair,"repair","i"}, // [Valaris] - {buildin_getequipisequiped,"getequipisequiped","i"}, - {buildin_getequipisenableref,"getequipisenableref","i"}, - {buildin_getequipisidentify,"getequipisidentify","i"}, - {buildin_getequiprefinerycnt,"getequiprefinerycnt","i"}, - {buildin_getequipweaponlv,"getequipweaponlv","i"}, - {buildin_getequippercentrefinery,"getequippercentrefinery","i"}, - {buildin_successrefitem,"successrefitem","i"}, - {buildin_failedrefitem,"failedrefitem","i"}, - {buildin_statusup,"statusup","i"}, - {buildin_statusup2,"statusup2","ii"}, - {buildin_bonus,"bonus","ii"}, - {buildin_bonus2,"bonus2","iii"}, - {buildin_bonus3,"bonus3","iiii"}, - {buildin_bonus4,"bonus4","iiiii"}, - {buildin_skill,"skill","ii*"}, - {buildin_addtoskill,"addtoskill","ii*"}, // [Valaris] - {buildin_guildskill,"guildskill","ii"}, - {buildin_getskilllv,"getskilllv","i"}, - {buildin_getgdskilllv,"getgdskilllv","ii"}, - {buildin_basicskillcheck,"basicskillcheck","*"}, - {buildin_getgmlevel,"getgmlevel","*"}, - {buildin_end,"end",""}, - {buildin_end,"break",""}, - {buildin_checkoption,"checkoption","i"}, - {buildin_setoption,"setoption","i"}, - {buildin_setcart,"setcart",""}, - {buildin_checkcart,"checkcart","*"}, //fixed by Lupus (added '*') - {buildin_setfalcon,"setfalcon",""}, - {buildin_checkfalcon,"checkfalcon","*"}, //fixed by Lupus (fixed wrong pointer, added '*') - {buildin_setriding,"setriding",""}, - {buildin_checkriding,"checkriding","*"}, //fixed by Lupus (fixed wrong pointer, added '*') - {buildin_savepoint,"save","sii"}, - {buildin_savepoint,"savepoint","sii"}, - {buildin_gettimetick,"gettimetick","i"}, - {buildin_gettime,"gettime","i"}, - {buildin_gettimestr,"gettimestr","si"}, - {buildin_openstorage,"openstorage",""}, - {buildin_guildopenstorage,"guildopenstorage","*"}, - {buildin_itemskill,"itemskill","iis"}, - {buildin_produce,"produce","i"}, - {buildin_monster,"monster","siisii*"}, - {buildin_areamonster,"areamonster","siiiisii*"}, - {buildin_killmonster,"killmonster","ss"}, - {buildin_killmonsterall,"killmonsterall","s"}, - {buildin_doevent,"doevent","s"}, - {buildin_donpcevent,"donpcevent","s"}, - {buildin_addtimer,"addtimer","is"}, - {buildin_deltimer,"deltimer","s"}, - {buildin_addtimercount,"addtimercount","si"}, - {buildin_initnpctimer,"initnpctimer","*"}, - {buildin_stopnpctimer,"stopnpctimer","*"}, - {buildin_startnpctimer,"startnpctimer","*"}, - {buildin_setnpctimer,"setnpctimer","*"}, - {buildin_getnpctimer,"getnpctimer","i*"}, - {buildin_attachnpctimer,"attachnpctimer","*"}, // attached the player id to the npc timer [Celest] - {buildin_detachnpctimer,"detachnpctimer","*"}, // detached the player id from the npc timer [Celest] - {buildin_announce,"announce","si"}, - {buildin_mapannounce,"mapannounce","ssi"}, - {buildin_areaannounce,"areaannounce","siiiisi"}, - {buildin_getusers,"getusers","i"}, - {buildin_getmapusers,"getmapusers","s"}, - {buildin_getareausers,"getareausers","siiii"}, - {buildin_getareadropitem,"getareadropitem","siiiii"}, - {buildin_enablenpc,"enablenpc","s"}, - {buildin_disablenpc,"disablenpc","s"}, - {buildin_enablearena,"enablearena",""}, // Added by RoVeRT - {buildin_disablearena,"disablearena",""}, // Added by RoVeRT - {buildin_hideoffnpc,"hideoffnpc","s"}, - {buildin_hideonnpc,"hideonnpc","s"}, - {buildin_sc_start,"sc_start","iii*"}, - {buildin_sc_start2,"sc_start2","iiii*"}, - {buildin_sc_end,"sc_end","i"}, - {buildin_getscrate,"getscrate","ii*"}, - {buildin_debugmes,"debugmes","s"}, - {buildin_catchpet,"pet","i"}, - {buildin_birthpet,"bpet",""}, - {buildin_resetlvl,"resetlvl","i"}, - {buildin_resetstatus,"resetstatus",""}, - {buildin_resetskill,"resetskill",""}, - {buildin_changebase,"changebase","i"}, - {buildin_changesex,"changesex",""}, - {buildin_waitingroom,"waitingroom","si*"}, - {buildin_warpwaitingpc,"warpwaitingpc","sii"}, - {buildin_delwaitingroom,"delwaitingroom","*"}, - {buildin_enablewaitingroomevent,"enablewaitingroomevent","*"}, - {buildin_disablewaitingroomevent,"disablewaitingroomevent","*"}, - {buildin_getwaitingroomstate,"getwaitingroomstate","i*"}, - {buildin_warpwaitingpc,"warpwaitingpc","sii*"}, - {buildin_attachrid,"attachrid","i"}, - {buildin_detachrid,"detachrid",""}, - {buildin_isloggedin,"isloggedin","i"}, - {buildin_setmapflagnosave,"setmapflagnosave","ssii"}, - {buildin_setmapflag,"setmapflag","si"}, - {buildin_removemapflag,"removemapflag","si"}, - {buildin_pvpon,"pvpon","s"}, - {buildin_pvpoff,"pvpoff","s"}, - {buildin_gvgon,"gvgon","s"}, - {buildin_gvgoff,"gvgoff","s"}, - {buildin_emotion,"emotion","i"}, - {buildin_maprespawnguildid,"maprespawnguildid","sii"}, - {buildin_agitstart,"agitstart",""}, // <Agit> - {buildin_agitend,"agitend",""}, - {buildin_agitcheck,"agitcheck","i"}, // <Agitcheck> - {buildin_flagemblem,"flagemblem","i"}, // Flag Emblem - {buildin_getcastlename,"getcastlename","s"}, - {buildin_getcastledata,"getcastledata","si*"}, - {buildin_setcastledata,"setcastledata","sii"}, - {buildin_requestguildinfo,"requestguildinfo","i*"}, - {buildin_getequipcardcnt,"getequipcardcnt","i"}, - {buildin_successremovecards,"successremovecards","i"}, - {buildin_failedremovecards,"failedremovecards","ii"}, - {buildin_marriage,"marriage","s"}, - {buildin_wedding_effect,"wedding",""}, - {buildin_divorce,"divorce","*"}, - {buildin_ispartneron,"ispartneron","*"}, - {buildin_getpartnerid,"getpartnerid","*"}, - {buildin_warppartner,"warppartner","sii"}, - {buildin_getitemname,"getitemname","i"}, - {buildin_makepet,"makepet","i"}, - {buildin_getexp,"getexp","ii"}, - {buildin_getinventorylist,"getinventorylist",""}, - {buildin_getskilllist,"getskilllist",""}, - {buildin_clearitem,"clearitem",""}, - {buildin_classchange,"classchange","ii"}, - {buildin_misceffect,"misceffect","i"}, - {buildin_soundeffect,"soundeffect","si"}, - {buildin_soundeffectall,"soundeffectall","si"}, // SoundEffectAll [Codemaster] - {buildin_strmobinfo,"strmobinfo","ii"}, // display mob data [Valaris] - {buildin_guardian,"guardian","siisii*i"}, // summon guardians - {buildin_guardianinfo,"guardianinfo","i"}, // display guardian data [Valaris] - {buildin_petskillbonus,"petskillbonus","iiii"}, // [Valaris] - {buildin_petrecovery,"petrecovery","ii"}, // [Valaris] - {buildin_petloot,"petloot","i"}, // [Valaris] - {buildin_petheal,"petheal","iii"}, // [Valaris] - {buildin_petmag,"petmag","iiii"}, // [Valaris] - {buildin_petskillattack,"petskillattack","iiii"}, // [Valaris] - {buildin_skilleffect,"skilleffect","ii"}, // skill effect [Celest] - {buildin_npcskilleffect,"npcskilleffect","iiii"}, // npc skill effect [Valaris] - {buildin_specialeffect,"specialeffect","i"}, // npc skill effect [Valaris] - {buildin_specialeffect2,"specialeffect2","i"}, // skill effect on players[Valaris] - {buildin_nude,"nude",""}, // nude command [Valaris] - {buildin_mapwarp,"mapwarp","ssii"}, // Added by RoVeRT - {buildin_inittimer,"inittimer",""}, - {buildin_stoptimer,"stoptimer",""}, - {buildin_cmdothernpc,"cmdothernpc","ss"}, - {buildin_gmcommand,"gmcommand","*"}, // [MouseJstr] -// {buildin_movenpc,"movenpc","siis"}, // [MouseJstr] - {buildin_message,"message","s*"}, // [MouseJstr] - {buildin_npctalk,"npctalk","*"}, // [Valaris] - {buildin_hasitems,"hasitems","*"}, // [Valaris] - {buildin_mobcount,"mobcount","ss"}, - {buildin_getlook,"getlook","i"}, - {buildin_getsavepoint,"getsavepoint","i"}, - {buildin_npcspeed,"npcspeed","i"}, // [Valaris] - {buildin_npcwalkto,"npcwalkto","ii"}, // [Valaris] - {buildin_npcstop,"npcstop",""}, // [Valaris] - {buildin_getmapxy,"getmapxy","siii*"}, //by Lorky [Lupus] - {buildin_checkoption1,"checkoption1","i"}, - {buildin_checkoption2,"checkoption2","i"}, - {buildin_guildgetexp,"guildgetexp","i"}, - {buildin_skilluseid,"skilluseid","ii"}, // originally by Qamera [Celest] - {buildin_skilluseid,"doskill","ii"}, // since a lot of scripts would already use 'doskill'... - {buildin_skillusepos,"skillusepos","iiii"}, // [Celest] - {buildin_logmes,"logmes","s"}, //this command actls as MES but prints info into LOG file either SQL/TXT [Lupus] - {buildin_summon,"summon","si*"}, // summons a slave monster [Celest] - {buildin_isnight,"isnight",""}, // check whether it is night time [Celest] - {buildin_isday,"isday",""}, // check whether it is day time [Celest] - {buildin_isequipped,"isequipped","i*"}, // check whether another item/card has been equipped [Celest] - {buildin_isequippedcnt,"isequippedcnt","i*"}, // check how many items/cards are being equipped [Celest] - {buildin_cardscnt,"cardscnt","i*"}, // check how many items/cards are being equipped in the same arm [Lupus] - {buildin_getrefine,"getrefine",""}, // returns the refined number of the current item, or an item with index specified [celest] -#ifdef PCRE_SUPPORT - {buildin_defpattern, "defpattern", "iss"}, // Define pattern to listen for [MouseJstr] - {buildin_activatepset, "activatepset", "i"}, // Activate a pattern set [MouseJstr] - {buildin_deactivatepset, "deactivatepset", "i"}, // Deactive a pattern set [MouseJstr] - {buildin_deletepset, "deletepset", "i"}, // Delete a pattern set [MouseJstr] -#endif - {buildin_dispbottom,"dispbottom","s"}, //added from jA [Lupus] - {buildin_getusersname,"getusersname","*"}, - {buildin_recovery,"recovery",""}, - {buildin_getpetinfo,"getpetinfo","i"}, - {buildin_checkequipedcard,"checkequipedcard","i"}, - {buildin_jump_zero,"jump_zero","ii"}, //for future jA script compatibility - {buildin_select,"select","*"}, //for future jA script compatibility - {buildin_globalmes,"globalmes","s*"}, - {buildin_getmapmobs,"getmapmobs","s"}, //end jA addition - {NULL,NULL,NULL}, -}; - -enum { - C_NOP,C_POS,C_INT,C_PARAM,C_FUNC,C_STR,C_CONSTSTR,C_ARG, - C_NAME,C_EOL, C_RETINFO, - - C_LOR,C_LAND,C_LE,C_LT,C_GE,C_GT,C_EQ,C_NE, //operator - C_XOR,C_OR,C_AND,C_ADD,C_SUB,C_MUL,C_DIV,C_MOD,C_NEG,C_LNOT,C_NOT,C_R_SHIFT,C_L_SHIFT -}; - -/*========================================== - * 文字列のハッシュを計算 - *------------------------------------------ - */ -static int calc_hash(const unsigned char *p) -{ - int h=0; - while(*p){ - h=(h<<1)+(h>>3)+(h>>5)+(h>>8); - h+=*p++; - } - return h&15; -} - -/*========================================== - * str_dataの中に名前があるか検索する - *------------------------------------------ - */ -// 既存のであれば番号、無ければ-1 -static int search_str(const unsigned char *p) -{ - int i; - i=str_hash[calc_hash(p)]; - while(i){ - if(strcmp(str_buf+str_data[i].str,(char *) p)==0){ - return i; - } - i=str_data[i].next; - } - return -1; -} - -/*========================================== - * str_dataに名前を登録 - *------------------------------------------ - */ -// 既存のであれば番号、無ければ登録して新規番号 -static int add_str(const unsigned char *p) -{ - int i; - char *lowcase; - - lowcase=aStrdup((char *) p); - for(i=0;lowcase[i];i++) - lowcase[i]=tolower(lowcase[i]); - if((i=search_str((unsigned char *) lowcase))>=0){ - aFree(lowcase); - return i; - } - aFree(lowcase); - - i=calc_hash(p); - if(str_hash[i]==0){ - str_hash[i]=str_num; - } else { - i=str_hash[i]; - for(;;){ - if(strcmp(str_buf+str_data[i].str,(char *) p)==0){ - return i; - } - if(str_data[i].next==0) - break; - i=str_data[i].next; - } - str_data[i].next=str_num; - } - if(str_num>=str_data_size){ - str_data_size+=128; - str_data=(struct str_data_struct *) aRealloc(str_data,sizeof(str_data[0])*str_data_size); - memset(str_data + (str_data_size - 128), '\0', 128); - } - while(str_pos+(int)strlen((char *) p)+1>=str_size){ - str_size+=256; - str_buf=(char *)aRealloc(str_buf,str_size); - memset(str_buf + (str_size - 256), '\0', 256); - } - strcpy(str_buf+str_pos, (char *) p); - str_data[str_num].type=C_NOP; - str_data[str_num].str=str_pos; - str_data[str_num].next=0; - str_data[str_num].func=NULL; - str_data[str_num].backpatch=-1; - str_data[str_num].label=-1; - str_pos+=strlen( (char *) p)+1; - return str_num++; -} - - -/*========================================== - * スクリプトバッファサイズの確認と拡張 - *------------------------------------------ - */ -static void check_script_buf(int size) -{ - if(script_pos+size>=script_size){ - script_size+=SCRIPT_BLOCK_SIZE; - script_buf=(unsigned char *)aRealloc(script_buf,script_size); - memset(script_buf + script_size - SCRIPT_BLOCK_SIZE, '\0', - SCRIPT_BLOCK_SIZE); - } -} - -/*========================================== - * スクリプトバッファに1バイト書き込む - *------------------------------------------ - */ -static void add_scriptb(int a) -{ - check_script_buf(1); - script_buf[script_pos++]=a; -} - -/*========================================== - * スクリプトバッファにデータタイプを書き込む - *------------------------------------------ - */ -static void add_scriptc(int a) -{ - while(a>=0x40){ - add_scriptb((a&0x3f)|0x40); - a=(a-0x40)>>6; - } - add_scriptb(a&0x3f); -} - -/*========================================== - * スクリプトバッファに整数を書き込む - *------------------------------------------ - */ -static void add_scripti(int a) -{ - while(a>=0x40){ - add_scriptb(a|0xc0); - a=(a-0x40)>>6; - } - add_scriptb(a|0x80); -} - -/*========================================== - * スクリプトバッファにラベル/変数/関数を書き込む - *------------------------------------------ - */ -// 最大16Mまで -static void add_scriptl(int l) -{ - int backpatch = str_data[l].backpatch; - - switch(str_data[l].type){ - case C_POS: - add_scriptc(C_POS); - add_scriptb(str_data[l].label); - add_scriptb(str_data[l].label>>8); - add_scriptb(str_data[l].label>>16); - break; - case C_NOP: - // ラベルの可能性があるのでbackpatch用データ埋め込み - add_scriptc(C_NAME); - str_data[l].backpatch=script_pos; - add_scriptb(backpatch); - add_scriptb(backpatch>>8); - add_scriptb(backpatch>>16); - break; - case C_INT: - add_scripti(str_data[l].val); - break; - default: - // もう他の用途と確定してるので数字をそのまま - add_scriptc(C_NAME); - add_scriptb(l); - add_scriptb(l>>8); - add_scriptb(l>>16); - break; - } -} - -/*========================================== - * ラベルを解決する - *------------------------------------------ - */ -void set_label(int l,int pos) -{ - int i,next; - - str_data[l].type=C_POS; - str_data[l].label=pos; - for(i=str_data[l].backpatch;i>=0 && i!=0x00ffffff;){ - next=(*(int*)(script_buf+i)) & 0x00ffffff; - script_buf[i-1]=C_POS; - script_buf[i]=pos; - script_buf[i+1]=pos>>8; - script_buf[i+2]=pos>>16; - i=next; - } -} - -/*========================================== - * スペース/コメント読み飛ばし - *------------------------------------------ - */ -static unsigned char *skip_space(unsigned char *p) -{ - while(1){ - while(isspace(*p)) - p++; - if(p[0]=='/' && p[1]=='/'){ - while(*p && *p!='\n') - p++; - } else if(p[0]=='/' && p[1]=='*'){ - p++; - while(*p && (p[-1]!='*' || p[0]!='/')) - p++; - if(*p) p++; - } else - break; - } - return p; -} - -/*========================================== - * 1単語スキップ - *------------------------------------------ - */ -static unsigned char *skip_word(unsigned char *p) -{ - // prefix - if(*p=='$') p++; // MAP鯖内共有変数用 - if(*p=='@') p++; // 一時的変数用(like weiss) - if(*p=='#') p++; // account変数用 - if(*p=='#') p++; // ワールドaccount変数用 - if(*p=='l') p++; // 一時的変数用(like weiss) - - while(isalnum(*p)||*p=='_'|| *p>=0x81) - if(*p>=0x81 && p[1]){ - p+=2; - } else - p++; - - // postfix - if(*p=='$') p++; // 文字列変数 - - return p; -} - -static unsigned char *startptr; -static int startline; - -/*========================================== - * エラーメッセージ出力 - *------------------------------------------ - */ -static void disp_error_message(const char *mes,const unsigned char *pos) -{ - int line,c=0,i; - unsigned char *p,*linestart,*lineend; - - for(line=startline,p=startptr;p && *p;line++){ - linestart=p; - lineend=(unsigned char *) strchr((char *) p,'\n'); - if(lineend){ - c=*lineend; - *lineend=0; - } - if(lineend==NULL || pos<lineend){ - if (current_file) { - printf("%s in "CL_WHITE"\'%s\'"CL_RESET" line "CL_WHITE"\'%d\'"CL_RESET" : ", mes, current_file, line); - } else { - printf("%s line "CL_WHITE"\'%d\'"CL_RESET" : ", mes, line); - } - for(i=0;(linestart[i]!='\r') && (linestart[i]!='\n') && linestart[i];i++){ - if(linestart+i!=pos) - printf("%c",linestart[i]); - else - printf("\'%c\'",linestart[i]); - } - printf("\a\n"); - if(lineend) - *lineend=c; - return; - } - *lineend=c; - p=lineend+1; - } -} - -/*========================================== - * 項の解析 - *------------------------------------------ - */ -unsigned char* parse_simpleexpr(unsigned char *p) -{ - int i; - p=skip_space(p); - -#ifdef DEBUG_FUNCIN - if(battle_config.etc_log) - printf("parse_simpleexpr %s\n",p); -#endif - if(*p==';' || *p==','){ - disp_error_message("unexpected expr end",p); - exit(1); - } - if(*p=='('){ - - p=parse_subexpr(p+1,-1); - p=skip_space(p); - if((*p++)!=')'){ - disp_error_message("unmatch ')'",p); - exit(1); - } - } else if(isdigit(*p) || ((*p=='-' || *p=='+') && isdigit(p[1]))){ - char *np; - i=strtoul((char *) p,&np,0); - add_scripti(i); - p=(unsigned char *) np; - } else if(*p=='"'){ - add_scriptc(C_STR); - p++; - while(*p && *p!='"'){ - if(p[-1]<=0x7e && *p=='\\') - p++; - else if(*p=='\n'){ - disp_error_message("unexpected newline @ string",p); - exit(1); - } - add_scriptb(*p++); - } - if(!*p){ - disp_error_message("unexpected eof @ string",p); - exit(1); - } - add_scriptb(0); - p++; //'"' - } else { - int c,l; - char *p2; - // label , register , function etc - if(skip_word(p)==p){ - disp_error_message("unexpected character",p); - exit(1); - } - p2=(char *) skip_word(p); - c=*p2; *p2=0; // 名前をadd_strする - l=add_str(p); - - parse_cmd=l; // warn_*_mismatch_paramnumのために必要 - if(l== search_str((unsigned char *) "if")) // warn_cmd_no_commaのために必要 - parse_cmd_if++; -/* - // 廃止予定のl14/l15,およびプレフィックスlの警告 - if( strcmp(str_buf+str_data[l].str,"l14")==0 || - strcmp(str_buf+str_data[l].str,"l15")==0 ){ - disp_error_message("l14 and l15 is DEPRECATED. use @menu instead of l15.",p); - }else if(str_buf[str_data[l].str]=='l'){ - disp_error_message("prefix 'l' is DEPRECATED. use prefix '@' instead.",p2); - } -*/ - *p2=c; - p=(unsigned char *) p2; - - if(str_data[l].type!=C_FUNC && c=='['){ - // array(name[i] => getelementofarray(name,i) ) - add_scriptl(search_str((unsigned char *) "getelementofarray")); - add_scriptc(C_ARG); - add_scriptl(l); - p=parse_subexpr(p+1,-1); - p=skip_space(p); - if((*p++)!=']'){ - disp_error_message("unmatch ']'",p); - exit(1); - } - add_scriptc(C_FUNC); - }else - add_scriptl(l); - - } - -#ifdef DEBUG_FUNCIN - if(battle_config.etc_log) - printf("parse_simpleexpr end %s\n",p); -#endif - return p; -} - -/*========================================== - * 式の解析 - *------------------------------------------ - */ -unsigned char* parse_subexpr(unsigned char *p,int limit) -{ - int op,opl,len; - char *tmpp; - -#ifdef DEBUG_FUNCIN - if(battle_config.etc_log) - printf("parse_subexpr %s\n",p); -#endif - p=skip_space(p); - - if(*p=='-'){ - tmpp=(char *) skip_space((unsigned char *) (p+1)); - if(*tmpp==';' || *tmpp==','){ - add_scriptl(LABEL_NEXTLINE); - p++; - return p; - } - } - tmpp=(char *) p; - if((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')){ - p=parse_subexpr(p+1,100); - add_scriptc(op); - } else - p=parse_simpleexpr(p); - p=skip_space(p); - while(((op=C_ADD,opl=6,len=1,*p=='+') || - (op=C_SUB,opl=6,len=1,*p=='-') || - (op=C_MUL,opl=7,len=1,*p=='*') || - (op=C_DIV,opl=7,len=1,*p=='/') || - (op=C_MOD,opl=7,len=1,*p=='%') || - (op=C_FUNC,opl=8,len=1,*p=='(') || - (op=C_LAND,opl=1,len=2,*p=='&' && p[1]=='&') || - (op=C_AND,opl=5,len=1,*p=='&') || - (op=C_LOR,opl=0,len=2,*p=='|' && p[1]=='|') || - (op=C_OR,opl=4,len=1,*p=='|') || - (op=C_XOR,opl=3,len=1,*p=='^') || - (op=C_EQ,opl=2,len=2,*p=='=' && p[1]=='=') || - (op=C_NE,opl=2,len=2,*p=='!' && p[1]=='=') || - (op=C_R_SHIFT,opl=5,len=2,*p=='>' && p[1]=='>') || - (op=C_GE,opl=2,len=2,*p=='>' && p[1]=='=') || - (op=C_GT,opl=2,len=1,*p=='>') || - (op=C_L_SHIFT,opl=5,len=2,*p=='<' && p[1]=='<') || - (op=C_LE,opl=2,len=2,*p=='<' && p[1]=='=') || - (op=C_LT,opl=2,len=1,*p=='<')) && opl>limit){ - p+=len; - if(op==C_FUNC){ - int i=0,func=parse_cmd; - const char *plist[128]; - - if( str_data[func].type!=C_FUNC ){ - disp_error_message("expect function",(unsigned char *) tmpp); - exit(0); - } - - add_scriptc(C_ARG); - do { - plist[i]=(char *) p; - p=parse_subexpr(p,-1); - p=skip_space(p); - if(*p==',') p++; - else if(*p!=')' && script_config.warn_func_no_comma){ - disp_error_message("expect ',' or ')' at func params",p); - } - p=skip_space(p); - i++; - } while(*p && *p!=')' && i<128); - plist[i]=(char *) p; - if(*(p++)!=')'){ - disp_error_message("func request '(' ')'",p); - exit(1); - } - - if( str_data[func].type==C_FUNC && script_config.warn_func_mismatch_paramnum){ - const char *arg=buildin_func[str_data[func].val].arg; - int j=0; - for(j=0;arg[j];j++) if(arg[j]=='*')break; - if( (arg[j]==0 && i!=j) || (arg[j]=='*' && i<j) ){ - disp_error_message("illegal number of parameters",(unsigned char *) (plist[(i<j)?i:j])); - } - } - } else { - p=parse_subexpr(p,opl); - } - add_scriptc(op); - p=skip_space(p); - } -#ifdef DEBUG_FUNCIN - if(battle_config.etc_log) - printf("parse_subexpr end %s\n",p); -#endif - return p; /* return first untreated operator */ -} - -/*========================================== - * 式の評価 - *------------------------------------------ - */ -unsigned char* parse_expr(unsigned char *p) -{ -#ifdef DEBUG_FUNCIN - if(battle_config.etc_log) - printf("parse_expr %s\n",p); -#endif - switch(*p){ - case ')': case ';': case ':': case '[': case ']': - case '}': - disp_error_message("unexpected char",p); - exit(1); - } - p=parse_subexpr(p,-1); -#ifdef DEBUG_FUNCIN - if(battle_config.etc_log) - printf("parse_expr end %s\n",p); -#endif - return p; -} - -/*========================================== - * 行の解析 - *------------------------------------------ - */ -unsigned char* parse_line(unsigned char *p) -{ - int i=0,cmd; - const char *plist[128]; - char *p2; - - p=skip_space(p); - if(*p==';') - return p; - - parse_cmd_if=0; // warn_cmd_no_commaのために必要 - - // 最初は関数名 - p2=(char *) p; - p=parse_simpleexpr(p); - p=skip_space(p); - - cmd=parse_cmd; - if( str_data[cmd].type!=C_FUNC ){ - disp_error_message("expect command",(unsigned char *) p2); -// exit(0); - } - - add_scriptc(C_ARG); - while(p && *p && *p!=';' && i<128){ - plist[i]=(char *) p; - - p=parse_expr(p); - p=skip_space(p); - // 引数区切りの,処理 - if(*p==',') p++; - else if(*p!=';' && script_config.warn_cmd_no_comma && parse_cmd_if*2<=i ){ - disp_error_message("expect ',' or ';' at cmd params",p); - } - p=skip_space(p); - i++; - } - plist[i]=(char *) p; - if(!p || *(p++)!=';'){ - disp_error_message("need ';'",p); - exit(1); - } - add_scriptc(C_FUNC); - - if( str_data[cmd].type==C_FUNC && script_config.warn_cmd_mismatch_paramnum){ - const char *arg=buildin_func[str_data[cmd].val].arg; - int j=0; - for(j=0;arg[j];j++) if(arg[j]=='*')break; - if( (arg[j]==0 && i!=j) || (arg[j]=='*' && i<j) ){ - disp_error_message("illegal number of parameters",(unsigned char *) (plist[(i<j)?i:j])); - } - } - - - return p; -} - -/*========================================== - * 組み込み関数の追加 - *------------------------------------------ - */ -static void add_buildin_func(void) -{ - int i,n; - for(i=0;buildin_func[i].func;i++){ - n=add_str((unsigned char *) buildin_func[i].name); - str_data[n].type=C_FUNC; - str_data[n].val=i; - str_data[n].func=buildin_func[i].func; - } -} - -/*========================================== - * 定数データベースの読み込み - *------------------------------------------ - */ -static void read_constdb(void) -{ - FILE *fp; - char line[1024],name[1024]; - int val,n,i,type; - - fp=fopen("db/const.txt","r"); - if(fp==NULL){ - printf("can't read db/const.txt\n"); - return ; - } - while(fgets(line,1020,fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - type=0; - if(sscanf(line,"%[A-Za-z0-9_],%d,%d",name,&val,&type)>=2 || - sscanf(line,"%[A-Za-z0-9_] %d %d",name,&val,&type)>=2){ - for(i=0;name[i];i++) - name[i]=tolower(name[i]); - n=add_str((const unsigned char *) name); - if(type==0) - str_data[n].type=C_INT; - else - str_data[n].type=C_PARAM; - str_data[n].val=val; - } - } - fclose(fp); -} - -/*========================================== - * スクリプトの解析 - *------------------------------------------ - */ -char* parse_script(unsigned char *src,int line) -{ - unsigned char *p,*tmpp; - int i; - static int first=1; - - if(first){ - add_buildin_func(); - read_constdb(); - } - first=0; - script_buf=(unsigned char *)aCallocA(SCRIPT_BLOCK_SIZE,sizeof(unsigned char)); - script_pos=0; - script_size=SCRIPT_BLOCK_SIZE; - str_data[LABEL_NEXTLINE].type=C_NOP; - str_data[LABEL_NEXTLINE].backpatch=-1; - str_data[LABEL_NEXTLINE].label=-1; - for(i=LABEL_START;i<str_num;i++){ - if(str_data[i].type==C_POS || str_data[i].type==C_NAME){ - str_data[i].type=C_NOP; - str_data[i].backpatch=-1; - str_data[i].label=-1; - } - } - - // 外部用label dbの初期化 - if(scriptlabel_db!=NULL) - strdb_final(scriptlabel_db,scriptlabel_final); - scriptlabel_db=strdb_init(50); - - // for error message - startptr = src; - startline = line; - - p=src; - p=skip_space(p); - if(*p!='{'){ - disp_error_message("not found '{'",p); - return NULL; - } - for(p++;p && *p && *p!='}';){ - p=skip_space(p); - // labelだけ特殊処理 - tmpp=skip_space(skip_word(p)); - if(*tmpp==':'){ - int l,c; - - c=*skip_word(p); - *skip_word(p)=0; - l=add_str(p); - if(str_data[l].label!=-1){ - *skip_word(p)=c; - disp_error_message("dup label ",p); - exit(1); - } - set_label(l,script_pos); - strdb_insert(scriptlabel_db,p,script_pos); // 外部用label db登録 - *skip_word(p)=c; - p=tmpp+1; - continue; - } - - // 他は全部一緒くた - p=parse_line(p); - p=skip_space(p); - add_scriptc(C_EOL); - - set_label(LABEL_NEXTLINE,script_pos); - str_data[LABEL_NEXTLINE].type=C_NOP; - str_data[LABEL_NEXTLINE].backpatch=-1; - str_data[LABEL_NEXTLINE].label=-1; - } - - add_scriptc(C_NOP); - - script_size = script_pos; - script_buf=(unsigned char *)aRealloc(script_buf,script_pos + 1); - - // 未解決のラベルを解決 - for(i=LABEL_START;i<str_num;i++){ - if(str_data[i].type==C_NOP){ - int j,next; - str_data[i].type=C_NAME; - str_data[i].label=i; - for(j=str_data[i].backpatch;j>=0 && j!=0x00ffffff;){ - next=(*(int*)(script_buf+j)) & 0x00ffffff; - script_buf[j]=i; - script_buf[j+1]=i>>8; - script_buf[j+2]=i>>16; - j=next; - } - } - } - -#ifdef DEBUG_DISP - for(i=0;i<script_pos;i++){ - if((i&15)==0) printf("%04x : ",i); - printf("%02x ",script_buf[i]); - if((i&15)==15) printf("\n"); - } - printf("\n"); -#endif - - return (char *) script_buf; -} - -// -// 実行系 -// -enum {STOP=1,END,RERUNLINE,GOTO,RETFUNC}; - -/*========================================== - * ridからsdへの解決 - *------------------------------------------ - */ -struct map_session_data *script_rid2sd(struct script_state *st) -{ - struct map_session_data *sd=map_id2sd(st->rid); - if(!sd){ - printf("script_rid2sd: fatal error ! player not attached!\n"); - } - return sd; -} - - -/*========================================== - * 変数の読み取り - *------------------------------------------ - */ -int get_val(struct script_state*st,struct script_data* data) -{ - struct map_session_data *sd=NULL; - if(data->type==C_NAME){ - char *name=str_buf+str_data[data->u.num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - - if(prefix!='$'){ - if((sd=script_rid2sd(st))==NULL) - printf("get_val error name?:%s\n",name); - } - if(postfix=='$'){ - - data->type=C_CONSTSTR; - if( prefix=='@' || prefix=='l' ){ - if(sd) - data->u.str = pc_readregstr(sd,data->u.num); - }else if(prefix=='$'){ - data->u.str = (char *)numdb_search(mapregstr_db,data->u.num); - }else{ - printf("script: get_val: illegal scope string variable.\n"); - data->u.str = "!!ERROR!!"; - } - if( data->u.str == NULL ) - data->u.str =""; - - }else{ - - data->type=C_INT; - if(str_data[data->u.num&0x00ffffff].type==C_INT){ - data->u.num = str_data[data->u.num&0x00ffffff].val; - }else if(str_data[data->u.num&0x00ffffff].type==C_PARAM){ - if(sd) - data->u.num = pc_readparam(sd,str_data[data->u.num&0x00ffffff].val); - }else if(prefix=='@' || prefix=='l'){ - if(sd) - data->u.num = pc_readreg(sd,data->u.num); - }else if(prefix=='$'){ - data->u.num = (int)numdb_search(mapreg_db,data->u.num); - }else if(prefix=='#'){ - if( name[1]=='#'){ - if(sd) - data->u.num = pc_readaccountreg2(sd,name); - }else{ - if(sd) - data->u.num = pc_readaccountreg(sd,name); - } - }else{ - if(sd) - data->u.num = pc_readglobalreg(sd,name); - } - } - } - return 0; -} -/*========================================== - * 変数の読み取り2 - *------------------------------------------ - */ -void* get_val2(struct script_state*st,int num) -{ - struct script_data dat; - dat.type=C_NAME; - dat.u.num=num; - get_val(st,&dat); - if( dat.type==C_INT ) return (void*)dat.u.num; - else return (void*)dat.u.str; -} - -/*========================================== - * 変数設定用 - *------------------------------------------ - */ -static int set_reg(struct map_session_data *sd,int num,char *name,void *v) -{ - char prefix=*name; - char postfix=name[strlen(name)-1]; - - if( postfix=='$' ){ - char *str=(char*)v; - if( prefix=='@' || prefix=='l'){ - pc_setregstr(sd,num,str); - }else if(prefix=='$') { - mapreg_setregstr(num,str); - }else{ - printf("script: set_reg: illegal scope string variable !"); - } - }else{ - // 数値 - int val = (int)v; - if(str_data[num&0x00ffffff].type==C_PARAM){ - pc_setparam(sd,str_data[num&0x00ffffff].val,val); - }else if(prefix=='@' || prefix=='l') { - pc_setreg(sd,num,val); - }else if(prefix=='$') { - mapreg_setreg(num,val); - }else if(prefix=='#') { - if( name[1]=='#' ) - pc_setaccountreg2(sd,name,val); - else - pc_setaccountreg(sd,name,val); - }else{ - pc_setglobalreg(sd,name,val); - } - } - return 0; -} - -int set_var(struct map_session_data *sd, char *name, void *val) -{ - return set_reg(sd, add_str((unsigned char *) name), name, val); -} - -/*========================================== - * 文字列への変換 - *------------------------------------------ - */ -char* conv_str(struct script_state *st,struct script_data *data) -{ - get_val(st,data); - if(data->type==C_INT){ - char *buf; - buf=(char *)aCallocA(16,sizeof(char)); - sprintf(buf,"%d",data->u.num); - data->type=C_STR; - data->u.str=buf; -#if 1 - } else if(data->type==C_NAME){ - // テンポラリ。本来無いはず - data->type=C_CONSTSTR; - data->u.str=str_buf+str_data[data->u.num].str; -#endif - } - return data->u.str; -} - -/*========================================== - * 数値へ変換 - *------------------------------------------ - */ -int conv_num(struct script_state *st,struct script_data *data) -{ - char *p; - get_val(st,data); - if(data->type==C_STR || data->type==C_CONSTSTR){ - p=data->u.str; - data->u.num = atoi(p); - if(data->type==C_STR) - aFree(p); - data->type=C_INT; - } - return data->u.num; -} - -/*========================================== - * スタックへ数値をプッシュ - *------------------------------------------ - */ -void push_val(struct script_stack *stack,int type,int val) -{ - if(stack->sp >= stack->sp_max){ - stack->sp_max += 64; - stack->stack_data = (struct script_data *)aRealloc(stack->stack_data, - sizeof(stack->stack_data[0]) * stack->sp_max); - memset(stack->stack_data + (stack->sp_max - 64), 0, - 64 * sizeof(*(stack->stack_data))); - } -// if(battle_config.etc_log) -// printf("push (%d,%d)-> %d\n",type,val,stack->sp); - stack->stack_data[stack->sp].type=type; - stack->stack_data[stack->sp].u.num=val; - stack->sp++; -} - -/*========================================== - * スタックへ文字列をプッシュ - *------------------------------------------ - */ -void push_str(struct script_stack *stack,int type,unsigned char *str) -{ - if(stack->sp>=stack->sp_max){ - stack->sp_max += 64; - stack->stack_data = (struct script_data *)aRealloc(stack->stack_data, - sizeof(stack->stack_data[0]) * stack->sp_max); - memset(stack->stack_data + (stack->sp_max - 64), '\0', - 64 * sizeof(*(stack->stack_data))); - } -// if(battle_config.etc_log) -// printf("push (%d,%x)-> %d\n",type,str,stack->sp); - stack->stack_data[stack->sp].type=type; - stack->stack_data[stack->sp].u.str=(char *) str; - stack->sp++; -} - -/*========================================== - * スタックへ複製をプッシュ - *------------------------------------------ - */ -void push_copy(struct script_stack *stack,int pos) -{ - switch(stack->stack_data[pos].type){ - case C_CONSTSTR: - push_str(stack,C_CONSTSTR,(unsigned char *) stack->stack_data[pos].u.str); - break; - case C_STR: - push_str(stack,C_STR,(unsigned char *) aStrdup(stack->stack_data[pos].u.str)); - break; - default: - push_val(stack,stack->stack_data[pos].type,stack->stack_data[pos].u.num); - break; - } -} - -/*========================================== - * スタックからポップ - *------------------------------------------ - */ -void pop_stack(struct script_stack* stack,int start,int end) -{ - int i; - for(i=start;i<end;i++){ - if(stack->stack_data[i].type==C_STR){ - aFree(stack->stack_data[i].u.str); - } - } - if(stack->sp>end){ - memmove(&stack->stack_data[start],&stack->stack_data[end],sizeof(stack->stack_data[0])*(stack->sp-end)); - } - stack->sp-=end-start; -} - -// -// 埋め込み関数 -// -/*========================================== - * - *------------------------------------------ - */ -int buildin_mes(struct script_state *st) -{ - conv_str(st,& (st->stack->stack_data[st->start+2])); - clif_scriptmes(script_rid2sd(st),st->oid,st->stack->stack_data[st->start+2].u.str); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_goto(struct script_state *st) -{ - int pos; - - if( st->stack->stack_data[st->start+2].type!=C_POS ){ - printf("script: goto: not label!\n"); - st->state=END; - return 0; - } - - pos=conv_num(st,& (st->stack->stack_data[st->start+2])); - st->pos=pos; - st->state=GOTO; - return 0; -} - -/*========================================== - * ユーザー定義関数の呼び出し - *------------------------------------------ - */ -int buildin_callfunc(struct script_state *st) -{ - char *scr; - char *str=conv_str(st,& (st->stack->stack_data[st->start+2])); - - if( (scr=(char *) strdb_search(script_get_userfunc_db(),str)) ){ - int i,j; - for(i=st->start+3,j=0;i<st->end;i++,j++) - push_copy(st->stack,i); - - push_val(st->stack,C_INT,j); // 引数の数をプッシュ - push_val(st->stack,C_INT,st->defsp); // 現在の基準スタックポインタをプッシュ - push_val(st->stack,C_INT,(int)st->script); // 現在のスクリプトをプッシュ - push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ - - st->pos=0; - st->script=scr; - st->defsp=st->start+4+j; - st->state=GOTO; - }else{ - printf("script:callfunc: function not found! [%s]\n",str); - st->state=END; - } - return 0; -} -/*========================================== - * サブルーティンの呼び出し - *------------------------------------------ - */ -int buildin_callsub(struct script_state *st) -{ - int pos=conv_num(st,& (st->stack->stack_data[st->start+2])); - int i,j; - for(i=st->start+3,j=0;i<st->end;i++,j++) - push_copy(st->stack,i); - - push_val(st->stack,C_INT,j); // 引数の数をプッシュ - push_val(st->stack,C_INT,st->defsp); // 現在の基準スタックポインタをプッシュ - push_val(st->stack,C_INT,(int)st->script); // 現在のスクリプトをプッシュ - push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ - - st->pos=pos; - st->defsp=st->start+4+j; - st->state=GOTO; - return 0; -} - -/*========================================== - * 引数の所得 - *------------------------------------------ - */ -int buildin_getarg(struct script_state *st) -{ - int num=conv_num(st,& (st->stack->stack_data[st->start+2])); - int max,stsp; - if( st->defsp<4 || st->stack->stack_data[st->defsp-1].type!=C_RETINFO ){ - printf("script:getarg without callfunc or callsub!\n"); - st->state=END; - return 0; - } - max=conv_num(st,& (st->stack->stack_data[st->defsp-4])); - stsp=st->defsp - max -4; - if( num >= max ){ - printf("script:getarg arg1(%d) out of range(%d) !\n",num,max); - st->state=END; - return 0; - } - push_copy(st->stack,stsp+num); - return 0; -} - -/*========================================== - * サブルーチン/ユーザー定義関数の終了 - *------------------------------------------ - */ -int buildin_return(struct script_state *st) -{ - if(st->end>st->start+2){ // 戻り値有り - push_copy(st->stack,st->start+2); - } - st->state=RETFUNC; - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_next(struct script_state *st) -{ - st->state=STOP; - clif_scriptnext(script_rid2sd(st),st->oid); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_close(struct script_state *st) -{ - st->state=END; - clif_scriptclose(script_rid2sd(st),st->oid); - return 0; -} -int buildin_close2(struct script_state *st) -{ - st->state=STOP; - clif_scriptclose(script_rid2sd(st),st->oid); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_menu(struct script_state *st) -{ - char *buf; - int len,i; - struct map_session_data *sd; - - sd=script_rid2sd(st); - - if(sd->state.menu_or_input==0){ - st->state=RERUNLINE; - sd->state.menu_or_input=1; - for(i=st->start+2,len=16;i<st->end;i+=2){ - conv_str(st,& (st->stack->stack_data[i])); - len+=strlen(st->stack->stack_data[i].u.str)+1; - } - buf=(char *)aCallocA(len+1,sizeof(char)); - buf[0]=0; - for(i=st->start+2,len=0;i<st->end;i+=2){ - strcat(buf,st->stack->stack_data[i].u.str); - strcat(buf,":"); - } - clif_scriptmenu(script_rid2sd(st),st->oid,buf); - aFree(buf); - } else if(sd->npc_menu==0xff){ // cansel - sd->state.menu_or_input=0; - st->state=END; - } else { // goto動作 - // ragemu互換のため - pc_setreg(sd,add_str((unsigned char *) "l15"),sd->npc_menu); - pc_setreg(sd,add_str((unsigned char *) "@menu"),sd->npc_menu); - sd->state.menu_or_input=0; - if(sd->npc_menu>0 && sd->npc_menu<(st->end-st->start)/2){ - int pos; - if( st->stack->stack_data[st->start+sd->npc_menu*2+1].type!=C_POS ){ - printf("script: menu: not label !\n"); - st->state=END; - return 0; - } - pos=conv_num(st,& (st->stack->stack_data[st->start+sd->npc_menu*2+1])); - st->pos=pos; - st->state=GOTO; - } - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_rand(struct script_state *st) -{ - int range; - - if (st->end > st->start+3){ - int min, max; - min = conv_num(st,& (st->stack->stack_data[st->start+2])); - max = conv_num(st,& (st->stack->stack_data[st->start+3])); - if (max < min){ - int tmp = min; - min = max; - max = tmp; - } - range = max - min + 1; - if (range == 0) range = 1; - push_val(st->stack,C_INT,rand()%range+min); - } else { - range = conv_num(st,& (st->stack->stack_data[st->start+2])); - if (range == 0) range = 1; - push_val(st->stack,C_INT,rand()%range); - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_warp(struct script_state *st) -{ - int x,y; - char *str; - struct map_session_data *sd=script_rid2sd(st); - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - x=conv_num(st,& (st->stack->stack_data[st->start+3])); - y=conv_num(st,& (st->stack->stack_data[st->start+4])); - if(strcmp(str,"Random")==0) - pc_randomwarp(sd,3); - else if(strcmp(str,"SavePoint")==0){ - if(map[sd->bl.m].flag.noreturn) // 蝶禁止 - return 0; - - pc_setpos(sd,sd->status.save_point.map, - sd->status.save_point.x,sd->status.save_point.y,3); - }else if(strcmp(str,"Save")==0){ - if(map[sd->bl.m].flag.noreturn) // 蝶禁止 - return 0; - - pc_setpos(sd,sd->status.save_point.map, - sd->status.save_point.x,sd->status.save_point.y,3); - }else - pc_setpos(sd,str,x,y,0); - return 0; -} -/*========================================== - * エリア指定ワープ - *------------------------------------------ - */ -int buildin_areawarp_sub(struct block_list *bl,va_list ap) -{ - int x,y; - char *map; - map=va_arg(ap, char *); - x=va_arg(ap,int); - y=va_arg(ap,int); - if(strcmp(map,"Random")==0) - pc_randomwarp((struct map_session_data *)bl,3); - else - pc_setpos((struct map_session_data *)bl,map,x,y,0); - return 0; -} -int buildin_areawarp(struct script_state *st) -{ - int x,y,m; - char *str; - char *mapname; - int x0,y0,x1,y1; - - mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - x0=conv_num(st,& (st->stack->stack_data[st->start+3])); - y0=conv_num(st,& (st->stack->stack_data[st->start+4])); - x1=conv_num(st,& (st->stack->stack_data[st->start+5])); - y1=conv_num(st,& (st->stack->stack_data[st->start+6])); - str=conv_str(st,& (st->stack->stack_data[st->start+7])); - x=conv_num(st,& (st->stack->stack_data[st->start+8])); - y=conv_num(st,& (st->stack->stack_data[st->start+9])); - - if( (m=map_mapname2mapid(mapname))< 0) - return 0; - - map_foreachinarea(buildin_areawarp_sub, - m,x0,y0,x1,y1,BL_PC, str,x,y ); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_heal(struct script_state *st) -{ - int hp,sp; - - hp=conv_num(st,& (st->stack->stack_data[st->start+2])); - sp=conv_num(st,& (st->stack->stack_data[st->start+3])); - pc_heal(script_rid2sd(st),hp,sp); - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_itemheal(struct script_state *st) -{ - int hp,sp; - - hp=conv_num(st,& (st->stack->stack_data[st->start+2])); - sp=conv_num(st,& (st->stack->stack_data[st->start+3])); - pc_itemheal(script_rid2sd(st),hp,sp); - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_percentheal(struct script_state *st) -{ - int hp,sp; - - hp=conv_num(st,& (st->stack->stack_data[st->start+2])); - sp=conv_num(st,& (st->stack->stack_data[st->start+3])); - pc_percentheal(script_rid2sd(st),hp,sp); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_jobchange(struct script_state *st) -{ - int job, upper=-1; - - job=conv_num(st,& (st->stack->stack_data[st->start+2])); - if( st->end>st->start+3 ) - upper=conv_num(st,& (st->stack->stack_data[st->start+3])); - - if ((job >= 0 && job < MAX_PC_CLASS)) - pc_jobchange(script_rid2sd(st),job, upper); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_input(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int num=(st->end>st->start+2)?st->stack->stack_data[st->start+2].u.num:0; - char *name=(char *) ((st->end>st->start+2)?str_buf+str_data[num&0x00ffffff].str:""); -// char prefix=*name; - char postfix=name[strlen(name)-1]; - - sd=script_rid2sd(st); - if(sd->state.menu_or_input){ - sd->state.menu_or_input=0; - if( postfix=='$' ){ - // 文字列 - if(st->end>st->start+2){ // 引数1個 - set_reg(sd,num,name,(void*)sd->npc_str); - }else{ - printf("buildin_input: string discarded !!\n"); - } - }else{ - - // commented by Lupus (check Value Number Input fix in clif.c) - // readded by Yor: set ammount to 0 instead of cancel trade. - // ** Fix by fritz :X keeps people from abusing old input bugs - if (sd->npc_amount < 0) { //** If input amount is less then 0 -// clif_tradecancelled(sd); // added "Deal has been cancelled" message by Valaris -// buildin_close(st); // ** close - sd->npc_amount = 0; - } else if (sd->npc_amount > battle_config.vending_max_value) // new fix by Yor - sd->npc_amount = battle_config.vending_max_value; - - // 数値 - if(st->end>st->start+2){ // 引数1個 - set_reg(sd,num,name,(void*)sd->npc_amount); - } else { - // ragemu互換のため - pc_setreg(sd,add_str((unsigned char *) "l14"),sd->npc_amount); - } - } - } else { - st->state=RERUNLINE; - if(postfix=='$')clif_scriptinputstr(sd,st->oid); - else clif_scriptinput(sd,st->oid); - sd->state.menu_or_input=1; - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_if(struct script_state *st) -{ - int sel,i; - - sel=conv_num(st,& (st->stack->stack_data[st->start+2])); - if(!sel) - return 0; - - // 関数名をコピー - push_copy(st->stack,st->start+3); - // 間に引数マーカを入れて - push_val(st->stack,C_ARG,0); - // 残りの引数をコピー - for(i=st->start+4;i<st->end;i++){ - push_copy(st->stack,i); - } - run_func(st); - - return 0; -} - - -/*========================================== - * 変数設定 - *------------------------------------------ - */ -int buildin_set(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int num=st->stack->stack_data[st->start+2].u.num; - char *name=str_buf+str_data[num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - - if( st->stack->stack_data[st->start+2].type!=C_NAME ){ - printf("script: buildin_set: not name\n"); - return 0; - } - - if( prefix!='$' ) - sd=script_rid2sd(st); - - - if( postfix=='$' ){ - // 文字列 - char *str = conv_str(st,& (st->stack->stack_data[st->start+3])); - set_reg(sd,num,name,(void*)str); - }else{ - // 数値 - int val = conv_num(st,& (st->stack->stack_data[st->start+3])); - set_reg(sd,num,name,(void*)val); - } - - return 0; -} -/*========================================== - * 配列変数設定 - *------------------------------------------ - */ -int buildin_setarray(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int num=st->stack->stack_data[st->start+2].u.num; - char *name=str_buf+str_data[num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - int i,j; - - if( prefix!='$' && prefix!='@' ){ - printf("buildin_setarray: illegal scope !\n"); - return 0; - } - if( prefix!='$' ) - sd=script_rid2sd(st); - - for(j=0,i=st->start+3; i<st->end && j<128;i++,j++){ - void *v; - if( postfix=='$' ) - v=(void*)conv_str(st,& (st->stack->stack_data[i])); - else - v=(void*)conv_num(st,& (st->stack->stack_data[i])); - set_reg( sd, num+(j<<24), name, v); - } - return 0; -} -/*========================================== - * 配列変数クリア - *------------------------------------------ - */ -int buildin_cleararray(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int num=st->stack->stack_data[st->start+2].u.num; - char *name=str_buf+str_data[num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - int sz=conv_num(st,& (st->stack->stack_data[st->start+4])); - int i; - void *v; - - if( prefix!='$' && prefix!='@' ){ - printf("buildin_cleararray: illegal scope !\n"); - return 0; - } - if( prefix!='$' ) - sd=script_rid2sd(st); - - if( postfix=='$' ) - v=(void*)conv_str(st,& (st->stack->stack_data[st->start+3])); - else - v=(void*)conv_num(st,& (st->stack->stack_data[st->start+3])); - - for(i=0;i<sz;i++) - set_reg(sd,num+(i<<24),name,v); - return 0; -} -/*========================================== - * 配列変数コピー - *------------------------------------------ - */ -int buildin_copyarray(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int num=st->stack->stack_data[st->start+2].u.num; - char *name=str_buf+str_data[num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - int num2=st->stack->stack_data[st->start+3].u.num; - char *name2=str_buf+str_data[num2&0x00ffffff].str; - char prefix2=*name2; - char postfix2=name2[strlen(name2)-1]; - int sz=conv_num(st,& (st->stack->stack_data[st->start+4])); - int i; - - if( prefix!='$' && prefix!='@' && prefix2!='$' && prefix2!='@' ){ - printf("buildin_copyarray: illegal scope !\n"); - return 0; - } - if( (postfix=='$' || postfix2=='$') && postfix!=postfix2 ){ - printf("buildin_copyarray: type mismatch !\n"); - return 0; - } - if( prefix!='$' || prefix2!='$' ) - sd=script_rid2sd(st); - - - for(i=0;i<sz;i++) - set_reg(sd,num+(i<<24),name, get_val2(st,num2+(i<<24)) ); - return 0; -} -/*========================================== - * 配列変数のサイズ所得 - *------------------------------------------ - */ -static int getarraysize(struct script_state *st,int num,int postfix) -{ - int i=(num>>24),c=i; - for(;i<128;i++){ - void *v=get_val2(st,num+(i<<24)); - if(postfix=='$' && *((char*)v) ) c=i; - if(postfix!='$' && (int)v )c=i; - } - return c+1; -} -int buildin_getarraysize(struct script_state *st) -{ - int num=st->stack->stack_data[st->start+2].u.num; - char *name=str_buf+str_data[num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - - if( prefix!='$' && prefix!='@' ){ - printf("buildin_copyarray: illegal scope !\n"); - return 0; - } - - push_val(st->stack,C_INT,getarraysize(st,num,postfix) ); - return 0; -} -/*========================================== - * 配列変数から要素削除 - *------------------------------------------ - */ -int buildin_deletearray(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int num=st->stack->stack_data[st->start+2].u.num; - char *name=str_buf+str_data[num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - int count=1; - int i,sz=getarraysize(st,num,postfix)-(num>>24)-count+1; - - - if( (st->end > st->start+3) ) - count=conv_num(st,& (st->stack->stack_data[st->start+3])); - - if( prefix!='$' && prefix!='@' ){ - printf("buildin_deletearray: illegal scope !\n"); - return 0; - } - if( prefix!='$' ) - sd=script_rid2sd(st); - - for(i=0;i<sz;i++){ - set_reg(sd,num+(i<<24),name, get_val2(st,num+((i+count)<<24) ) ); - } - for(;i<(128-(num>>24));i++){ - if( postfix!='$' ) set_reg(sd,num+(i<<24),name, 0); - if( postfix=='$' ) set_reg(sd,num+(i<<24),name, (void *) ""); - } - return 0; -} - -/*========================================== - * 指定要素を表す値(キー)を所得する - *------------------------------------------ - */ -int buildin_getelementofarray(struct script_state *st) -{ - if( st->stack->stack_data[st->start+2].type==C_NAME ){ - int i=conv_num(st,& (st->stack->stack_data[st->start+3])); - if(i>127 || i<0){ - printf("script: getelementofarray (operator[]): param2 illegal number %d\n",i); - push_val(st->stack,C_INT,0); - }else{ - push_val(st->stack,C_NAME, - (i<<24) | st->stack->stack_data[st->start+2].u.num ); - } - }else{ - printf("script: getelementofarray (operator[]): param1 not name !\n"); - push_val(st->stack,C_INT,0); - } - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_setlook(struct script_state *st) -{ - int type,val; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - val=conv_num(st,& (st->stack->stack_data[st->start+3])); - - pc_changelook(script_rid2sd(st),type,val); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_cutin(struct script_state *st) -{ - int type; - - conv_str(st,& (st->stack->stack_data[st->start+2])); - type=conv_num(st,& (st->stack->stack_data[st->start+3])); - - clif_cutin(script_rid2sd(st),st->stack->stack_data[st->start+2].u.str,type); - - return 0; -} -/*========================================== - * カードのイラストを表示する - *------------------------------------------ - */ -int buildin_cutincard(struct script_state *st) -{ - int itemid; - - itemid=conv_num(st,& (st->stack->stack_data[st->start+2])); - - clif_cutin(script_rid2sd(st),itemdb_search(itemid)->cardillustname,4); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_viewpoint(struct script_state *st) -{ - int type,x,y,id,color; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - x=conv_num(st,& (st->stack->stack_data[st->start+3])); - y=conv_num(st,& (st->stack->stack_data[st->start+4])); - id=conv_num(st,& (st->stack->stack_data[st->start+5])); - color=conv_num(st,& (st->stack->stack_data[st->start+6])); - - clif_viewpoint(script_rid2sd(st),st->oid,type,x,y,id,color); - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_countitem(struct script_state *st) -{ - int nameid=0,count=0,i; - struct map_session_data *sd; - - struct script_data *data; - - sd = script_rid2sd(st); - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data; - if( (item_data = itemdb_searchname(name)) != NULL) - nameid=item_data->nameid; - }else - nameid=conv_num(st,data); - - if (nameid>=500) //if no such ID then skip this iteration - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid==nameid) - count+=sd->status.inventory[i].amount; - } - else{ - if(battle_config.error_log) - printf("wrong item ID : countitem(%i)\n",nameid); - } - push_val(st->stack,C_INT,count); - - return 0; -} - -/*========================================== - * 重量チェック - *------------------------------------------ - */ -int buildin_checkweight(struct script_state *st) -{ - int nameid=0,amount; - struct map_session_data *sd; - struct script_data *data; - - sd = script_rid2sd(st); - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data = itemdb_searchname(name); - if( item_data ) - nameid=item_data->nameid; - }else - nameid=conv_num(st,data); - - amount=conv_num(st,& (st->stack->stack_data[st->start+3])); - if ( amount<=0 || nameid<500 ) { //if get wrong item ID or amount<=0, don't count weight of non existing items - push_val(st->stack,C_INT,0); - } - - sd=script_rid2sd(st); - if(itemdb_weight(nameid)*amount + sd->weight > sd->max_weight){ - push_val(st->stack,C_INT,0); - } else { - push_val(st->stack,C_INT,1); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_getitem(struct script_state *st) -{ - int nameid,nameidsrc,amount,flag = 0; - struct item item_tmp; - struct map_session_data *sd; - struct script_data *data; - - sd = script_rid2sd(st); - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data = itemdb_searchname(name); - nameid=512; //Apple item ID - if( item_data != NULL) - nameid=item_data->nameid; - }else - nameid=conv_num(st,data); - - if ( ( amount=conv_num(st,& (st->stack->stack_data[st->start+3])) ) <= 0) { - return 0; //return if amount <=0, skip the useles iteration - } - //Violet Box, Blue Box, etc - random item pick - if((nameidsrc = nameid)<0) { // Save real ID of the source Box [Lupus] - nameid=itemdb_searchrandomid(-nameid); - - if(log_config.present > 0) - log_present(sd, -nameidsrc, nameid); //fixed missing ID by Lupus - - flag = 1; - } - - if(nameid > 0) { - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid=nameid; - if(!flag) - item_tmp.identify=1; - else - item_tmp.identify=!itemdb_isequip3(nameid); - if( st->end>st->start+5 ) //アイテムを指定したIDに渡す - sd=map_id2sd(conv_num(st,& (st->stack->stack_data[st->start+5]))); - if(sd == NULL) //アイテムを渡す相手がいなかったらお帰り - return 0; - if((flag = pc_additem(sd,&item_tmp,amount))) { - clif_additem(sd,0,0,flag); - if(!pc_candrop(sd,nameid)) - map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_getitem2(struct script_state *st) -{ - int nameid,amount,flag = 0; - int iden,ref,attr,c1,c2,c3,c4; - struct item_data *item_data; - struct item item_tmp; - struct map_session_data *sd; - struct script_data *data; - - sd = script_rid2sd(st); - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data = itemdb_searchname(name); - nameid=512; //Apple item ID - if( item_data ) - nameid=item_data->nameid; - }else - nameid=conv_num(st,data); - - amount=conv_num(st,& (st->stack->stack_data[st->start+3])); - iden=conv_num(st,& (st->stack->stack_data[st->start+4])); - ref=conv_num(st,& (st->stack->stack_data[st->start+5])); - attr=conv_num(st,& (st->stack->stack_data[st->start+6])); - c1=conv_num(st,& (st->stack->stack_data[st->start+7])); - c2=conv_num(st,& (st->stack->stack_data[st->start+8])); - c3=conv_num(st,& (st->stack->stack_data[st->start+9])); - c4=conv_num(st,& (st->stack->stack_data[st->start+10])); - if( st->end>st->start+11 ) //アイテムを指定したIDに渡す - sd=map_id2sd(conv_num(st,& (st->stack->stack_data[st->start+11]))); - if(sd == NULL) //アイテムを渡す相手がいなかったらお帰り - return 0; - - if(nameid<0) { // ランダム - nameid=itemdb_searchrandomid(-nameid); - flag = 1; - } - - if(nameid > 0) { - memset(&item_tmp,0,sizeof(item_tmp)); - item_data=itemdb_search(nameid); - if(item_data->type==4 || item_data->type==5){ - if(ref > 10) ref = 10; - } - else if(item_data->type==7) { - iden = 1; - ref = 0; - } - else { - iden = 1; - ref = attr = 0; - } - - item_tmp.nameid=nameid; - if(!flag) - item_tmp.identify=iden; - else if(item_data->type==4 || item_data->type==5) - item_tmp.identify=0; - item_tmp.refine=ref; - item_tmp.attribute=attr; - item_tmp.card[0]=c1; - item_tmp.card[1]=c2; - item_tmp.card[2]=c3; - item_tmp.card[3]=c4; - if((flag = pc_additem(sd,&item_tmp,amount))) { - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_makeitem(struct script_state *st) -{ - int nameid,amount,flag = 0; - int x,y,m; - char *mapname; - struct item item_tmp; - struct map_session_data *sd; - struct script_data *data; - - sd = script_rid2sd(st); - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data = itemdb_searchname(name); - nameid=512; //Apple Item ID - if( item_data ) - nameid=item_data->nameid; - }else - nameid=conv_num(st,data); - - amount=conv_num(st,& (st->stack->stack_data[st->start+3])); - mapname =conv_str(st,& (st->stack->stack_data[st->start+4])); - x =conv_num(st,& (st->stack->stack_data[st->start+5])); - y =conv_num(st,& (st->stack->stack_data[st->start+6])); - - if( sd && strcmp(mapname,"this")==0) - m=sd->bl.m; - else - m=map_mapname2mapid(mapname); - - if(nameid<0) { // ランダム - nameid=itemdb_searchrandomid(-nameid); - flag = 1; - } - - if(nameid > 0) { - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid=nameid; - if(!flag) - item_tmp.identify=1; - else - item_tmp.identify=!itemdb_isequip3(nameid); - -// clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,amount,m,x,y,NULL,NULL,NULL,0); - } - - return 0; -} -/*========================================== - * script DELITEM command (fixed 2 bugs by Lupus, added deletion priority by Lupus) - *------------------------------------------ - */ -int buildin_delitem(struct script_state *st) -{ - int nameid=0,amount,i,important_item=0; - struct map_session_data *sd; - struct script_data *data; - - sd = script_rid2sd(st); - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data = itemdb_searchname(name); - //nameid=512; - if( item_data ) - nameid=item_data->nameid; - }else - nameid=conv_num(st,data); - - amount=conv_num(st,& (st->stack->stack_data[st->start+3])); - - if (nameid<500 || amount<=0 ) {//by Lupus. Don't run FOR if u got wrong item ID or amount<=0 - //printf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount); - return 0; - } - sd=script_rid2sd(st); - //1st pass - //here we won't delete items with CARDS, named items but we count them - for(i=0;i<MAX_INVENTORY;i++){ - //we don't delete wrong item or equipped item - if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || - sd->status.inventory[i].amount<=0 || sd->status.inventory[i].nameid!=nameid ) - continue; - //1 egg uses 1 cell in the inventory. so it's ok to delete 1 pet / per cycle - if(sd->inventory_data[i]->type==7 && sd->status.inventory[i].card[0] == (short)0xff00 && search_petDB_index(nameid, PET_EGG) >= 0 ){ - intif_delete_petdata(*((long *)(&sd->status.inventory[i].card[1]))); - //clear egg flag. so it won't be put in IMPORTANT items (eggs look like item with 2 cards ^_^) - sd->status.inventory[i].card[1] = sd->status.inventory[i].card[0] = 0; - //now this egg'll be deleted as a common unimportant item - } - //is this item important? does it have cards? or Player's name? or Refined/Upgraded - if( sd->status.inventory[i].card[0] || sd->status.inventory[i].card[1] || - sd->status.inventory[i].card[2] || sd->status.inventory[i].card[3] || sd->status.inventory[i].refine) { - //this is important item, count it - important_item++; - continue; - } - - if(sd->status.inventory[i].amount>=amount){ - pc_delitem(sd,i,amount,0); - return 0; //we deleted exact amount of items. now exit - } else { - amount-=sd->status.inventory[i].amount; - pc_delitem(sd,i,sd->status.inventory[i].amount,0); - } - } - //2nd pass - //now if there WERE items with CARDs/REFINED/NAMED... and if we still have to delete some items. we'll delete them finally - if (important_item>0 && amount>0) - for(i=0;i<MAX_INVENTORY;i++){ - //we don't delete wrong item - if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || - sd->status.inventory[i].amount<=0 || sd->status.inventory[i].nameid!=nameid ) - continue; - - if(sd->status.inventory[i].amount>=amount){ - pc_delitem(sd,i,amount,0); - return 0; //we deleted exact amount of items. now exit - } else { - amount-=sd->status.inventory[i].amount; - pc_delitem(sd,i,sd->status.inventory[i].amount,0); - } - } - - return 0; -} - -/*========================================== - *キャラ関係のパラメータ取得 - *------------------------------------------ - */ -int buildin_readparam(struct script_state *st) -{ - int type; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - if( st->end>st->start+3 ) - sd=map_nick2sd(conv_str(st,& (st->stack->stack_data[st->start+3]))); - else - sd=script_rid2sd(st); - - if(sd==NULL){ - push_val(st->stack,C_INT,-1); - return 0; - } - - push_val(st->stack,C_INT,pc_readparam(sd,type)); - - return 0; -} -/*========================================== - *キャラ関係のID取得 - *------------------------------------------ - */ -int buildin_getcharid(struct script_state *st) -{ - int num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - if( st->end>st->start+3 ) - sd=map_nick2sd(conv_str(st,& (st->stack->stack_data[st->start+3]))); - else - sd=script_rid2sd(st); - if(sd==NULL){ - push_val(st->stack,C_INT,-1); - return 0; - } - if(num==0) - push_val(st->stack,C_INT,sd->status.char_id); - if(num==1) - push_val(st->stack,C_INT,sd->status.party_id); - if(num==2) - push_val(st->stack,C_INT,sd->status.guild_id); - if(num==3) - push_val(st->stack,C_INT,sd->status.account_id); - return 0; -} -/*========================================== - *指定IDのPT名取得 - *------------------------------------------ - */ -char *buildin_getpartyname_sub(int party_id) -{ - struct party *p; - - p=NULL; - p=party_search(party_id); - - if(p!=NULL){ - char *buf; - buf=(char *)aCallocA(24,sizeof(char)); - strcpy(buf,p->name); - return buf; - } - - return 0; -} -int buildin_getpartyname(struct script_state *st) -{ - char *name; - int party_id; - - party_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - name=buildin_getpartyname_sub(party_id); - if(name!=0) - push_str(st->stack,C_STR,(unsigned char *)name); - else - push_str(st->stack,C_CONSTSTR, (unsigned char *) "null"); - - return 0; -} -/*========================================== - *指定IDのPT人数とメンバーID取得 - *------------------------------------------ - */ -int buildin_getpartymember(struct script_state *st) -{ - struct party *p; - int i,j=0; - - p=NULL; - p=party_search(conv_num(st,& (st->stack->stack_data[st->start+2]))); - - if(p!=NULL){ - for(i=0;i<MAX_PARTY;i++){ - if(p->member[i].account_id){ -// printf("name:%s %d\n",p->member[i].name,i); - mapreg_setregstr(add_str((unsigned char *) "$@partymembername$")+(i<<24),p->member[i].name); - j++; - } - } - } - mapreg_setreg(add_str((unsigned char *) "$@partymembercount"),j); - - return 0; -} -/*========================================== - *指定IDのギルド名取得 - *------------------------------------------ - */ -char *buildin_getguildname_sub(int guild_id) -{ - struct guild *g=NULL; - g=guild_search(guild_id); - - if(g!=NULL){ - char *buf; - buf=(char *)aCallocA(24,sizeof(char)); - strcpy(buf,g->name); - return buf; - } - return 0; -} -int buildin_getguildname(struct script_state *st) -{ - char *name; - int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - name=buildin_getguildname_sub(guild_id); - if(name!=0) - push_str(st->stack,C_STR,(unsigned char *) name); - else - push_str(st->stack,C_CONSTSTR,(unsigned char *) "null"); - return 0; -} - -/*========================================== - *指定IDのGuildMaster名取得 - *------------------------------------------ - */ -char *buildin_getguildmaster_sub(int guild_id) -{ - struct guild *g=NULL; - g=guild_search(guild_id); - - if(g!=NULL){ - char *buf; - buf=(char *)aCallocA(24,sizeof(char)); - strncpy(buf,g->master, 23); - return buf; - } - - return 0; -} -int buildin_getguildmaster(struct script_state *st) -{ - char *master; - int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - master=buildin_getguildmaster_sub(guild_id); - if(master!=0) - push_str(st->stack,C_STR,(unsigned char *) master); - else - push_str(st->stack,C_CONSTSTR,(unsigned char *) "null"); - return 0; -} - -int buildin_getguildmasterid(struct script_state *st) -{ - char *master; - struct map_session_data *sd=NULL; - int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - master=buildin_getguildmaster_sub(guild_id); - if(master!=0){ - if((sd=map_nick2sd(master)) == NULL){ - push_val(st->stack,C_INT,0); - return 0; - } - push_val(st->stack,C_INT,sd->status.char_id); - }else{ - push_val(st->stack,C_INT,0); - } - return 0; -} - -/*========================================== - * キャラクタの名前 - *------------------------------------------ - */ -int buildin_strcharinfo(struct script_state *st) -{ - struct map_session_data *sd; - int num; - - sd=script_rid2sd(st); - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - if(num==0){ - char *buf; - buf=(char *)aCallocA(24,sizeof(char)); - strncpy(buf,sd->status.name, 23); - push_str(st->stack,C_STR,(unsigned char *) buf); - } - if(num==1){ - char *buf; - buf=buildin_getpartyname_sub(sd->status.party_id); - if(buf!=0) - push_str(st->stack,C_STR,(unsigned char *) buf); - else - push_str(st->stack,C_CONSTSTR,(unsigned char *) ""); - } - if(num==2){ - char *buf; - buf=buildin_getguildname_sub(sd->status.guild_id); - if(buf!=0) - push_str(st->stack,C_STR,(unsigned char *) buf); - else - push_str(st->stack,C_CONSTSTR,(unsigned char *) ""); - } - - return 0; -} - -unsigned int equip[10]={0x0100,0x0010,0x0020,0x0002,0x0004,0x0040,0x0008,0x0080,0x0200,0x0001}; - -/*========================================== - * GetEquipID(Pos); Pos: 1-10 - *------------------------------------------ - */ -int buildin_getequipid(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - struct item_data* item; - - sd=script_rid2sd(st); - if(sd == NULL) - { - printf("getequipid: sd == NULL\n"); - return 0; - } - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0){ - item=sd->inventory_data[i]; - if(item) - push_val(st->stack,C_INT,item->nameid); - else - push_val(st->stack,C_INT,0); - }else{ - push_val(st->stack,C_INT,-1); - } - return 0; -} - -/*========================================== - * 装備名文字列(精錬メニュー用) - *------------------------------------------ - */ -int buildin_getequipname(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - struct item_data* item; - char *buf; - - buf=(char *)aCallocA(64,sizeof(char)); - sd=script_rid2sd(st); - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0){ - item=sd->inventory_data[i]; - if(item) - sprintf(buf,"%s-[%s]",pos[num-1],item->jname); - else - sprintf(buf,"%s-[%s]",pos[num-1],pos[10]); - }else{ - sprintf(buf,"%s-[%s]",pos[num-1],pos[10]); - } - push_str(st->stack,C_STR,(unsigned char *) buf); - - return 0; -} - -/*========================================== - * getbrokenid [Valaris] - *------------------------------------------ - */ -int buildin_getbrokenid(struct script_state *st) -{ - int i,num,id=0,brokencounter=0; - struct map_session_data *sd; - - sd=script_rid2sd(st); - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].attribute==1){ - brokencounter++; - if(num==brokencounter){ - id=sd->status.inventory[i].nameid; - break; - } - } - } - - push_val(st->stack,C_INT,id); - - return 0; -} - -/*========================================== - * repair [Valaris] - *------------------------------------------ - */ -int buildin_repair(struct script_state *st) -{ - int i,num; - int repaircounter=0; - struct map_session_data *sd; - - - sd=script_rid2sd(st); - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].attribute==1){ - repaircounter++; - if(num==repaircounter){ - sd->status.inventory[i].attribute=0; - clif_equiplist(sd); - clif_produceeffect(sd, 0, sd->status.inventory[i].nameid); - clif_misceffect(&sd->bl, 3); - clif_displaymessage(sd->fd,"Item has been repaired."); - break; - } - } - } - - return 0; -} - -/*========================================== - * 装備チェック - *------------------------------------------ - */ -int buildin_getequipisequiped(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0){ - push_val(st->stack,C_INT,1); - }else{ - push_val(st->stack,C_INT,0); - } - - return 0; -} - -/*========================================== - * 装備品精錬可能チェック - *------------------------------------------ - */ -int buildin_getequipisenableref(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0 && num<7 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine) - // replaced by Celest - /*(num!=1 - || sd->inventory_data[i]->def > 1 - || (sd->inventory_data[i]->def==1 && sd->inventory_data[i]->equip_script==NULL) - || (sd->inventory_data[i]->def<=0 && sd->inventory_data[i]->equip_script!=NULL)))*/ - - { - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - - return 0; -} - -/*========================================== - * 装備品鑑定チェック - *------------------------------------------ - */ -int buildin_getequipisidentify(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0) - push_val(st->stack,C_INT,sd->status.inventory[i].identify); - else - push_val(st->stack,C_INT,0); - - return 0; -} - -/*========================================== - * 装備品精錬度 - *------------------------------------------ - */ -int buildin_getequiprefinerycnt(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0) - push_val(st->stack,C_INT,sd->status.inventory[i].refine); - else - push_val(st->stack,C_INT,0); - - return 0; -} - -/*========================================== - * 装備品武器LV - *------------------------------------------ - */ -int buildin_getequipweaponlv(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0 && sd->inventory_data[i]) - push_val(st->stack,C_INT,sd->inventory_data[i]->wlv); - else - push_val(st->stack,C_INT,0); - - return 0; -} - -/*========================================== - * 装備品精錬成功率 - *------------------------------------------ - */ -int buildin_getequippercentrefinery(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0) - push_val(st->stack,C_INT,status_percentrefinery(sd,&sd->status.inventory[i])); - else - push_val(st->stack,C_INT,0); - - return 0; -} - -/*========================================== - * 精錬成功 - *------------------------------------------ - */ -int buildin_successrefitem(struct script_state *st) -{ - int i,num,ep; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0) { - ep=sd->status.inventory[i].equip; - - if(log_config.refine > 0) - log_refine(sd, i, 1); - - sd->status.inventory[i].refine++; - pc_unequipitem(sd,i,2); - clif_refine(sd->fd,sd,0,i,sd->status.inventory[i].refine); - clif_delitem(sd,i,1); - clif_additem(sd,i,1,0); - pc_equipitem(sd,i,ep); - clif_misceffect(&sd->bl,3); - } - - return 0; -} - -/*========================================== - * 精錬失敗 - *------------------------------------------ - */ -int buildin_failedrefitem(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0) { - if(log_config.refine > 0) - log_refine(sd, i, 0); - - sd->status.inventory[i].refine = 0; - pc_unequipitem(sd,i,3); - // 精錬失敗エフェクトのパケット - clif_refine(sd->fd,sd,1,i,sd->status.inventory[i].refine); - pc_delitem(sd,i,1,0); - // 他の人にも失敗を通知 - clif_misceffect(&sd->bl,2); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_statusup(struct script_state *st) -{ - int type; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - pc_statusup(sd,type); - - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_statusup2(struct script_state *st) -{ - int type,val; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - val=conv_num(st,& (st->stack->stack_data[st->start+3])); - sd=script_rid2sd(st); - pc_statusup2(sd,type,val); - - return 0; -} -/*========================================== - * 装備品による能力値ボーナス - *------------------------------------------ - */ -int buildin_bonus(struct script_state *st) -{ - int type,val; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - val=conv_num(st,& (st->stack->stack_data[st->start+3])); - sd=script_rid2sd(st); - pc_bonus(sd,type,val); - - return 0; -} -/*========================================== - * 装備品による能力値ボーナス - *------------------------------------------ - */ -int buildin_bonus2(struct script_state *st) -{ - int type,type2,val; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - type2=conv_num(st,& (st->stack->stack_data[st->start+3])); - val=conv_num(st,& (st->stack->stack_data[st->start+4])); - sd=script_rid2sd(st); - pc_bonus2(sd,type,type2,val); - - return 0; -} -/*========================================== - * 装備品による能力値ボーナス - *------------------------------------------ - */ -int buildin_bonus3(struct script_state *st) -{ - int type,type2,type3,val; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - type2=conv_num(st,& (st->stack->stack_data[st->start+3])); - type3=conv_num(st,& (st->stack->stack_data[st->start+4])); - val=conv_num(st,& (st->stack->stack_data[st->start+5])); - sd=script_rid2sd(st); - pc_bonus3(sd,type,type2,type3,val); - - return 0; -} - -int buildin_bonus4(struct script_state *st) -{ - int type,type2,type3,type4,val; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - type2=conv_num(st,& (st->stack->stack_data[st->start+3])); - type3=conv_num(st,& (st->stack->stack_data[st->start+4])); - type4=conv_num(st,& (st->stack->stack_data[st->start+5])); - val=conv_num(st,& (st->stack->stack_data[st->start+6])); - sd=script_rid2sd(st); - pc_bonus4(sd,type,type2,type3,type4,val); - - return 0; -} -/*========================================== - * スキル所得 - *------------------------------------------ - */ -int buildin_skill(struct script_state *st) -{ - int id,level,flag=1; - struct map_session_data *sd; - - id=conv_num(st,& (st->stack->stack_data[st->start+2])); - level=conv_num(st,& (st->stack->stack_data[st->start+3])); - if( st->end>st->start+4 ) - flag=conv_num(st,&(st->stack->stack_data[st->start+4]) ); - sd=script_rid2sd(st); - pc_skill(sd,id,level,flag); - - return 0; -} - -// add x levels of skill (stackable) [Valaris] -int buildin_addtoskill(struct script_state *st) -{ - int id,level,flag=2; - struct map_session_data *sd; - - id=conv_num(st,& (st->stack->stack_data[st->start+2])); - level=conv_num(st,& (st->stack->stack_data[st->start+3])); - if( st->end>st->start+4 ) - flag=conv_num(st,&(st->stack->stack_data[st->start+4]) ); - sd=script_rid2sd(st); - pc_skill(sd,id,level,flag); - - return 0; -} - -/*========================================== - * ギルドスキル取得 - *------------------------------------------ - */ -int buildin_guildskill(struct script_state *st) -{ - int id,level,flag=0; - struct map_session_data *sd; - int i=0; - - id=conv_num(st,& (st->stack->stack_data[st->start+2])); - level=conv_num(st,& (st->stack->stack_data[st->start+3])); - if( st->end>st->start+4 ) - flag=conv_num(st,&(st->stack->stack_data[st->start+4]) ); - sd=script_rid2sd(st); - for(i=0;i<level;i++) - guild_skillup(sd,id,flag); - - return 0; -} -/*========================================== - * スキルレベル所得 - *------------------------------------------ - */ -int buildin_getskilllv(struct script_state *st) -{ - int id=conv_num(st,& (st->stack->stack_data[st->start+2])); - push_val(st->stack,C_INT, pc_checkskill( script_rid2sd(st) ,id) ); - return 0; -} -/*========================================== - * getgdskilllv(Guild_ID, Skill_ID); - * skill_id = 10000 : GD_APPROVAL - * 10001 : GD_KAFRACONTACT - * 10002 : GD_GUARDIANRESEARCH - * 10003 : GD_GUARDUP - * 10004 : GD_EXTENSION - *------------------------------------------ - */ -int buildin_getgdskilllv(struct script_state *st) -{ - int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - int skill_id=conv_num(st,& (st->stack->stack_data[st->start+3])); - struct guild *g=guild_search(guild_id); - push_val(st->stack,C_INT, (g==NULL)?-1:guild_checkskill(g,skill_id) ); - return 0; -/* - struct map_session_data *sd=NULL; - struct guild *g=NULL; - int skill_id; - - skill_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - if(sd && sd->status.guild_id > 0) g=guild_search(sd->status.guild_id); - if(sd && g) { - push_val(st->stack,C_INT, guild_checkskill(g,skill_id+9999) ); - } else { - push_val(st->stack,C_INT,-1); - } - return 0; -*/ -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_basicskillcheck(struct script_state *st) -{ - push_val(st->stack,C_INT, battle_config.basic_skill_check); - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_getgmlevel(struct script_state *st) -{ - push_val(st->stack,C_INT, pc_isGM(script_rid2sd(st))); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_end(struct script_state *st) -{ - st->state = END; - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_checkoption(struct script_state *st) -{ - int type; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - - if(sd->status.option & type){ - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_checkoption1(struct script_state *st) -{ - int type; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - - if(sd->opt1 & type){ - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int buildin_checkoption2(struct script_state *st) -{ - int type; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - - if(sd->opt2 & type){ - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_setoption(struct script_state *st) -{ - int type; - struct map_session_data *sd; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - pc_setoption(sd,type); - - return 0; -} - -/*========================================== - * Checkcart [Valaris] - *------------------------------------------ - */ - -int buildin_checkcart(struct script_state *st) -{ - struct map_session_data *sd; - - sd=script_rid2sd(st); - - if(pc_iscarton(sd)){ - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - return 0; -} - -/*========================================== - * カートを付ける - *------------------------------------------ - */ -int buildin_setcart(struct script_state *st) -{ - struct map_session_data *sd; - - sd=script_rid2sd(st); - pc_setcart(sd,1); - - return 0; -} - -/*========================================== - * checkfalcon [Valaris] - *------------------------------------------ - */ - -int buildin_checkfalcon(struct script_state *st) -{ - struct map_session_data *sd; - - sd=script_rid2sd(st); - - if(pc_isfalcon(sd)){ - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - - return 0; -} - - -/*========================================== - * 鷹を付ける - *------------------------------------------ - */ -int buildin_setfalcon(struct script_state *st) -{ - struct map_session_data *sd; - - sd=script_rid2sd(st); - pc_setfalcon(sd); - - return 0; -} - -/*========================================== - * Checkcart [Valaris] - *------------------------------------------ - */ - -int buildin_checkriding(struct script_state *st) -{ - struct map_session_data *sd; - - sd=script_rid2sd(st); - - if(pc_isriding(sd)){ - push_val(st->stack,C_INT,1); - } else { - push_val(st->stack,C_INT,0); - } - - return 0; -} - - -/*========================================== - * ペコペコ乗り - *------------------------------------------ - */ -int buildin_setriding(struct script_state *st) -{ - struct map_session_data *sd; - - sd=script_rid2sd(st); - pc_setriding(sd); - - return 0; -} - -/*========================================== - * セーブポイントの保存 - *------------------------------------------ - */ -int buildin_savepoint(struct script_state *st) -{ - int x,y; - char *str; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - x=conv_num(st,& (st->stack->stack_data[st->start+3])); - y=conv_num(st,& (st->stack->stack_data[st->start+4])); - pc_setsavepoint(script_rid2sd(st),str,x,y); - return 0; -} - -/*========================================== - * GetTimeTick(0: System Tick, 1: Time Second Tick) - *------------------------------------------ - */ -int buildin_gettimetick(struct script_state *st) /* Asgard Version */ -{ - int type; - time_t timer; - struct tm *t; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - - switch(type){ - case 1: - //type 1:(Second Ticks: 0-86399, 00:00:00-23:59:59) - time(&timer); - t=localtime(&timer); - push_val(st->stack,C_INT,((t->tm_hour)*3600+(t->tm_min)*60+t->tm_sec)); - break; - case 0: - default: - //type 0:(System Ticks) - push_val(st->stack,C_INT,gettick()); - break; - } - return 0; -} - -/*========================================== - * GetTime(Type); - * 1: Sec 2: Min 3: Hour - * 4: WeekDay 5: MonthDay 6: Month - * 7: Year - *------------------------------------------ - */ -int buildin_gettime(struct script_state *st) /* Asgard Version */ -{ - int type; - time_t timer; - struct tm *t; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - - time(&timer); - t=localtime(&timer); - - switch(type){ - case 1://Sec(0~59) - push_val(st->stack,C_INT,t->tm_sec); - break; - case 2://Min(0~59) - push_val(st->stack,C_INT,t->tm_min); - break; - case 3://Hour(0~23) - push_val(st->stack,C_INT,t->tm_hour); - break; - case 4://WeekDay(0~6) - push_val(st->stack,C_INT,t->tm_wday); - break; - case 5://MonthDay(01~31) - push_val(st->stack,C_INT,t->tm_mday); - break; - case 6://Month(01~12) - push_val(st->stack,C_INT,t->tm_mon+1); - break; - case 7://Year(20xx) - push_val(st->stack,C_INT,t->tm_year+1900); - break; - default://(format error) - push_val(st->stack,C_INT,-1); - break; - } - return 0; -} - -/*========================================== - * GetTimeStr("TimeFMT", Length); - *------------------------------------------ - */ -int buildin_gettimestr(struct script_state *st) -{ - char *tmpstr; - char *fmtstr; - int maxlen; - time_t now = time(NULL); - - fmtstr=conv_str(st,& (st->stack->stack_data[st->start+2])); - maxlen=conv_num(st,& (st->stack->stack_data[st->start+3])); - - tmpstr=(char *)aCallocA(maxlen+1,sizeof(char)); - strftime(tmpstr,maxlen,fmtstr,localtime(&now)); - tmpstr[maxlen]='\0'; - - push_str(st->stack,C_STR,(unsigned char *) tmpstr); - return 0; -} - -/*========================================== - * カプラ倉庫を開く - *------------------------------------------ - */ -int buildin_openstorage(struct script_state *st) -{ - storage_storageopen(script_rid2sd(st)); - return 0; -} - -int buildin_guildopenstorage(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int ret; - ret = storage_guild_storageopen(sd); - push_val(st->stack,C_INT,ret); - return 0; -} - -/*========================================== - * アイテムによるスキル発動 - *------------------------------------------ - */ -int buildin_itemskill(struct script_state *st) -{ - int id,lv; - char *str; - struct map_session_data *sd=script_rid2sd(st); - - id=conv_num(st,& (st->stack->stack_data[st->start+2])); - lv=conv_num(st,& (st->stack->stack_data[st->start+3])); - str=conv_str(st,& (st->stack->stack_data[st->start+4])); - - // 詠唱中にスキルアイテムは使用できない - if(sd->skilltimer != -1) - return 0; - - sd->skillitem=id; - sd->skillitemlv=lv; - clif_item_skill(sd,id,lv,str); - return 0; -} -/*========================================== - * アイテム作成 - *------------------------------------------ - */ -int buildin_produce(struct script_state *st) -{ - int trigger; - struct map_session_data *sd=script_rid2sd(st); - - if( sd->state.produce_flag == 1) return 0; - trigger=conv_num(st,& (st->stack->stack_data[st->start+2])); - clif_skill_produce_mix_list(sd,trigger); - return 0; -} -/*========================================== - * NPCでペット作る - *------------------------------------------ - */ -int buildin_makepet(struct script_state *st) -{ - struct map_session_data *sd = script_rid2sd(st); - struct script_data *data; - int id,pet_id; - - data=&(st->stack->stack_data[st->start+2]); - get_val(st,data); - - id=conv_num(st,data); - - pet_id = search_petDB_index(id, PET_CLASS); - - if (pet_id < 0) - pet_id = search_petDB_index(id, PET_EGG); - if (pet_id >= 0 && sd) { - sd->catch_target_class = pet_db[pet_id].class_; - intif_create_pet( - sd->status.account_id, sd->status.char_id, - (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv, - (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate, - 100, 0, 1, pet_db[pet_id].jname); - } - - return 0; -} -/*========================================== - * NPCで経験値上げる - *------------------------------------------ - */ -int buildin_getexp(struct script_state *st) -{ - struct map_session_data *sd = script_rid2sd(st); - int base=0,job=0; - - base=conv_num(st,& (st->stack->stack_data[st->start+2])); - job =conv_num(st,& (st->stack->stack_data[st->start+3])); - if(base<0 || job<0) - return 0; - if(sd) - pc_gainexp(sd,base,job); - - return 0; -} - -/*========================================== - * Gain guild exp [Celest] - *------------------------------------------ - */ -int buildin_guildgetexp(struct script_state *st) -{ - struct map_session_data *sd = script_rid2sd(st); - int exp; - - exp = conv_num(st,& (st->stack->stack_data[st->start+2])); - if(exp < 0) - return 0; - if(sd && sd->status.guild_id > 0) - guild_getexp (sd, exp); - - return 0; -} - -/*========================================== - * モンスター発生 - *------------------------------------------ - */ -int buildin_monster(struct script_state *st) -{ - int class_,amount,x,y; - char *str,*map,*event=""; - - map =conv_str(st,& (st->stack->stack_data[st->start+2])); - x =conv_num(st,& (st->stack->stack_data[st->start+3])); - y =conv_num(st,& (st->stack->stack_data[st->start+4])); - str =conv_str(st,& (st->stack->stack_data[st->start+5])); - class_=conv_num(st,& (st->stack->stack_data[st->start+6])); - amount=conv_num(st,& (st->stack->stack_data[st->start+7])); - if( st->end>st->start+8 ) - event=conv_str(st,& (st->stack->stack_data[st->start+8])); - - mob_once_spawn(map_id2sd(st->rid),map,x,y,str,class_,amount,event); - return 0; -} -/*========================================== - * モンスター発生 - *------------------------------------------ - */ -int buildin_areamonster(struct script_state *st) -{ - int class_,amount,x0,y0,x1,y1; - char *str,*map,*event=""; - - map =conv_str(st,& (st->stack->stack_data[st->start+2])); - x0 =conv_num(st,& (st->stack->stack_data[st->start+3])); - y0 =conv_num(st,& (st->stack->stack_data[st->start+4])); - x1 =conv_num(st,& (st->stack->stack_data[st->start+5])); - y1 =conv_num(st,& (st->stack->stack_data[st->start+6])); - str =conv_str(st,& (st->stack->stack_data[st->start+7])); - class_=conv_num(st,& (st->stack->stack_data[st->start+8])); - amount=conv_num(st,& (st->stack->stack_data[st->start+9])); - if( st->end>st->start+10 ) - event=conv_str(st,& (st->stack->stack_data[st->start+10])); - - mob_once_spawn_area(map_id2sd(st->rid),map,x0,y0,x1,y1,str,class_,amount,event); - return 0; -} -/*========================================== - * モンスター削除 - *------------------------------------------ - */ -int buildin_killmonster_sub(struct block_list *bl,va_list ap) -{ - char *event=va_arg(ap,char *); - int allflag=va_arg(ap,int); - - if(!allflag){ - if(strcmp(event,((struct mob_data *)bl)->npc_event)==0) - mob_delete((struct mob_data *)bl); - return 0; - }else if(allflag){ - if(((struct mob_data *)bl)->spawndelay1==-1 && ((struct mob_data *)bl)->spawndelay2==-1) - mob_delete((struct mob_data *)bl); - return 0; - } - return 0; -} -int buildin_killmonster(struct script_state *st) -{ - char *mapname,*event; - int m,allflag=0; - mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - event=conv_str(st,& (st->stack->stack_data[st->start+3])); - if(strcmp(event,"All")==0) - allflag = 1; - - if( (m=map_mapname2mapid(mapname))<0 ) - return 0; - map_foreachinarea(buildin_killmonster_sub, - m,0,0,map[m].xs,map[m].ys,BL_MOB, event ,allflag); - return 0; -} - -int buildin_killmonsterall_sub(struct block_list *bl,va_list ap) -{ - mob_delete((struct mob_data *)bl); - return 0; -} -int buildin_killmonsterall(struct script_state *st) -{ - char *mapname; - int m; - mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - - if( (m=map_mapname2mapid(mapname))<0 ) - return 0; - map_foreachinarea(buildin_killmonsterall_sub, - m,0,0,map[m].xs,map[m].ys,BL_MOB); - return 0; -} - -/*========================================== - * イベント実行 - *------------------------------------------ - */ -int buildin_doevent(struct script_state *st) -{ - char *event; - event=conv_str(st,& (st->stack->stack_data[st->start+2])); - npc_event(map_id2sd(st->rid),event,0); - return 0; -} -/*========================================== - * NPC主体イベント実行 - *------------------------------------------ - */ -int buildin_donpcevent(struct script_state *st) -{ - char *event; - event=conv_str(st,& (st->stack->stack_data[st->start+2])); - npc_event_do(event); - return 0; -} -/*========================================== - * イベントタイマー追加 - *------------------------------------------ - */ -int buildin_addtimer(struct script_state *st) -{ - char *event; - int tick; - tick=conv_num(st,& (st->stack->stack_data[st->start+2])); - event=conv_str(st,& (st->stack->stack_data[st->start+3])); - pc_addeventtimer(script_rid2sd(st),tick,event); - return 0; -} -/*========================================== - * イベントタイマー削除 - *------------------------------------------ - */ -int buildin_deltimer(struct script_state *st) -{ - char *event; - event=conv_str(st,& (st->stack->stack_data[st->start+2])); - pc_deleventtimer(script_rid2sd(st),event); - return 0; -} -/*========================================== - * イベントタイマーのカウント値追加 - *------------------------------------------ - */ -int buildin_addtimercount(struct script_state *st) -{ - char *event; - int tick; - event=conv_str(st,& (st->stack->stack_data[st->start+2])); - tick=conv_num(st,& (st->stack->stack_data[st->start+3])); - pc_addeventtimercount(script_rid2sd(st),event,tick); - return 0; -} - -/*========================================== - * NPCタイマー初期化 - *------------------------------------------ - */ -int buildin_initnpctimer(struct script_state *st) -{ - struct npc_data *nd; - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - npc_settimerevent_tick(nd,0); - npc_timerevent_start(nd, st->rid); - return 0; -} -/*========================================== - * NPCタイマー開始 - *------------------------------------------ - */ -int buildin_startnpctimer(struct script_state *st) -{ - struct npc_data *nd; - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - npc_timerevent_start(nd, st->rid); - return 0; -} -/*========================================== - * NPCタイマー停止 - *------------------------------------------ - */ -int buildin_stopnpctimer(struct script_state *st) -{ - struct npc_data *nd; - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - npc_timerevent_stop(nd); - return 0; -} -/*========================================== - * NPCタイマー情報所得 - *------------------------------------------ - */ -int buildin_getnpctimer(struct script_state *st) -{ - struct npc_data *nd; - int type=conv_num(st,& (st->stack->stack_data[st->start+2])); - int val=0; - if( st->end > st->start+3 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - switch(type){ - case 0: val=npc_gettimerevent_tick(nd); break; - case 1: val= (nd->u.scr.nexttimer>=0); break; - case 2: val= nd->u.scr.timeramount; break; - } - push_val(st->stack,C_INT,val); - return 0; -} -/*========================================== - * NPCタイマー値設定 - *------------------------------------------ - */ -int buildin_setnpctimer(struct script_state *st) -{ - int tick; - struct npc_data *nd; - tick=conv_num(st,& (st->stack->stack_data[st->start+2])); - if( st->end > st->start+3 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - npc_settimerevent_tick(nd,tick); - return 0; -} - -/*========================================== - * attaches the player rid to the timer [Celest] - *------------------------------------------ - */ -int buildin_attachnpctimer(struct script_state *st) -{ - struct map_session_data *sd; - struct npc_data *nd; - - nd=(struct npc_data *)map_id2bl(st->oid); - if( st->end > st->start+2 ) { - char *name = conv_str(st,& (st->stack->stack_data[st->start+2])); - sd=map_nick2sd(name); - } else { - sd = script_rid2sd(st); - } - - if (sd==NULL) - return 0; - - nd->u.scr.rid = sd->bl.id; - return 0; -} - -/*========================================== - * detaches a player rid from the timer [Celest] - *------------------------------------------ - */ -int buildin_detachnpctimer(struct script_state *st) -{ - struct npc_data *nd; - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - nd->u.scr.rid = 0; - return 0; -} - -/*========================================== - * 天の声アナウンス - *------------------------------------------ - */ -int buildin_announce(struct script_state *st) -{ - char *str; - int flag; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - flag=conv_num(st,& (st->stack->stack_data[st->start+3])); - - if(flag&0x0f){ - struct block_list *bl=(flag&0x08)? map_id2bl(st->oid) : - (struct block_list *)script_rid2sd(st); - clif_GMmessage(bl,str,strlen(str)+1,flag); - }else - intif_GMmessage(str,strlen(str)+1,flag); - return 0; -} -/*========================================== - * 天の声アナウンス(特定マップ) - *------------------------------------------ - */ -int buildin_mapannounce_sub(struct block_list *bl,va_list ap) -{ - char *str; - int len,flag; - str=va_arg(ap,char *); - len=va_arg(ap,int); - flag=va_arg(ap,int); - clif_GMmessage(bl,str,len,flag|3); - return 0; -} -int buildin_mapannounce(struct script_state *st) -{ - char *mapname,*str; - int flag,m; - - mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - str=conv_str(st,& (st->stack->stack_data[st->start+3])); - flag=conv_num(st,& (st->stack->stack_data[st->start+4])); - - if( (m=map_mapname2mapid(mapname))<0 ) - return 0; - map_foreachinarea(buildin_mapannounce_sub, - m,0,0,map[m].xs,map[m].ys,BL_PC, str,strlen(str)+1,flag&0x10); - return 0; -} -/*========================================== - * 天の声アナウンス(特定エリア) - *------------------------------------------ - */ -int buildin_areaannounce(struct script_state *st) -{ - char *map,*str; - int flag,m; - int x0,y0,x1,y1; - - map=conv_str(st,& (st->stack->stack_data[st->start+2])); - x0=conv_num(st,& (st->stack->stack_data[st->start+3])); - y0=conv_num(st,& (st->stack->stack_data[st->start+4])); - x1=conv_num(st,& (st->stack->stack_data[st->start+5])); - y1=conv_num(st,& (st->stack->stack_data[st->start+6])); - str=conv_str(st,& (st->stack->stack_data[st->start+7])); - flag=conv_num(st,& (st->stack->stack_data[st->start+8])); - - if( (m=map_mapname2mapid(map))<0 ) - return 0; - - map_foreachinarea(buildin_mapannounce_sub, - m,x0,y0,x1,y1,BL_PC, str,strlen(str)+1,flag&0x10 ); - return 0; -} -/*========================================== - * ユーザー数所得 - *------------------------------------------ - */ -int buildin_getusers(struct script_state *st) -{ - int flag=conv_num(st,& (st->stack->stack_data[st->start+2])); - struct block_list *bl=map_id2bl((flag&0x08)?st->oid:st->rid); - int val=0; - switch(flag&0x07){ - case 0: val=map[bl->m].users; break; - case 1: val=map_getusers(); break; - } - push_val(st->stack,C_INT,val); - return 0; -} -/*========================================== - * Works like @WHO - displays all online users names in window - *------------------------------------------ - */ -int buildin_getusersname(struct script_state *st) -{ - struct map_session_data *pl_sd = NULL; - int i=0,disp_num=1; - - for (i=0;i<fd_max;i++) - if(session[i] && (pl_sd=(struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){ - if( !(battle_config.hide_GM_session && pc_isGM(pl_sd)) ){ - if((disp_num++)%10==0) - clif_scriptnext(script_rid2sd(st),st->oid); - clif_scriptmes(script_rid2sd(st),st->oid,pl_sd->status.name); - } - } - return 0; -} -/*========================================== - * マップ指定ユーザー数所得 - *------------------------------------------ - */ -int buildin_getmapusers(struct script_state *st) -{ - char *str; - int m; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - if( (m=map_mapname2mapid(str))< 0){ - push_val(st->stack,C_INT,-1); - return 0; - } - push_val(st->stack,C_INT,map[m].users); - return 0; -} -/*========================================== - * エリア指定ユーザー数所得 - *------------------------------------------ - */ -int buildin_getareausers_sub(struct block_list *bl,va_list ap) -{ - int *users=va_arg(ap,int *); - (*users)++; - return 0; -} -int buildin_getareausers(struct script_state *st) -{ - char *str; - int m,x0,y0,x1,y1,users=0; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - x0=conv_num(st,& (st->stack->stack_data[st->start+3])); - y0=conv_num(st,& (st->stack->stack_data[st->start+4])); - x1=conv_num(st,& (st->stack->stack_data[st->start+5])); - y1=conv_num(st,& (st->stack->stack_data[st->start+6])); - if( (m=map_mapname2mapid(str))< 0){ - push_val(st->stack,C_INT,-1); - return 0; - } - map_foreachinarea(buildin_getareausers_sub, - m,x0,y0,x1,y1,BL_PC,&users); - push_val(st->stack,C_INT,users); - return 0; -} - -/*========================================== - * エリア指定ドロップアイテム数所得 - *------------------------------------------ - */ -int buildin_getareadropitem_sub(struct block_list *bl,va_list ap) -{ - int item=va_arg(ap,int); - int *amount=va_arg(ap,int *); - struct flooritem_data *drop=(struct flooritem_data *)bl; - - if(drop->item_data.nameid==item) - (*amount)+=drop->item_data.amount; - - return 0; -} -int buildin_getareadropitem(struct script_state *st) -{ - char *str; - int m,x0,y0,x1,y1,item,amount=0; - struct script_data *data; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - x0=conv_num(st,& (st->stack->stack_data[st->start+3])); - y0=conv_num(st,& (st->stack->stack_data[st->start+4])); - x1=conv_num(st,& (st->stack->stack_data[st->start+5])); - y1=conv_num(st,& (st->stack->stack_data[st->start+6])); - - data=&(st->stack->stack_data[st->start+7]); - get_val(st,data); - if( data->type==C_STR || data->type==C_CONSTSTR ){ - const char *name=conv_str(st,data); - struct item_data *item_data = itemdb_searchname(name); - item=512; - if( item_data ) - item=item_data->nameid; - }else - item=conv_num(st,data); - - if( (m=map_mapname2mapid(str))< 0){ - push_val(st->stack,C_INT,-1); - return 0; - } - map_foreachinarea(buildin_getareadropitem_sub, - m,x0,y0,x1,y1,BL_ITEM,item,&amount); - push_val(st->stack,C_INT,amount); - return 0; -} -/*========================================== - * NPCの有効化 - *------------------------------------------ - */ -int buildin_enablenpc(struct script_state *st) -{ - char *str; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - npc_enable(str,1); - return 0; -} -/*========================================== - * NPCの無効化 - *------------------------------------------ - */ -int buildin_disablenpc(struct script_state *st) -{ - char *str; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - npc_enable(str,0); - return 0; -} - -int buildin_enablearena(struct script_state *st) // Added by RoVeRT -{ - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - struct chat_data *cd; - - - if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL) - return 0; - - npc_enable(nd->name,1); - nd->arenaflag=1; - - if(cd->users>=cd->trigger && cd->npc_event[0]) - npc_timer_event(cd->npc_event); - - return 0; -} -int buildin_disablearena(struct script_state *st) // Added by RoVeRT -{ - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - nd->arenaflag=0; - - return 0; -} -/*========================================== - * 隠れているNPCの表示 - *------------------------------------------ - */ -int buildin_hideoffnpc(struct script_state *st) -{ - char *str; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - npc_enable(str,2); - return 0; -} -/*========================================== - * NPCをハイディング - *------------------------------------------ - */ -int buildin_hideonnpc(struct script_state *st) -{ - char *str; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - npc_enable(str,4); - return 0; -} -/*========================================== - * 状態異常にかかる - *------------------------------------------ - */ -int buildin_sc_start(struct script_state *st) -{ - struct block_list *bl; - int type,tick,val1; - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - tick=conv_num(st,& (st->stack->stack_data[st->start+3])); - val1=conv_num(st,& (st->stack->stack_data[st->start+4])); - if( st->end>st->start+5 ) //指定したキャラを状態異常にする - bl = map_id2bl(conv_num(st,& (st->stack->stack_data[st->start+5]))); - else - bl = map_id2bl(st->rid); - - if (bl != 0) { - if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag) - bl = map_id2bl(((struct map_session_data *)bl)->skilltarget); - status_change_start(bl,type,val1,0,0,0,tick,0); - } - return 0; -} - -/*========================================== - * 状態異常にかかる(確率指定) - *------------------------------------------ - */ -int buildin_sc_start2(struct script_state *st) -{ - struct block_list *bl; - int type,tick,val1,per; - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - tick=conv_num(st,& (st->stack->stack_data[st->start+3])); - val1=conv_num(st,& (st->stack->stack_data[st->start+4])); - per=conv_num(st,& (st->stack->stack_data[st->start+5])); - if( st->end>st->start+6 ) //指定したキャラを状態異常にする - bl = map_id2bl(conv_num(st,& (st->stack->stack_data[st->start+6]))); - else - bl = map_id2bl(st->rid); - if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag) - bl = map_id2bl(((struct map_session_data *)bl)->skilltarget); - if(rand()%10000 < per) - status_change_start(bl,type,val1,0,0,0,tick,0); - return 0; -} - -/*========================================== - * 状態異常が直る - *------------------------------------------ - */ -int buildin_sc_end(struct script_state *st) -{ - struct block_list *bl; - int type; - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - bl = map_id2bl(st->rid); - if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag) - bl = map_id2bl(((struct map_session_data *)bl)->skilltarget); - status_change_end(bl,type,-1); -// if(battle_config.etc_log) -// printf("sc_end : %d %d\n",st->rid,type); - return 0; -} -/*========================================== - * 状態異常耐性を計算した確率を返す - *------------------------------------------ - */ -int buildin_getscrate(struct script_state *st) -{ - struct block_list *bl; - int sc_def,type,rate; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - rate=conv_num(st,& (st->stack->stack_data[st->start+3])); - if( st->end>st->start+4 ) //指定したキャラの耐性を計算する - bl = map_id2bl(conv_num(st,& (st->stack->stack_data[st->start+6]))); - else - bl = map_id2bl(st->rid); - - sc_def = status_get_sc_def(bl,type); - - rate = rate * sc_def / 100; - push_val(st->stack,C_INT,rate); - - return 0; - -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_debugmes(struct script_state *st) -{ - conv_str(st,& (st->stack->stack_data[st->start+2])); - printf("script debug : %d %d : %s\n",st->rid,st->oid,st->stack->stack_data[st->start+2].u.str); - return 0; -} - -/*========================================== - *捕獲アイテム使用 - *------------------------------------------ - */ -int buildin_catchpet(struct script_state *st) -{ - int pet_id; - struct map_session_data *sd; - pet_id= conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - pet_catch_process1(sd,pet_id); - return 0; -} - -/*========================================== - *携帯卵孵化機使用 - *------------------------------------------ - */ -int buildin_birthpet(struct script_state *st) -{ - struct map_session_data *sd; - sd=script_rid2sd(st); - clif_sendegg(sd); - return 0; -} - -/*========================================== - * Added - AppleGirl For Advanced Classes, (Updated for Cleaner Script Purposes) - *------------------------------------------ - */ -int buildin_resetlvl(struct script_state *st) -{ - struct map_session_data *sd; - - int type=conv_num(st,& (st->stack->stack_data[st->start+2])); - - sd=script_rid2sd(st); - pc_resetlvl(sd,type); - return 0; -} -/*========================================== - * ステータスリセット - *------------------------------------------ - */ -int buildin_resetstatus(struct script_state *st) -{ - struct map_session_data *sd; - sd=script_rid2sd(st); - pc_resetstate(sd); - return 0; -} - -/*========================================== - * スキルリセット - *------------------------------------------ - */ -int buildin_resetskill(struct script_state *st) -{ - struct map_session_data *sd; - sd=script_rid2sd(st); - pc_resetskill(sd); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int buildin_changebase(struct script_state *st) -{ - struct map_session_data *sd=NULL; - int vclass; - - if( st->end>st->start+3 ) - sd=map_id2sd(conv_num(st,& (st->stack->stack_data[st->start+3]))); - else - sd=script_rid2sd(st); - - if(sd == NULL) - return 0; - - vclass = conv_num(st,& (st->stack->stack_data[st->start+2])); - if(vclass == 22 && !battle_config.wedding_modifydisplay) - return 0; - -// if(vclass==22) { -// pc_unequipitem(sd,sd->equip_index[9],0); // 装備外 -// } - - sd->view_class = vclass; - - return 0; -} - -/*========================================== - * 性別変換 - *------------------------------------------ - */ -int buildin_changesex(struct script_state *st) { - struct map_session_data *sd = NULL; - sd = script_rid2sd(st); - - if (sd->status.sex == 0) { - sd->status.sex = 1; - sd->sex = 1; - if (sd->status.class_ == 20 || sd->status.class_ == 4021) - sd->status.class_ -= 1; - } else if (sd->status.sex == 1) { - sd->status.sex = 0; - sd->sex = 0; - if(sd->status.class_ == 19 || sd->status.class_ == 4020) - sd->status.class_ += 1; - } - chrif_char_ask_name(-1, sd->status.name, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex - chrif_save(sd); - return 0; -} - -/*========================================== - * npcチャット作成 - *------------------------------------------ - */ -int buildin_waitingroom(struct script_state *st) -{ - char *name,*ev=""; - int limit, trigger = 0,pub=1; - name=conv_str(st,& (st->stack->stack_data[st->start+2])); - limit= conv_num(st,& (st->stack->stack_data[st->start+3])); - if(limit==0) - pub=3; - - if( (st->end > st->start+5) ){ - struct script_data* data=&(st->stack->stack_data[st->start+5]); - get_val(st,data); - if(data->type==C_INT){ - // 新Athena仕様(旧Athena仕様と互換性あり) - ev=conv_str(st,& (st->stack->stack_data[st->start+4])); - trigger=conv_num(st,& (st->stack->stack_data[st->start+5])); - }else{ - // eathena仕様 - trigger=conv_num(st,& (st->stack->stack_data[st->start+4])); - ev=conv_str(st,& (st->stack->stack_data[st->start+5])); - } - }else{ - // 旧Athena仕様 - if( st->end > st->start+4 ) - ev=conv_str(st,& (st->stack->stack_data[st->start+4])); - } - chat_createnpcchat( (struct npc_data *)map_id2bl(st->oid), - limit,pub,trigger,name,strlen(name)+1,ev); - return 0; -} -/*========================================== - * Works like 'announce' but outputs in the common chat window - *------------------------------------------ - */ -int buildin_globalmes(struct script_state *st) -{ - struct block_list *bl = map_id2bl(st->oid); - struct npc_data *nd = (struct npc_data *)bl; - char *name=NULL,*mes; - - mes=conv_str(st,& (st->stack->stack_data[st->start+2])); // メッセージの取得 - if(mes==NULL) return 0; - - if(st->end>st->start+3){ // NPC名の取得(123#456) - name=conv_str(st,& (st->stack->stack_data[st->start+3])); - } else { - name=nd->name; - } - - npc_globalmessage(name,mes); // グローバルメッセージ送信 - - return 0; -} -/*========================================== - * npcチャット削除 - *------------------------------------------ - */ -int buildin_delwaitingroom(struct script_state *st) -{ - struct npc_data *nd; - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - chat_deletenpcchat(nd); - return 0; -} -/*========================================== - * npcチャット全員蹴り出す - *------------------------------------------ - */ -int buildin_waitingroomkickall(struct script_state *st) -{ - struct npc_data *nd; - struct chat_data *cd; - - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL ) - return 0; - chat_npckickall(cd); - return 0; -} - -/*========================================== - * npcチャットイベント有効化 - *------------------------------------------ - */ -int buildin_enablewaitingroomevent(struct script_state *st) -{ - struct npc_data *nd; - struct chat_data *cd; - - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL ) - return 0; - chat_enableevent(cd); - return 0; -} - -/*========================================== - * npcチャットイベント無効化 - *------------------------------------------ - */ -int buildin_disablewaitingroomevent(struct script_state *st) -{ - struct npc_data *nd; - struct chat_data *cd; - - if( st->end > st->start+2 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL ) - return 0; - chat_disableevent(cd); - return 0; -} -/*========================================== - * npcチャット状態所得 - *------------------------------------------ - */ -int buildin_getwaitingroomstate(struct script_state *st) -{ - struct npc_data *nd; - struct chat_data *cd; - int val=0,type; - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - if( st->end > st->start+3 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL ){ - push_val(st->stack,C_INT,-1); - return 0; - } - - switch(type){ - case 0: val=cd->users; break; - case 1: val=cd->limit; break; - case 2: val=cd->trigger&0x7f; break; - case 3: val=((cd->trigger&0x80)>0); break; - case 32: val=(cd->users >= cd->limit); break; - case 33: val=(cd->users >= cd->trigger); break; - - case 4: - push_str(st->stack,C_CONSTSTR,(unsigned char *) cd->title); - return 0; - case 5: - push_str(st->stack,C_CONSTSTR,(unsigned char *) cd->pass); - return 0; - case 16: - push_str(st->stack,C_CONSTSTR,(unsigned char *) cd->npc_event); - return 0; - } - push_val(st->stack,C_INT,val); - return 0; -} - -/*========================================== - * チャットメンバー(規定人数)ワープ - *------------------------------------------ - */ -int buildin_warpwaitingpc(struct script_state *st) -{ - int x,y,i,n; - char *str; - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - struct chat_data *cd; - - if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL ) - return 0; - - n=cd->trigger&0x7f; - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - x=conv_num(st,& (st->stack->stack_data[st->start+3])); - y=conv_num(st,& (st->stack->stack_data[st->start+4])); - - if( st->end > st->start+5 ) - n=conv_num(st,& (st->stack->stack_data[st->start+5])); - - for(i=0;i<n;i++){ - struct map_session_data *sd=cd->usersd[0]; // リスト先頭のPCを次々に。 - - mapreg_setreg(add_str((unsigned char *) "$@warpwaitingpc")+(i<<24),sd->bl.id); - - if(strcmp(str,"Random")==0) - pc_randomwarp(sd,3); - else if(strcmp(str,"SavePoint")==0){ - if(map[sd->bl.m].flag.noteleport) // テレポ禁止 - return 0; - - pc_setpos(sd,sd->status.save_point.map, - sd->status.save_point.x,sd->status.save_point.y,3); - }else - pc_setpos(sd,str,x,y,0); - } - mapreg_setreg(add_str((unsigned char *) "$@warpwaitingpcnum"),n); - return 0; -} -/*========================================== - * RIDのアタッチ - *------------------------------------------ - */ -int buildin_attachrid(struct script_state *st) -{ - st->rid=conv_num(st,& (st->stack->stack_data[st->start+2])); - push_val(st->stack,C_INT, (map_id2sd(st->rid)!=NULL)); - return 0; -} -/*========================================== - * RIDのデタッチ - *------------------------------------------ - */ -int buildin_detachrid(struct script_state *st) -{ - st->rid=0; - return 0; -} -/*========================================== - * 存在チェック - *------------------------------------------ - */ -int buildin_isloggedin(struct script_state *st) -{ - push_val(st->stack,C_INT, map_id2sd( - conv_num(st,& (st->stack->stack_data[st->start+2])) )!=NULL ); - return 0; -} - - -/*========================================== - * - *------------------------------------------ - */ -enum { MF_NOMEMO,MF_NOTELEPORT,MF_NOSAVE,MF_NOBRANCH,MF_NOPENALTY,MF_NOZENYPENALTY, - MF_PVP,MF_PVP_NOPARTY,MF_PVP_NOGUILD,MF_GVG,MF_GVG_NOPARTY,MF_NOTRADE,MF_NOSKILL, - MF_NOWARP,MF_NOPVP,MF_NOICEWALL,MF_SNOW,MF_FOG,MF_SAKURA,MF_LEAVES,MF_RAIN,MF_INDOORS,MF_NOGO }; - -int buildin_setmapflagnosave(struct script_state *st) -{ - int m,x,y; - char *str,*str2; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - str2=conv_str(st,& (st->stack->stack_data[st->start+3])); - x=conv_num(st,& (st->stack->stack_data[st->start+4])); - y=conv_num(st,& (st->stack->stack_data[st->start+5])); - m = map_mapname2mapid(str); - if(m >= 0) { - map[m].flag.nosave=1; - memcpy(map[m].save.map,str2,16); - map[m].save.x=x; - map[m].save.y=y; - } - - return 0; -} - -int buildin_setmapflag(struct script_state *st) -{ - int m,i; - char *str; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - i=conv_num(st,& (st->stack->stack_data[st->start+3])); - m = map_mapname2mapid(str); - if(m >= 0) { - switch(i) { - case MF_NOMEMO: - map[m].flag.nomemo=1; - break; - case MF_NOTELEPORT: - map[m].flag.noteleport=1; - break; - case MF_NOBRANCH: - map[m].flag.nobranch=1; - break; - case MF_NOPENALTY: - map[m].flag.nopenalty=1; - break; - case MF_NOZENYPENALTY: - map[m].flag.nozenypenalty=1; - break; - case MF_PVP: - map[m].flag.pvp=1; - break; - case MF_PVP_NOPARTY: - map[m].flag.pvp_noparty=1; - break; - case MF_PVP_NOGUILD: - map[m].flag.pvp_noguild=1; - break; - case MF_GVG: - map[m].flag.gvg=1; - break; - case MF_GVG_NOPARTY: - map[m].flag.gvg_noparty=1; - break; - case MF_NOTRADE: - map[m].flag.notrade=1; - break; - case MF_NOSKILL: - map[m].flag.noskill=1; - break; - case MF_NOWARP: - map[m].flag.nowarp=1; - break; - case MF_NOPVP: - map[m].flag.nopvp=1; - break; - case MF_NOICEWALL: // [Valaris] - map[m].flag.noicewall=1; - break; - case MF_SNOW: // [Valaris] - map[m].flag.snow=1; - break; - case MF_FOG: // [Valaris] - map[m].flag.fog=1; - break; - case MF_SAKURA: // [Valaris] - map[m].flag.sakura=1; - break; - case MF_LEAVES: // [Valaris] - map[m].flag.leaves=1; - break; - case MF_RAIN: // [Valaris] - map[m].flag.rain=1; - break; - case MF_INDOORS: // celest - map[m].flag.indoors=1; - break; - case MF_NOGO: // celest - map[m].flag.nogo=1; - break; - - } - } - - return 0; -} - -int buildin_removemapflag(struct script_state *st) -{ - int m,i; - char *str; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - i=conv_num(st,& (st->stack->stack_data[st->start+3])); - m = map_mapname2mapid(str); - if(m >= 0) { - switch(i) { - case MF_NOMEMO: - map[m].flag.nomemo=0; - break; - case MF_NOTELEPORT: - map[m].flag.noteleport=0; - break; - case MF_NOSAVE: - map[m].flag.nosave=0; - break; - case MF_NOBRANCH: - map[m].flag.nobranch=0; - break; - case MF_NOPENALTY: - map[m].flag.nopenalty=0; - break; - case MF_PVP: - map[m].flag.pvp=0; - break; - case MF_PVP_NOPARTY: - map[m].flag.pvp_noparty=0; - break; - case MF_PVP_NOGUILD: - map[m].flag.pvp_noguild=0; - break; - case MF_GVG: - map[m].flag.gvg=0; - break; - case MF_GVG_NOPARTY: - map[m].flag.gvg_noparty=0; - break; - case MF_NOZENYPENALTY: - map[m].flag.nozenypenalty=0; - break; - case MF_NOSKILL: - map[m].flag.noskill=0; - break; - case MF_NOWARP: - map[m].flag.nowarp=0; - break; - case MF_NOPVP: - map[m].flag.nopvp=0; - break; - case MF_NOICEWALL: // [Valaris] - map[m].flag.noicewall=0; - break; - case MF_SNOW: // [Valaris] - map[m].flag.snow=0; - break; - case MF_FOG: // [Valaris] - map[m].flag.fog=0; - break; - case MF_SAKURA: // [Valaris] - map[m].flag.sakura=0; - break; - case MF_LEAVES: // [Valaris] - map[m].flag.leaves=0; - break; - case MF_RAIN: // [Valaris] - map[m].flag.rain=0; - break; - case MF_INDOORS: // celest - map[m].flag.indoors=0; - break; - case MF_NOGO: // celest - map[m].flag.nogo=0; - break; - } - } - - return 0; -} - -int buildin_pvpon(struct script_state *st) -{ - int m,i; - char *str; - struct map_session_data *pl_sd=NULL; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - m = map_mapname2mapid(str); - if(m >= 0 && !map[m].flag.pvp && !map[m].flag.nopvp) { - map[m].flag.pvp = 1; - clif_send0199(m,1); - - if(battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris] - return 0; - - for(i=0;i<fd_max;i++){ //人数分ループ - if(session[i] && (pl_sd=(struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){ - if(m == pl_sd->bl.m && pl_sd->pvp_timer == -1) { - pl_sd->pvp_timer=add_timer(gettick()+200,pc_calc_pvprank_timer,pl_sd->bl.id,0); - pl_sd->pvp_rank=0; - pl_sd->pvp_lastusers=0; - pl_sd->pvp_point=5; - } - } - } - } - - return 0; -} - -int buildin_pvpoff(struct script_state *st) -{ - int m,i; - char *str; - struct map_session_data *pl_sd=NULL; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - m = map_mapname2mapid(str); - if(m >= 0 && map[m].flag.pvp && map[m].flag.nopvp) { - map[m].flag.pvp = 0; - clif_send0199(m,0); - - if(battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris] - return 0; - - for(i=0;i<fd_max;i++){ //人数分ループ - if(session[i] && (pl_sd=(struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){ - if(m == pl_sd->bl.m) { - clif_pvpset(pl_sd,0,0,2); - if(pl_sd->pvp_timer != -1) { - delete_timer(pl_sd->pvp_timer,pc_calc_pvprank_timer); - pl_sd->pvp_timer = -1; - } - } - } - } - } - - return 0; -} - -int buildin_gvgon(struct script_state *st) -{ - int m; - char *str; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - m = map_mapname2mapid(str); - if(m >= 0 && !map[m].flag.gvg) { - map[m].flag.gvg = 1; - clif_send0199(m,3); - } - - return 0; -} -int buildin_gvgoff(struct script_state *st) -{ - int m; - char *str; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - m = map_mapname2mapid(str); - if(m >= 0 && map[m].flag.gvg) { - map[m].flag.gvg = 0; - clif_send0199(m,0); - } - - return 0; -} -/*========================================== - * NPCエモーション - *------------------------------------------ - */ - -int buildin_emotion(struct script_state *st) -{ - int type; - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - if(type < 0 || type > 100) - return 0; - clif_emotion(map_id2bl(st->oid),type); - return 0; -} - -int buildin_maprespawnguildid_sub(struct block_list *bl,va_list ap) -{ - int g_id=va_arg(ap,int); - int flag=va_arg(ap,int); - struct map_session_data *sd=NULL; - struct mob_data *md=NULL; - - if(bl->type == BL_PC) - sd=(struct map_session_data*)bl; - if(bl->type == BL_MOB) - md=(struct mob_data *)bl; - - if(sd){ - if((sd->status.guild_id == g_id) && (flag&1)) - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,3); - else if((sd->status.guild_id != g_id) && (flag&2)) - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,3); - else if (sd->status.guild_id == 0) // Warp out players not in guild [Valaris] - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,3); // end addition [Valaris] - } - if(md && flag&4){ - if(md->class_ < 1285 || md->class_ > 1288) - mob_delete(md); - } - return 0; -} -int buildin_maprespawnguildid(struct script_state *st) -{ - char *mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - int g_id=conv_num(st,& (st->stack->stack_data[st->start+3])); - int flag=conv_num(st,& (st->stack->stack_data[st->start+4])); - - int m=map_mapname2mapid(mapname); - - if(m) map_foreachinarea(buildin_maprespawnguildid_sub,m,0,0,map[m].xs-1,map[m].ys-1,BL_NUL,g_id,flag); - return 0; -} - -int buildin_agitstart(struct script_state *st) -{ - if(agit_flag==1) return 1; // Agit already Start. - agit_flag=1; - guild_agit_start(); - return 0; -} - -int buildin_agitend(struct script_state *st) -{ - if(agit_flag==0) return 1; // Agit already End. - agit_flag=0; - guild_agit_end(); - return 0; -} -/*========================================== - * agitcheck 1; // choice script - * if(@agit_flag == 1) goto agit; - * if(agitcheck(0) == 1) goto agit; - *------------------------------------------ - */ -int buildin_agitcheck(struct script_state *st) -{ - struct map_session_data *sd; - int cond; - - cond=conv_num(st,& (st->stack->stack_data[st->start+2])); - - if(cond == 0) { - if (agit_flag==1) push_val(st->stack,C_INT,1); - if (agit_flag==0) push_val(st->stack,C_INT,0); - } else { - sd=script_rid2sd(st); - if (agit_flag==1) pc_setreg(sd,add_str((unsigned char *) "@agit_flag"),1); - if (agit_flag==0) pc_setreg(sd,add_str((unsigned char *) "@agit_flag"),0); - } - return 0; -} -int buildin_flagemblem(struct script_state *st) -{ - int g_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - - if(g_id < 0) return 0; - -// printf("Script.c: [FlagEmblem] GuildID=%d, Emblem=%d.\n", g->guild_id, g->emblem_id); - ((struct npc_data *)map_id2bl(st->oid))->u.scr.guild_id = g_id; - return 1; -} - -int buildin_getcastlename(struct script_state *st) -{ - char *mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - struct guild_castle *gc; - int i; - char *buf=NULL; - for(i=0;i<MAX_GUILDCASTLE;i++){ - if( (gc=guild_castle_search(i)) != NULL ){ - if(strcmp(mapname,gc->map_name)==0){ - buf=(char *)aCallocA(24,sizeof(char)); - strncpy(buf,gc->castle_name,24); - break; - } - } - } - if(buf) - push_str(st->stack,C_STR,(unsigned char *) buf); - else - push_str(st->stack,C_CONSTSTR,(unsigned char *) ""); - return 0; -} - -int buildin_getcastledata(struct script_state *st) -{ - char *mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - int index=conv_num(st,& (st->stack->stack_data[st->start+3])); - char *event=NULL; - struct guild_castle *gc; - int i,j; - - if( st->end>st->start+4 && index==0){ - for(i=0,j=-1;i<MAX_GUILDCASTLE;i++) - if( (gc=guild_castle_search(i)) != NULL && - strcmp(mapname,gc->map_name)==0 ) - j=i; - if(j>=0){ - event=conv_str(st,& (st->stack->stack_data[st->start+4])); - guild_addcastleinfoevent(j,17,event); - } - } - - for(i=0;i<MAX_GUILDCASTLE;i++){ - if( (gc=guild_castle_search(i)) != NULL ){ - if(strcmp(mapname,gc->map_name)==0){ - switch(index){ - case 0: for(j=1;j<26;j++) guild_castledataload(gc->castle_id,j); break; // Initialize[AgitInit] - case 1: push_val(st->stack,C_INT,gc->guild_id); break; - case 2: push_val(st->stack,C_INT,gc->economy); break; - case 3: push_val(st->stack,C_INT,gc->defense); break; - case 4: push_val(st->stack,C_INT,gc->triggerE); break; - case 5: push_val(st->stack,C_INT,gc->triggerD); break; - case 6: push_val(st->stack,C_INT,gc->nextTime); break; - case 7: push_val(st->stack,C_INT,gc->payTime); break; - case 8: push_val(st->stack,C_INT,gc->createTime); break; - case 9: push_val(st->stack,C_INT,gc->visibleC); break; - case 10: push_val(st->stack,C_INT,gc->visibleG0); break; - case 11: push_val(st->stack,C_INT,gc->visibleG1); break; - case 12: push_val(st->stack,C_INT,gc->visibleG2); break; - case 13: push_val(st->stack,C_INT,gc->visibleG3); break; - case 14: push_val(st->stack,C_INT,gc->visibleG4); break; - case 15: push_val(st->stack,C_INT,gc->visibleG5); break; - case 16: push_val(st->stack,C_INT,gc->visibleG6); break; - case 17: push_val(st->stack,C_INT,gc->visibleG7); break; - case 18: push_val(st->stack,C_INT,gc->Ghp0); break; - case 19: push_val(st->stack,C_INT,gc->Ghp1); break; - case 20: push_val(st->stack,C_INT,gc->Ghp2); break; - case 21: push_val(st->stack,C_INT,gc->Ghp3); break; - case 22: push_val(st->stack,C_INT,gc->Ghp4); break; - case 23: push_val(st->stack,C_INT,gc->Ghp5); break; - case 24: push_val(st->stack,C_INT,gc->Ghp6); break; - case 25: push_val(st->stack,C_INT,gc->Ghp7); break; - default: - push_val(st->stack,C_INT,0); break; - } - return 0; - } - } - } - push_val(st->stack,C_INT,0); - return 0; -} - -int buildin_setcastledata(struct script_state *st) -{ - char *mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - int index=conv_num(st,& (st->stack->stack_data[st->start+3])); - int value=conv_num(st,& (st->stack->stack_data[st->start+4])); - struct guild_castle *gc; - int i; - - for(i=0;i<MAX_GUILDCASTLE;i++){ - if( (gc=guild_castle_search(i)) != NULL ){ - if(strcmp(mapname,gc->map_name)==0){ - // Save Data byself First - switch(index){ - case 1: gc->guild_id = value; break; - case 2: gc->economy = value; break; - case 3: gc->defense = value; break; - case 4: gc->triggerE = value; break; - case 5: gc->triggerD = value; break; - case 6: gc->nextTime = value; break; - case 7: gc->payTime = value; break; - case 8: gc->createTime = value; break; - case 9: gc->visibleC = value; break; - case 10: gc->visibleG0 = value; break; - case 11: gc->visibleG1 = value; break; - case 12: gc->visibleG2 = value; break; - case 13: gc->visibleG3 = value; break; - case 14: gc->visibleG4 = value; break; - case 15: gc->visibleG5 = value; break; - case 16: gc->visibleG6 = value; break; - case 17: gc->visibleG7 = value; break; - case 18: gc->Ghp0 = value; break; - case 19: gc->Ghp1 = value; break; - case 20: gc->Ghp2 = value; break; - case 21: gc->Ghp3 = value; break; - case 22: gc->Ghp4 = value; break; - case 23: gc->Ghp5 = value; break; - case 24: gc->Ghp6 = value; break; - case 25: gc->Ghp7 = value; break; - default: return 0; - } - guild_castledatasave(gc->castle_id,index,value); - return 0; - } - } - } - return 0; -} - -/* ===================================================================== - * ギルド情報を要求する - * --------------------------------------------------------------------- - */ -int buildin_requestguildinfo(struct script_state *st) -{ - int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - char *event=NULL; - - if( st->end>st->start+3 ) - event=conv_str(st,& (st->stack->stack_data[st->start+3])); - - if(guild_id>0) - guild_npc_request_info(guild_id,event); - return 0; -} - -/* ===================================================================== - * カードの数を得る - * --------------------------------------------------------------------- - */ -int buildin_getequipcardcnt(struct script_state *st) -{ - int i,num; - struct map_session_data *sd; - int c=4; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(sd->status.inventory[i].card[0] == 0x00ff){ // 製造武器はカードなし - push_val(st->stack,C_INT,0); - return 0; - } - do{ - if( (sd->status.inventory[i].card[c-1] > 4000 && - sd->status.inventory[i].card[c-1] < 5000) || - itemdb_type(sd->status.inventory[i].card[c-1]) == 6){ // [Celest] - push_val(st->stack,C_INT,(c)); - return 0; - } - }while(c--); - push_val(st->stack,C_INT,0); - return 0; -} - -/* ================================================================ - * カード取り外し成功 - * ---------------------------------------------------------------- - */ -int buildin_successremovecards(struct script_state *st) -{ - int i,num,cardflag=0,flag; - struct map_session_data *sd; - struct item item_tmp; - int c=4; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(sd->status.inventory[i].card[0]==0x00ff){ // 製造武器は処理しない - return 0; - } - do{ - if( (sd->status.inventory[i].card[c-1] > 4000 && - sd->status.inventory[i].card[c-1] < 5000) || - itemdb_type(sd->status.inventory[i].card[c-1]) == 6){ // [Celest] - - cardflag = 1; - item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].card[c-1]; - item_tmp.equip=0,item_tmp.identify=1,item_tmp.refine=0; - item_tmp.attribute=0; - item_tmp.card[0]=0,item_tmp.card[1]=0,item_tmp.card[2]=0,item_tmp.card[3]=0; - - if((flag=pc_additem(sd,&item_tmp,1))){ // 持てないならドロップ - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - }while(c--); - - if(cardflag == 1){ // カードを取り除いたアイテム所得 - flag=0; - item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].nameid; - item_tmp.equip=0,item_tmp.identify=1,item_tmp.refine=sd->status.inventory[i].refine; - item_tmp.attribute=sd->status.inventory[i].attribute; - item_tmp.card[0]=0,item_tmp.card[1]=0,item_tmp.card[2]=0,item_tmp.card[3]=0; - pc_delitem(sd,i,1,0); - if((flag=pc_additem(sd,&item_tmp,1))){ // もてないならドロップ - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - clif_misceffect(&sd->bl,3); - return 0; - } - return 0; -} - -/* ================================================================ - * カード取り外し失敗 slot,type - * type=0: 両方損失、1:カード損失、2:武具損失、3:損失無し - * ---------------------------------------------------------------- - */ -int buildin_failedremovecards(struct script_state *st) -{ - int i,num,cardflag=0,flag,typefail; - struct map_session_data *sd; - struct item item_tmp; - int c=4; - - num=conv_num(st,& (st->stack->stack_data[st->start+2])); - typefail=conv_num(st,& (st->stack->stack_data[st->start+3])); - sd=script_rid2sd(st); - i=pc_checkequip(sd,equip[num-1]); - if(sd->status.inventory[i].card[0]==0x00ff){ // 製造武器は処理しない - return 0; - } - do{ - if( (sd->status.inventory[i].card[c-1] > 4000 && - sd->status.inventory[i].card[c-1] < 5000) || - itemdb_type(sd->status.inventory[i].card[c-1]) == 6){ // [Celest] - - cardflag = 1; - - if(typefail == 2){ // 武具のみ損失なら、カードは受け取らせる - item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].card[c-1]; - item_tmp.equip=0,item_tmp.identify=1,item_tmp.refine=0; - item_tmp.attribute=0; - item_tmp.card[0]=0,item_tmp.card[1]=0,item_tmp.card[2]=0,item_tmp.card[3]=0; - if((flag=pc_additem(sd,&item_tmp,1))){ - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - } - }while(c--); - - if(cardflag == 1){ - - if(typefail == 0 || typefail == 2){ // 武具損失 - pc_delitem(sd,i,1,0); - clif_misceffect(&sd->bl,2); - return 0; - } - if(typefail == 1){ // カードのみ損失(武具を返す) - flag=0; - item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].nameid; - item_tmp.equip=0,item_tmp.identify=1,item_tmp.refine=sd->status.inventory[i].refine; - item_tmp.attribute=sd->status.inventory[i].attribute; - item_tmp.card[0]=0,item_tmp.card[1]=0,item_tmp.card[2]=0,item_tmp.card[3]=0; - pc_delitem(sd,i,1,0); - if((flag=pc_additem(sd,&item_tmp,1))){ - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - clif_misceffect(&sd->bl,2); - return 0; - } - return 0; -} - -int buildin_mapwarp(struct script_state *st) // Added by RoVeRT -{ - int x,y,m; - char *str; - char *mapname; - int x0,y0,x1,y1; - - mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - x0=0; - y0=0; - x1=map[map_mapname2mapid(mapname)].xs; - y1=map[map_mapname2mapid(mapname)].ys; - str=conv_str(st,& (st->stack->stack_data[st->start+3])); - x=conv_num(st,& (st->stack->stack_data[st->start+4])); - y=conv_num(st,& (st->stack->stack_data[st->start+5])); - - if( (m=map_mapname2mapid(mapname))< 0) - return 0; - - map_foreachinarea(buildin_areawarp_sub, - m,x0,y0,x1,y1,BL_PC, str,x,y ); - return 0; -} - -int buildin_cmdothernpc(struct script_state *st) // Added by RoVeRT -{ - char *npc,*command; - - npc=conv_str(st,& (st->stack->stack_data[st->start+2])); - command=conv_str(st,& (st->stack->stack_data[st->start+3])); - - npc_command(map_id2sd(st->rid),npc,command); - return 0; -} - -int buildin_inittimer(struct script_state *st) // Added by RoVeRT -{ -// struct npc_data *nd=(struct npc_data*)map_id2bl(st->oid); -// nd->lastaction=nd->timer=gettick(); - - npc_do_ontimer(st->oid, 1); - - return 0; -} - -int buildin_stoptimer(struct script_state *st) // Added by RoVeRT -{ -// struct npc_data *nd=(struct npc_data*)map_id2bl(st->oid); -// nd->lastaction=nd->timer=-1; - - npc_do_ontimer(st->oid, 0); - - return 0; -} - -int buildin_mobcount_sub(struct block_list *bl,va_list ap) // Added by RoVeRT -{ - char *event=va_arg(ap,char *); - int *c=va_arg(ap,int *); - - if(strcmp(event,((struct mob_data *)bl)->npc_event)==0) - (*c)++; - return 0; -} - -int buildin_mobcount(struct script_state *st) // Added by RoVeRT -{ - char *mapname,*event; - int m,c=0; - mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); - event=conv_str(st,& (st->stack->stack_data[st->start+3])); - - if( (m=map_mapname2mapid(mapname))<0 ) { - push_val(st->stack,C_INT,-1); - return 0; - } - map_foreachinarea(buildin_mobcount_sub, - m,0,0,map[m].xs,map[m].ys,BL_MOB, event,&c ); - - push_val(st->stack,C_INT, (c - 1)); - - return 0; -} -int buildin_marriage(struct script_state *st) -{ - char *partner=conv_str(st,& (st->stack->stack_data[st->start+2])); - struct map_session_data *sd=script_rid2sd(st); - struct map_session_data *p_sd=map_nick2sd(partner); - - if(sd==NULL || p_sd==NULL || pc_marriage(sd,p_sd) < 0){ - push_val(st->stack,C_INT,0); - return 0; - } - push_val(st->stack,C_INT,1); - return 0; -} -int buildin_wedding_effect(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - struct block_list *bl; - - if(sd==NULL) { - bl=map_id2bl(st->oid); - } else - bl=&sd->bl; - clif_wedding_effect(bl); - return 0; -} -int buildin_divorce(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - if(sd==NULL || pc_divorce(sd) < 0){ - push_val(st->stack,C_INT,0); - return 0; - } - push_val(st->stack,C_INT,1); - return 0; -} - -int buildin_ispartneron(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - struct map_session_data *p_sd=NULL; - - if(sd==NULL || !pc_ismarried(sd) || - ((p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) == NULL)) { - push_val(st->stack,C_INT,0); - return 0; - } - - push_val(st->stack,C_INT,1); - return 0; -} - -int buildin_getpartnerid(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - if (sd == NULL) { - push_val(st->stack,C_INT,0); - return 0; - } - - push_val(st->stack,C_INT,sd->status.partner_id); - return 0; -} - -int buildin_warppartner(struct script_state *st) -{ - int x,y; - char *str; - struct map_session_data *sd=script_rid2sd(st); - struct map_session_data *p_sd=NULL; - - if(sd==NULL || !pc_ismarried(sd) || - ((p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) == NULL)) { - push_val(st->stack,C_INT,0); - return 0; - } - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - x=conv_num(st,& (st->stack->stack_data[st->start+3])); - y=conv_num(st,& (st->stack->stack_data[st->start+4])); - - pc_setpos(p_sd,str,x,y,0); - - push_val(st->stack,C_INT,1); - return 0; -} - -/*================================================ - * Script for Displaying MOB Information [Valaris] - *------------------------------------------------ - */ -int buildin_strmobinfo(struct script_state *st) -{ - - int num=conv_num(st,& (st->stack->stack_data[st->start+2])); - int class_=conv_num(st,& (st->stack->stack_data[st->start+3])); - - if((class_>=0 && class_<=1000) || class_ >2000) - return 0; - - switch (num) { - case 1: - { - char *buf; - buf=(char *) aCallocA(24, 1); -// buf=mob_db[class_].name; -// for string assignments you would need to go for c++ [Shinomori] - strcpy(buf,mob_db[class_].name); - push_str(st->stack,C_STR,(unsigned char *) buf); - break; - } - case 2: - { - char *buf; - buf=(char *) aCallocA(24, 1); -// buf=mob_db[class_].jname; -// for string assignments you would need to go for c++ [Shinomori] - strcpy(buf,mob_db[class_].jname); - push_str(st->stack,C_STR,(unsigned char *) buf); - break; - } - case 3: - push_val(st->stack,C_INT,mob_db[class_].lv); - break; - case 4: - push_val(st->stack,C_INT,mob_db[class_].max_hp); - break; - case 5: - push_val(st->stack,C_INT,mob_db[class_].max_sp); - break; - case 6: - push_val(st->stack,C_INT,mob_db[class_].base_exp); - break; - case 7: - push_val(st->stack,C_INT,mob_db[class_].job_exp); - break; - } - return 0; -} - -/*========================================== - * Summon guardians [Valaris] - *------------------------------------------ - */ -int buildin_guardian(struct script_state *st) -{ - int class_=0,amount=1,x=0,y=0,guardian=0; - char *str,*map,*event=""; - - map =conv_str(st,& (st->stack->stack_data[st->start+2])); - x =conv_num(st,& (st->stack->stack_data[st->start+3])); - y =conv_num(st,& (st->stack->stack_data[st->start+4])); - str =conv_str(st,& (st->stack->stack_data[st->start+5])); - class_=conv_num(st,& (st->stack->stack_data[st->start+6])); - amount=conv_num(st,& (st->stack->stack_data[st->start+7])); - event=conv_str(st,& (st->stack->stack_data[st->start+8])); - if( st->end>st->start+9 ) - guardian=conv_num(st,& (st->stack->stack_data[st->start+9])); - - mob_spawn_guardian(map_id2sd(st->rid),map,x,y,str,class_,amount,event,guardian); - - return 0; -} - -/*================================================ - * Script for Displaying Guardian Info [Valaris] - *------------------------------------------------ - */ -int buildin_guardianinfo(struct script_state *st) -{ - int guardian=conv_num(st,& (st->stack->stack_data[st->start+2])); - struct map_session_data *sd=script_rid2sd(st); - struct guild_castle *gc=guild_mapname2gc(map[sd->bl.m].name); - - if(guardian==0 && gc->visibleG0 == 1) push_val(st->stack,C_INT,gc->Ghp0); - if(guardian==1 && gc->visibleG1 == 1) push_val(st->stack,C_INT,gc->Ghp1); - if(guardian==2 && gc->visibleG2 == 1) push_val(st->stack,C_INT,gc->Ghp2); - if(guardian==3 && gc->visibleG3 == 1) push_val(st->stack,C_INT,gc->Ghp3); - if(guardian==4 && gc->visibleG4 == 1) push_val(st->stack,C_INT,gc->Ghp4); - if(guardian==5 && gc->visibleG5 == 1) push_val(st->stack,C_INT,gc->Ghp5); - if(guardian==6 && gc->visibleG6 == 1) push_val(st->stack,C_INT,gc->Ghp6); - if(guardian==7 && gc->visibleG7 == 1) push_val(st->stack,C_INT,gc->Ghp7); - else push_val(st->stack,C_INT,-1); - - return 0; -} -/*========================================== - * IDからItem名 - *------------------------------------------ - */ -int buildin_getitemname(struct script_state *st) -{ - int item_id; - struct item_data *i_data; - char *item_name; - - item_id=conv_num(st,& (st->stack->stack_data[st->start+2])); - - i_data = NULL; - i_data = itemdb_search(item_id); - item_name=(char *)aCallocA(24,sizeof(char)); - - strncpy(item_name,i_data->jname,23); - push_str(st->stack,C_STR,(unsigned char *) item_name); - return 0; -} - -/*========================================== - * petskillbonus [Valaris] - *------------------------------------------ - */ - -int buildin_petskillbonus(struct script_state *st) -{ - int type,val,duration,timer; - struct pet_data *pd; - - struct map_session_data *sd=script_rid2sd(st); - - if(sd==NULL || sd->pd==NULL) - return 0; - - pd=sd->pd; - - if(pd==NULL) - return 0; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - val=conv_num(st,& (st->stack->stack_data[st->start+3])); - duration=conv_num(st,& (st->stack->stack_data[st->start+4])); - timer=conv_num(st,& (st->stack->stack_data[st->start+5])); - - // initialise bonuses - pd->skillbonustype=type; - pd->skillbonusval=val; - pd->skillduration=duration*1000; - pd->skilltimer=timer*1000; - - if (pd->state.skillbonus == -1) - pd->state.skillbonus=0; // waiting state - - // wait for timer to start - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer,pet_skill_bonus_timer,sd->bl.id,0); - - return 0; -} - -/*========================================== - * pet looting [Valaris] - *------------------------------------------ - */ -int buildin_petloot(struct script_state *st) -{ - int max; - struct pet_data *pd; - - struct map_session_data *sd=script_rid2sd(st); - if(sd==NULL || sd->pd==NULL) - return 0; - - pd=sd->pd; - - if(pd==NULL) - return 0; - - max=conv_num(st,& (st->stack->stack_data[st->start+2])); - - if(!max) - return 0; - - pd->loot=1; - pd->lootmax=max; - - return 0; -} -/*========================================== - * PCの所持品情報読み取り - *------------------------------------------ - */ -int buildin_getinventorylist(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int i,j=0; - if(!sd) return 0; - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0){ - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_id")+(j<<24),sd->status.inventory[i].nameid); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_amount")+(j<<24),sd->status.inventory[i].amount); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_equip")+(j<<24),sd->status.inventory[i].equip); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_refine")+(j<<24),sd->status.inventory[i].refine); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_identify")+(j<<24),sd->status.inventory[i].identify); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_attribute")+(j<<24),sd->status.inventory[i].attribute); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card1")+(j<<24),sd->status.inventory[i].card[0]); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card2")+(j<<24),sd->status.inventory[i].card[1]); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card3")+(j<<24),sd->status.inventory[i].card[2]); - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card4")+(j<<24),sd->status.inventory[i].card[3]); - j++; - } - } - pc_setreg(sd,add_str((unsigned char *) "@inventorylist_count"),j); - return 0; -} - -int buildin_getskilllist(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int i,j=0; - if(!sd) return 0; - for(i=0;i<MAX_SKILL;i++){ - if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0){ - pc_setreg(sd,add_str((unsigned char *) "@skilllist_id")+(j<<24),sd->status.skill[i].id); - pc_setreg(sd,add_str((unsigned char *)"@skilllist_lv")+(j<<24),sd->status.skill[i].lv); - pc_setreg(sd,add_str((unsigned char *)"@skilllist_flag")+(j<<24),sd->status.skill[i].flag); - j++; - } - } - pc_setreg(sd,add_str((unsigned char *) "@skilllist_count"),j); - return 0; -} - -int buildin_clearitem(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int i; - if(sd==NULL) return 0; - for (i=0; i<MAX_INVENTORY; i++) { - if (sd->status.inventory[i].amount) - pc_delitem(sd, i, sd->status.inventory[i].amount, 0); - } - return 0; -} - -/*========================================== - * NPCクラスチェンジ - * classは変わりたいclass - * typeは通常0なのかな? - *------------------------------------------ - */ -int buildin_classchange(struct script_state *st) -{ - int _class,type; - struct block_list *bl=map_id2bl(st->oid); - - if(bl==NULL) return 0; - - _class=conv_num(st,& (st->stack->stack_data[st->start+2])); - type=conv_num(st,& (st->stack->stack_data[st->start+3])); - clif_class_change(bl,_class,type); - return 0; -} - -/*========================================== - * NPCから発生するエフェクト - *------------------------------------------ - */ -int buildin_misceffect(struct script_state *st) -{ - int type; - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - if(st->oid) - clif_misceffect2(map_id2bl(st->oid),type); - else{ - struct map_session_data *sd=script_rid2sd(st); - if(sd) - clif_misceffect2(&sd->bl,type); - } - return 0; -} -/*========================================== - * サウンドエフェクト - *------------------------------------------ - */ -int buildin_soundeffect(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - char *name; - int type=0; - - - name=conv_str(st,& (st->stack->stack_data[st->start+2])); - type=conv_num(st,& (st->stack->stack_data[st->start+3])); - if(sd){ - if(st->oid) - clif_soundeffect(sd,map_id2bl(st->oid),name,type); - else{ - clif_soundeffect(sd,&sd->bl,name,type); - } - } - return 0; -} - -int buildin_soundeffectall(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - char *name; - int type=0; - - name=conv_str(st,& (st->stack->stack_data[st->start+2])); - type=conv_num(st,& (st->stack->stack_data[st->start+3])); - if(sd) - { - if(st->oid) - clif_soundeffectall(map_id2bl(st->oid),name,type); - else - clif_soundeffectall(&sd->bl,name,type); - } - return 0; -} -/*========================================== - * pet status recovery [Valaris] - *------------------------------------------ - */ -int buildin_petrecovery(struct script_state *st) -{ - struct pet_data *pd; - - struct map_session_data *sd=script_rid2sd(st); - - if(sd==NULL || sd->pd==NULL) - return 0; - - pd=sd->pd; - - if(pd==NULL) - return 0; - - pd->skilltype=conv_num(st,& (st->stack->stack_data[st->start+2])); - pd->skilltimer=conv_num(st,& (st->stack->stack_data[st->start+3])); - - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_recovery_timer,sd->bl.id,0); - - return 0; -} - -/*========================================== - * pet healing [Valaris] - *------------------------------------------ - */ -int buildin_petheal(struct script_state *st) - -{ - struct pet_data *pd; - struct map_session_data *sd=script_rid2sd(st); - - if(sd==NULL || sd->pd==NULL) - return 0; - - pd=sd->pd; - - if(pd==NULL) - return 0; - - pd->skilltype=conv_num(st,& (st->stack->stack_data[st->start+2])); - pd->skillval=conv_num(st,& (st->stack->stack_data[st->start+3])); - pd->skilltimer=conv_num(st,& (st->stack->stack_data[st->start+4])); - - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_heal_timer,sd->bl.id,0); - - return 0; -} - -/*========================================== - * pet magnificat [Valaris] - *------------------------------------------ - */ -int buildin_petmag(struct script_state *st) -{ - struct pet_data *pd; - struct map_session_data *sd=script_rid2sd(st); - - if(sd==NULL || sd->pd==NULL) - return 0; - - pd=sd->pd; - - if(pd==NULL) - return 0; - - pd->skilltype=conv_num(st,& (st->stack->stack_data[st->start+2])); - pd->skillduration=conv_num(st,& (st->stack->stack_data[st->start+3])); - pd->skillval=conv_num(st,& (st->stack->stack_data[st->start+4])); - pd->skilltimer=conv_num(st,& (st->stack->stack_data[st->start+5])); - - pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_mag_timer,sd->bl.id,0); - - return 0; -} - -/*========================================== - * pet attack skills [Valaris] - *------------------------------------------ - */ -int buildin_petskillattack(struct script_state *st) -{ - struct pet_data *pd; - struct map_session_data *sd=script_rid2sd(st); - - if(sd==NULL || sd->pd==NULL) - return 0; - - pd=sd->pd; - - if(pd==NULL) - return 0; - - pd->skilltype=conv_num(st,& (st->stack->stack_data[st->start+2])); - pd->skillval=conv_num(st,& (st->stack->stack_data[st->start+3])); - pd->skillduration=conv_num(st,& (st->stack->stack_data[st->start+4])); - pd->skilltimer=conv_num(st,& (st->stack->stack_data[st->start+5])); - - pd->skillbonustimer=add_timer(gettick()+100,pet_skillattack_timer,sd->bl.id,0); - - return 0; -} - -/*========================================== - * Scripted skill effects [Celest] - *------------------------------------------ - */ -int buildin_skilleffect(struct script_state *st) -{ - struct map_session_data *sd; - - int skillid=conv_num(st,& (st->stack->stack_data[st->start+2])); - int skilllv=conv_num(st,& (st->stack->stack_data[st->start+3])); - sd=script_rid2sd(st); - - clif_skill_nodamage(&sd->bl,&sd->bl,skillid,skilllv,1); - - return 0; -} - -/*========================================== - * NPC skill effects [Valaris] - *------------------------------------------ - */ -int buildin_npcskilleffect(struct script_state *st) -{ - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - - int skillid=conv_num(st,& (st->stack->stack_data[st->start+2])); - int skilllv=conv_num(st,& (st->stack->stack_data[st->start+3])); - int x=conv_num(st,& (st->stack->stack_data[st->start+4])); - int y=conv_num(st,& (st->stack->stack_data[st->start+5])); - - clif_skill_poseffect(&nd->bl,skillid,skilllv,x,y,gettick()); - - return 0; -} - -/*========================================== - * Special effects [Valaris] - *------------------------------------------ - */ -int buildin_specialeffect(struct script_state *st) -{ - struct block_list *bl=map_id2bl(st->oid); - - if(bl==NULL) - return 0; - - clif_specialeffect(bl,conv_num(st,& (st->stack->stack_data[st->start+2])), 0); - - return 0; -} - -int buildin_specialeffect2(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - - if(sd==NULL) - return 0; - - clif_specialeffect(&sd->bl,conv_num(st,& (st->stack->stack_data[st->start+2])), 0); - - return 0; -} - -/*========================================== - * Nude [Valaris] - *------------------------------------------ - */ - -int buildin_nude(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int i; - - if(sd==NULL) - return 0; - - for(i=0;i<11;i++) - if(sd->equip_index[i] >= 0) - pc_unequipitem(sd,sd->equip_index[i],2); - - return 0; -} - -/*========================================== - * gmcommand [MouseJstr] - * - * suggested on the forums... - *------------------------------------------ - */ - -int buildin_gmcommand(struct script_state *st) -{ - struct map_session_data *sd; - char *cmd; - - sd = script_rid2sd(st); - cmd = conv_str(st,& (st->stack->stack_data[st->start+2])); - - is_atcommand(sd->fd, sd, cmd, 99); - - return 0; -} - -/*========================================== - * Displays a message for the player only (like system messages like "you got an apple" ) - *------------------------------------------ - */ -int buildin_dispbottom(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - char *message; - message=conv_str(st,& (st->stack->stack_data[st->start+2])); - if(sd) - clif_disp_onlyself(sd,message,strlen(message)); - return 0; -} - -/*========================================== - * All The Players Full Recovery - (HP/SP full restore and resurrect if need) - *------------------------------------------ - */ -int buildin_recovery(struct script_state *st) -{ - int i = 0; - for (i = 0; i < fd_max; i++) { - if (session[i]){ - struct map_session_data *sd = (struct map_session_data *) session[i]->session_data; - if (sd && sd->state.auth) { - sd->status.hp = sd->status.max_hp; - sd->status.sp = sd->status.max_sp; - clif_updatestatus(sd, SP_HP); - clif_updatestatus(sd, SP_SP); - if(pc_isdead(sd)){ - pc_setstand(sd); - clif_resurrection(&sd->bl, 1); - } - clif_displaymessage(sd->fd,"You have been recovered!"); - } - } - } - return 0; -} -/*========================================== - * Get your pet info: getpetinfo(n) - * n -> 0:pet_id 1:pet_class 2:pet_name - 3:friendly 4:hungry - *------------------------------------------ - */ -int buildin_getpetinfo(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int type=conv_num(st,& (st->stack->stack_data[st->start+2])); - - if(sd && sd->status.pet_id){ - switch(type){ - case 0: - push_val(st->stack,C_INT,sd->status.pet_id); - break; - case 1: - if(sd->pet.class_) - push_val(st->stack,C_INT,sd->pet.class_); - else - push_val(st->stack,C_INT,0); - break; - case 2: - if(sd->pet.name) - push_str(st->stack,C_STR,(unsigned char *) sd->pet.name); - else - push_val(st->stack,C_INT,0); - break; - case 3: - //if(sd->pet.intimate) - push_val(st->stack,C_INT,sd->pet.intimate); - break; - case 4: - //if(sd->pet.hungry) - push_val(st->stack,C_INT,sd->pet.hungry); - break; - default: - push_val(st->stack,C_INT,0); - break; - } - }else{ - push_val(st->stack,C_INT,0); - } - return 0; -} -/*========================================== - * Shows wether your inventory(and equips) contain - selected card or not. - checkequipedcard(4001); - *------------------------------------------ - */ -int buildin_checkequipedcard(struct script_state *st) -{ - struct map_session_data *sd=script_rid2sd(st); - int n,i,c=0; - c=conv_num(st,& (st->stack->stack_data[st->start+2])); - - if(sd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount){ - for(n=0;n<4;n++){ - if(sd->status.inventory[i].card[n]==c){ - push_val(st->stack,C_INT,1); - return 0; - } - } - } - } - } - push_val(st->stack,C_INT,0); - return 0; -} - -int buildin_jump_zero(struct script_state *st) { - int sel; - sel=conv_num(st,& (st->stack->stack_data[st->start+2])); - if(!sel) { - int pos; - if( st->stack->stack_data[st->start+3].type!=C_POS ){ - printf("script: jump_zero: not label !\n"); - st->state=END; - return 0; - } - - pos=conv_num(st,& (st->stack->stack_data[st->start+3])); - st->pos=pos; - st->state=GOTO; - // printf("script: jump_zero: jumpto : %d\n",pos); - } else { - // printf("script: jump_zero: fail\n"); - } - return 0; -} - -int buildin_select(struct script_state *st) -{ - char *buf; - int len,i; - struct map_session_data *sd; - - sd=script_rid2sd(st); - - if(sd->state.menu_or_input==0){ - st->state=RERUNLINE; - sd->state.menu_or_input=1; - for(i=st->start+2,len=16;i<st->end;i++){ - conv_str(st,& (st->stack->stack_data[i])); - len+=strlen(st->stack->stack_data[i].u.str)+1; - } - buf=(char *)aCalloc(len+1,sizeof(char)); - buf[0]=0; - for(i=st->start+2,len=0;i<st->end;i++){ - strcat(buf,st->stack->stack_data[i].u.str); - strcat(buf,":"); - } - clif_scriptmenu(script_rid2sd(st),st->oid,buf); - aFree(buf); - } else if(sd->npc_menu==0xff){ // cansel - sd->state.menu_or_input=0; - st->state=END; - } else { - pc_setreg(sd,add_str((unsigned char *) "l15"),sd->npc_menu); - pc_setreg(sd,add_str((unsigned char *) "@menu"),sd->npc_menu); - sd->state.menu_or_input=0; - push_val(st->stack,C_INT,sd->npc_menu); - } - return 0; -} - -/*========================================== - * GetMapMobs - returns mob counts on a set map: - e.g. GetMapMobs("prontera.gat") - use "this" - for player's map - *------------------------------------------ - */ -int buildin_getmapmobs(struct script_state *st) -{ - char *str=NULL; - int m=-1,bx,by,i; - int count=0,c; - struct block_list *bl; - - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - - if(strcmp(str,"this")==0){ - struct map_session_data *sd=script_rid2sd(st); - if(sd) - m=sd->bl.m; - else{ - push_val(st->stack,C_INT,-1); - return 0; - } - }else - m=map_mapname2mapid(str); - - if(m < 0){ - push_val(st->stack,C_INT,-1); - return 0; - } - - for(by=0;by<=(map[m].ys-1)/BLOCK_SIZE;by++){ - for(bx=0;bx<=(map[m].xs-1)/BLOCK_SIZE;bx++){ - bl = map[m].block_mob[bx+by*map[m].bxs]; - c = map[m].block_mob_count[bx+by*map[m].bxs]; - for(i=0;i<c && bl;i++,bl=bl->next){ - if(bl->x>=0 && bl->x<=map[m].xs-1 && bl->y>=0 && bl->y<=map[m].ys-1) - count++; - } - } - } - push_val(st->stack,C_INT,count); - return 0; -} - -/*========================================== - * movenpc [MouseJstr] - *------------------------------------------ - */ - -int buildin_movenpc(struct script_state *st) -{ - struct map_session_data *sd; - char *map,*npc; - int x,y; - - sd = script_rid2sd(st); - - map = conv_str(st,& (st->stack->stack_data[st->start+2])); - x = conv_num(st,& (st->stack->stack_data[st->start+3])); - y = conv_num(st,& (st->stack->stack_data[st->start+4])); - npc = conv_str(st,& (st->stack->stack_data[st->start+5])); - - return 0; -} - -/*========================================== - * message [MouseJstr] - *------------------------------------------ - */ - -int buildin_message(struct script_state *st) -{ - struct map_session_data *sd; - char *msg,*player; - struct map_session_data *pl_sd = NULL; - - sd = script_rid2sd(st); - - player = conv_str(st,& (st->stack->stack_data[st->start+2])); - msg = conv_str(st,& (st->stack->stack_data[st->start+3])); - - if((pl_sd=map_nick2sd((char *) player)) == NULL) - return 1; - clif_displaymessage(pl_sd->fd, msg); - - return 0; -} - -/*========================================== - * npctalk (sends message to surrounding - * area) [Valaris] - *------------------------------------------ - */ - -int buildin_npctalk(struct script_state *st) -{ - char *str; - char message[255]; - - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - str=conv_str(st,& (st->stack->stack_data[st->start+2])); - - if(nd) { - memcpy(message,nd->name,24); - strcat(message," : "); - strcat(message,str); - clif_message(&(nd->bl), message); - } - - return 0; -} - -/*========================================== - * hasitems (checks to see if player has any - * items on them, if so will return a 1) - * [Valaris] - *------------------------------------------ - */ - -int buildin_hasitems(struct script_state *st) -{ - int i; - struct map_session_data *sd; - - sd=script_rid2sd(st); - - for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].amount) { - push_val(st->stack,C_INT,1); - return 0; - } - } - - push_val(st->stack,C_INT,0); - - return 0; -} -// change npc walkspeed [Valaris] -int buildin_npcspeed(struct script_state *st) -{ - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - int x=0; - - x=conv_num(st,& (st->stack->stack_data[st->start+2])); - - if(nd) { - nd->speed=x; - } - - return 0; -} -// make an npc walk to a position [Valaris] -int buildin_npcwalkto(struct script_state *st) -{ - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - int x=0,y=0; - - x=conv_num(st,& (st->stack->stack_data[st->start+2])); - y=conv_num(st,& (st->stack->stack_data[st->start+3])); - - if(nd) { - npc_walktoxy(nd,x,y,0); - } - - return 0; -} -// stop an npc's movement [Valaris] -int buildin_npcstop(struct script_state *st) -{ - struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid); - - if(nd) { - if(nd->state.state==MS_WALK) - npc_stop_walking(nd,1); - } - - return 0; -} - - -/*========================================== - * getlook char info. getlook(arg) - *------------------------------------------ - */ -int buildin_getlook(struct script_state *st){ - int type,val; - struct map_session_data *sd; - sd=script_rid2sd(st); - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - val=-1; - switch(type){ - case LOOK_HAIR: //1 - val=sd->status.hair; - break; - case LOOK_WEAPON: //2 - val=sd->status.weapon; - break; - case LOOK_HEAD_BOTTOM: //3 - val=sd->status.head_bottom; - break; - case LOOK_HEAD_TOP: //4 - val=sd->status.head_top; - break; - case LOOK_HEAD_MID: //5 - val=sd->status.head_mid; - break; - case LOOK_HAIR_COLOR: //6 - val=sd->status.hair_color; - break; - case LOOK_CLOTHES_COLOR: //7 - val=sd->status.clothes_color; - break; - case LOOK_SHIELD: //8 - val=sd->status.shield; - break; - case LOOK_SHOES: //9 - break; - } - - push_val(st->stack,C_INT,val); - return 0; -} - -/*========================================== - * get char save point. argument: 0- map name, 1- x, 2- y - *------------------------------------------ -*/ -int buildin_getsavepoint(struct script_state *st) -{ - int x,y,type; - char *mapname; - struct map_session_data *sd; - - sd=script_rid2sd(st); - - type=conv_num(st,& (st->stack->stack_data[st->start+2])); - mapname=(char *) aCallocA(24, 1); - - x=sd->status.save_point.x; - y=sd->status.save_point.y; - strncpy(mapname,sd->status.save_point.map,24); - switch(type){ - case 0: - push_str(st->stack,C_STR,(unsigned char *) mapname); - break; - case 1: - push_val(st->stack,C_INT,x); - break; - case 2: - push_val(st->stack,C_INT,y); - break; - } - return 0; -} - -/*========================================== - * Get position for char/npc/pet/mob objects. Added by Lorky - * - * int getMapXY(MapName$,MaxX,MapY,type,[CharName$]); - * where type: - * MapName$ - String variable for output map name - * MapX - Integer variable for output coord X - * MapY - Integer variable for output coord Y - * type - type of object - * 0 - Character coord - * 1 - NPC coord - * 2 - Pet coord - * 3 - Mob coord (not released) - * CharName$ - Name object. If miss or "this" the current object - * - * Return: - * 0 - success - * -1 - some error, MapName$,MapX,MapY contains unknown value. - *------------------------------------------ -*/ -int buildin_getmapxy(struct script_state *st){ - struct map_session_data *sd=NULL; - struct npc_data *nd; - struct pet_data *pd; - - int num; - char *name; - char prefix; - - int x,y,type; - char *mapname; - - if( st->stack->stack_data[st->start+2].type!=C_NAME ){ - printf("script: buildin_getmapxy: not mapname variable\n"); - push_val(st->stack,C_INT,-1); - return 0; - } - if( st->stack->stack_data[st->start+3].type!=C_NAME ){ - printf("script: buildin_getmapxy: not mapx variable\n"); - push_val(st->stack,C_INT,-1); - return 0; - } - if( st->stack->stack_data[st->start+4].type!=C_NAME ){ - printf("script: buildin_getmapxy: not mapy variable\n"); - push_val(st->stack,C_INT,-1); - return 0; - } - -//??????????? >>> Possible needly check function parameters on C_STR,C_INT,C_INT <<< ???????????// - type=conv_num(st,& (st->stack->stack_data[st->start+5])); - mapname=(char *) aCallocA(24, 1); - - switch (type){ - case 0: //Get Character Position - if( st->end>st->start+6 ) - sd=map_nick2sd(conv_str(st,& (st->stack->stack_data[st->start+6]))); - else - sd=script_rid2sd(st); - - if ( sd==NULL ) { //wrong char name or char offline - push_val(st->stack,C_INT,-1); - return 0; - } - - - x=sd->bl.x; - y=sd->bl.y; - strncpy(mapname,sd->mapname,24); - printf(">>>>%s %d %d\n",mapname,x,y); - break; - case 1: //Get NPC Position - if( st->end > st->start+6 ) - nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+6]))); - else - nd=(struct npc_data *)map_id2bl(st->oid); - - if ( nd==NULL ) { //wrong npc name or char offline - push_val(st->stack,C_INT,-1); - return 0; - } - - x=nd->bl.x; - y=nd->bl.y; - strncpy(mapname,map[nd->bl.m].name,24); - printf(">>>>%s %d %d\n",mapname,x,y); - break; - case 2: //Get Pet Position - if( st->end>st->start+6 ) - sd=map_nick2sd(conv_str(st,& (st->stack->stack_data[st->start+6]))); - else - sd=script_rid2sd(st); - - if ( sd==NULL ) { //wrong char name or char offline - push_val(st->stack,C_INT,-1); - return 0; - } - - pd=sd->pd; - - if(pd==NULL){ //ped data not found - push_val(st->stack,C_INT,-1); - return 0; - } - x=pd->bl.x; - y=pd->bl.y; - strncpy(mapname,map[pd->bl.m].name,24); - - printf(">>>>%s %d %d\n",mapname,x,y); - break; - - case 3: //Get Mob Position - push_val(st->stack,C_INT,-1); - return 0; - default: //Wrong type parameter - push_val(st->stack,C_INT,-1); - return 0; - } - - //Set MapName$ - num=st->stack->stack_data[st->start+2].u.num; - name=(char *)(str_buf+str_data[num&0x00ffffff].str); - prefix=*name; - - if( prefix!='$' ) - sd=script_rid2sd(st); - else - sd=NULL; - - set_reg(sd,num,name,(void*)mapname); - - //Set MapX - num=st->stack->stack_data[st->start+3].u.num; - name=(char *)(str_buf+str_data[num&0x00ffffff].str); - prefix=*name; - - if( prefix!='$' ) - sd=script_rid2sd(st); - else - sd=NULL; - set_reg(sd,num,name,(void*)x); - - - //Set MapY - num=st->stack->stack_data[st->start+4].u.num; - name=(char *)(str_buf+str_data[num&0x00ffffff].str); - prefix=*name; - - if( prefix!='$' ) - sd=script_rid2sd(st); - else - sd=NULL; - - set_reg(sd,num,name,(void*)y); - - //Return Success value - push_val(st->stack,C_INT,0); - return 0; -} - -/*===================================================== - * Allows players to use a skill - by Qamera - *----------------------------------------------------- - */ -int buildin_skilluseid (struct script_state *st) -{ - int skid,sklv; - struct map_session_data *sd; - - skid=conv_num(st,& (st->stack->stack_data[st->start+2])); - sklv=conv_num(st,& (st->stack->stack_data[st->start+3])); - sd=script_rid2sd(st); - skill_use_id(sd,sd->status.account_id,skid,sklv); - - return 0; -} - -/*===================================================== - * Allows players to use a skill on a position [Celest] - *----------------------------------------------------- - */ -int buildin_skillusepos(struct script_state *st) -{ - int skid,sklv,x,y; - struct map_session_data *sd; - - skid=conv_num(st,& (st->stack->stack_data[st->start+2])); - sklv=conv_num(st,& (st->stack->stack_data[st->start+3])); - x=conv_num(st,& (st->stack->stack_data[st->start+4])); - y=conv_num(st,& (st->stack->stack_data[st->start+5])); - - sd=script_rid2sd(st); - skill_use_pos(sd,x,y,skid,sklv); - - return 0; -} - -/*========================================== - * Allows player to write NPC logs (i.e. Bank NPC, etc) [Lupus] - *------------------------------------------ - */ -int buildin_logmes(struct script_state *st) -{ - if (log_config.npc <= 0 ) return 0; - conv_str(st,& (st->stack->stack_data[st->start+2])); - log_npc(script_rid2sd(st),st->stack->stack_data[st->start+2].u.str); - return 0; -} - -int buildin_summon(struct script_state *st) -{ - int _class, id; - char *str,*event=""; - struct map_session_data *sd; - struct mob_data *md; - - sd=script_rid2sd(st); - if (sd) { - int tick = gettick(); - str =conv_str(st,& (st->stack->stack_data[st->start+2])); - _class=conv_num(st,& (st->stack->stack_data[st->start+3])); - if( st->end>st->start+4 ) - event=conv_str(st,& (st->stack->stack_data[st->start+4])); - - id=mob_once_spawn(sd, "this", 0, 0, str,_class,1,event); - if((md=(struct mob_data *)map_id2bl(id))){ - md->master_id=sd->bl.id; - md->state.special_mob_ai=1; - md->mode=mob_db[md->class_].mode|0x04; - md->deletetimer=add_timer(tick+60000,mob_timer_delete,id,0); - clif_misceffect2(&md->bl,344); - } - clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick); - } - - return 0; -} - -int buildin_isnight(struct script_state *st) -{ - push_val(st->stack,C_INT, (night_flag == 1)); - return 0; -} - -int buildin_isday(struct script_state *st) -{ - push_val(st->stack,C_INT, (night_flag == 0)); - return 0; -} - -/*================================================ - * Check whether another item/card has been - * equipped - used for 2/15's cards patch [celest] - *------------------------------------------------ - */ -int buildin_isequipped(struct script_state *st) -{ - struct map_session_data *sd; - int i, j, k, id = 1; - int ret = -1; - - sd = script_rid2sd(st); - - for (i=0; id!=0; i++) { - int flag = 0; - - FETCH (i+2, id) else id = 0; - if (id <= 0) - continue; - - for (j=0; j<10; j++) { - int index, type; - index = sd->equip_index[j]; - if(index < 0) continue; - if(j == 9 && sd->equip_index[8] == index) continue; - if(j == 5 && sd->equip_index[4] == index) continue; - if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue; - type = itemdb_type(id); - - if(sd->inventory_data[index]) { - if (type == 4 || type == 5) { - if (sd->inventory_data[index]->nameid == id) - flag = 1; - } else if (type == 6) { - for(k=0; k<sd->inventory_data[index]->slot; k++) { - if (sd->status.inventory[index].card[0]!=0x00ff && - sd->status.inventory[index].card[0]!=0x00fe && - sd->status.inventory[index].card[0]!=(short)0xff00 && - sd->status.inventory[index].card[k] == id) { - flag = 1; - break; - } - } - } - if (flag) break; - } - } - if (ret == -1) - ret = flag; - else - ret &= flag; - if (!ret) break; - } - - push_val(st->stack,C_INT,ret); - return 0; -} - -/*================================================ - * Check how many items/cards in the list are - * equipped - used for 2/15's cards patch [celest] - *------------------------------------------------ - */ -int buildin_isequippedcnt(struct script_state *st) -{ - struct map_session_data *sd; - int i, j, k, id = 1; - int ret = 0; - - sd = script_rid2sd(st); - - for (i=0; id!=0; i++) { - FETCH (i+2, id) else id = 0; - if (id <= 0) - continue; - - for (j=0; j<10; j++) { - int index, type; - index = sd->equip_index[j]; - if(index < 0) continue; - if(j == 9 && sd->equip_index[8] == index) continue; - if(j == 5 && sd->equip_index[4] == index) continue; - if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue; - type = itemdb_type(id); - - if(sd->inventory_data[index]) { - if (type == 4 || type == 5) { - if (sd->inventory_data[index]->nameid == id) - ret++; //[Lupus] - } else if (type == 6) { - for(k=0; k<sd->inventory_data[index]->slot; k++) { - if (sd->status.inventory[index].card[0]!=0x00ff && - sd->status.inventory[index].card[0]!=0x00fe && - sd->status.inventory[index].card[0]!=(short)0xff00 && - sd->status.inventory[index].card[k] == id) { - ret++; //[Lupus] - } - } - } - } - } - } - - push_val(st->stack,C_INT,ret); - return 0; -} - -/*================================================ - * Check how many given inserted cards in the CURRENT - * weapon - used for 2/15's cards patch [Lupus] - *------------------------------------------------ - */ -int buildin_cardscnt(struct script_state *st) -{ - struct map_session_data *sd; - int i, k, id = 1; - int ret = 0; - int index, type; - - sd = script_rid2sd(st); - - for (i=0; id!=0; i++) { - FETCH (i+2, id) else id = 0; - if (id <= 0) - continue; - - index = current_equip_item_index; //we get CURRENT WEAPON inventory index from status.c [Lupus] - if(index < 0) continue; - - type = itemdb_type(id); - - if(sd->inventory_data[index]) { - if (type == 4 || type == 5) { - if (sd->inventory_data[index]->nameid == id) - ret++; - } else if (type == 6) { - for(k=0; k<sd->inventory_data[index]->slot; k++) { - if (sd->status.inventory[index].card[0]!=0x00ff && - sd->status.inventory[index].card[0]!=0x00fe && - sd->status.inventory[index].card[0]!=(short)0xff00 && - sd->status.inventory[index].card[k] == id) { - ret++; - } - } - } - } - } - push_val(st->stack,C_INT,ret); -// push_val(st->stack,C_INT,current_equip_item_index); - return 0; -} - -/*======================================================= - * Returns the refined number of the current item, or an - * item with inventory index specified - *------------------------------------------------------- - */ -int buildin_getrefine(struct script_state *st) -{ - struct map_session_data *sd; - if ((sd = script_rid2sd(st))!= NULL) - push_val(st->stack, C_INT, sd->status.inventory[current_equip_item_index].refine); - return 0; -} - -// -// 実行部main -// -/*========================================== - * コマンドの読み取り - *------------------------------------------ - */ -static int unget_com_data=-1; -int get_com(unsigned char *script,int *pos) -{ - int i,j; - if(unget_com_data>=0){ - i=unget_com_data; - unget_com_data=-1; - return i; - } - if(script[*pos]>=0x80){ - return C_INT; - } - i=0; j=0; - while(script[*pos]>=0x40){ - i=script[(*pos)++]<<j; - j+=6; - } - return i+(script[(*pos)++]<<j); -} - -/*========================================== - * コマンドのプッシュバック - *------------------------------------------ - */ -void unget_com(int c) -{ - if(unget_com_data!=-1){ - if(battle_config.error_log) - printf("unget_com can back only 1 data\n"); - } - unget_com_data=c; -} - -/*========================================== - * 数値の所得 - *------------------------------------------ - */ -int get_num(unsigned char *script,int *pos) -{ - int i,j; - i=0; j=0; - while(script[*pos]>=0xc0){ - i+=(script[(*pos)++]&0x7f)<<j; - j+=6; - } - return i+((script[(*pos)++]&0x7f)<<j); -} - -/*========================================== - * スタックから値を取り出す - *------------------------------------------ - */ -int pop_val(struct script_state* st) -{ - if(st->stack->sp<=0) - return 0; - st->stack->sp--; - get_val(st,&(st->stack->stack_data[st->stack->sp])); - if(st->stack->stack_data[st->stack->sp].type==C_INT) - return st->stack->stack_data[st->stack->sp].u.num; - return 0; -} - -#define isstr(c) ((c).type==C_STR || (c).type==C_CONSTSTR) - -/*========================================== - * 加算演算子 - *------------------------------------------ - */ -void op_add(struct script_state* st) -{ - st->stack->sp--; - get_val(st,&(st->stack->stack_data[st->stack->sp])); - get_val(st,&(st->stack->stack_data[st->stack->sp-1])); - - if(isstr(st->stack->stack_data[st->stack->sp]) || isstr(st->stack->stack_data[st->stack->sp-1])){ - conv_str(st,&(st->stack->stack_data[st->stack->sp])); - conv_str(st,&(st->stack->stack_data[st->stack->sp-1])); - } - if(st->stack->stack_data[st->stack->sp].type==C_INT){ // ii - st->stack->stack_data[st->stack->sp-1].u.num += st->stack->stack_data[st->stack->sp].u.num; - } else { // ssの予定 - char *buf; - buf=(char *)aCallocA(strlen(st->stack->stack_data[st->stack->sp-1].u.str)+ - strlen(st->stack->stack_data[st->stack->sp].u.str)+1,sizeof(char)); - strcpy(buf,st->stack->stack_data[st->stack->sp-1].u.str); - strcat(buf,st->stack->stack_data[st->stack->sp].u.str); - if(st->stack->stack_data[st->stack->sp-1].type==C_STR) - aFree(st->stack->stack_data[st->stack->sp-1].u.str); - if(st->stack->stack_data[st->stack->sp].type==C_STR) - aFree(st->stack->stack_data[st->stack->sp].u.str); - st->stack->stack_data[st->stack->sp-1].type=C_STR; - st->stack->stack_data[st->stack->sp-1].u.str=buf; - } -} - -/*========================================== - * 二項演算子(文字列) - *------------------------------------------ - */ -void op_2str(struct script_state *st,int op,int sp1,int sp2) -{ - char *s1=st->stack->stack_data[sp1].u.str, - *s2=st->stack->stack_data[sp2].u.str; - int a=0; - - switch(op){ - case C_EQ: - a= (strcmp(s1,s2)==0); - break; - case C_NE: - a= (strcmp(s1,s2)!=0); - break; - case C_GT: - a= (strcmp(s1,s2)> 0); - break; - case C_GE: - a= (strcmp(s1,s2)>=0); - break; - case C_LT: - a= (strcmp(s1,s2)< 0); - break; - case C_LE: - a= (strcmp(s1,s2)<=0); - break; - default: - printf("illegal string operater\n"); - break; - } - - push_val(st->stack,C_INT,a); - - if(st->stack->stack_data[sp1].type==C_STR) aFree(s1); - if(st->stack->stack_data[sp2].type==C_STR) aFree(s2); -} -/*========================================== - * 二項演算子(数値) - *------------------------------------------ - */ -void op_2num(struct script_state *st,int op,int i1,int i2) -{ - switch(op){ - case C_SUB: - i1-=i2; - break; - case C_MUL: - { - #ifndef _MSC_VER - long long res = i1 * i2; - #else - __int64 res = i1 * i2; - #endif - if (res > 2147483647 ) - i1 = 2147483647; - else - i1*=i2; - } - break; - case C_DIV: - i1/=i2; - break; - case C_MOD: - i1%=i2; - break; - case C_AND: - i1&=i2; - break; - case C_OR: - i1|=i2; - break; - case C_XOR: - i1^=i2; - break; - case C_LAND: - i1=i1&&i2; - break; - case C_LOR: - i1=i1||i2; - break; - case C_EQ: - i1=i1==i2; - break; - case C_NE: - i1=i1!=i2; - break; - case C_GT: - i1=i1>i2; - break; - case C_GE: - i1=i1>=i2; - break; - case C_LT: - i1=i1<i2; - break; - case C_LE: - i1=i1<=i2; - break; - case C_R_SHIFT: - i1=i1>>i2; - break; - case C_L_SHIFT: - i1=i1<<i2; - break; - } - push_val(st->stack,C_INT,i1); -} -/*========================================== - * 二項演算子 - *------------------------------------------ - */ -void op_2(struct script_state *st,int op) -{ - int i1,i2; - char *s1=NULL,*s2=NULL; - - i2=pop_val(st); - if( isstr(st->stack->stack_data[st->stack->sp]) ) - s2=st->stack->stack_data[st->stack->sp].u.str; - - i1=pop_val(st); - if( isstr(st->stack->stack_data[st->stack->sp]) ) - s1=st->stack->stack_data[st->stack->sp].u.str; - - if( s1!=NULL && s2!=NULL ){ - // ss => op_2str - op_2str(st,op,st->stack->sp,st->stack->sp+1); - }else if( s1==NULL && s2==NULL ){ - // ii => op_2num - op_2num(st,op,i1,i2); - }else{ - // si,is => error - printf("script: op_2: int&str, str&int not allow."); - push_val(st->stack,C_INT,0); - } -} - -/*========================================== - * 単項演算子 - *------------------------------------------ - */ -void op_1num(struct script_state *st,int op) -{ - int i1; - i1=pop_val(st); - switch(op){ - case C_NEG: - i1=-i1; - break; - case C_NOT: - i1=~i1; - break; - case C_LNOT: - i1=!i1; - break; - } - push_val(st->stack,C_INT,i1); -} - - -/*========================================== - * 関数の実行 - *------------------------------------------ - */ -int run_func(struct script_state *st) -{ - int i,start_sp,end_sp,func; - - end_sp=st->stack->sp; - for(i=end_sp-1;i>=0 && st->stack->stack_data[i].type!=C_ARG;i--); - if(i==0){ - if(battle_config.error_log) - printf("function not found\n"); -// st->stack->sp=0; - st->state=END; - return 0; - } - start_sp=i-1; - st->start=i-1; - st->end=end_sp; - - func=st->stack->stack_data[st->start].u.num; - if( st->stack->stack_data[st->start].type!=C_NAME || str_data[func].type!=C_FUNC ){ - printf("run_func: not function and command! \n"); -// st->stack->sp=0; - st->state=END; - return 0; - } -#ifdef DEBUG_RUN - if(battle_config.etc_log) { - printf("run_func : %s? (%d(%d))\n",str_buf+str_data[func].str,func,str_data[func].type); - printf("stack dump :"); - for(i=0;i<end_sp;i++){ - switch(st->stack->stack_data[i].type){ - case C_INT: - printf(" int(%d)",st->stack->stack_data[i].u.num); - break; - case C_NAME: - printf(" name(%s)",str_buf+str_data[st->stack->stack_data[i].u.num].str); - break; - case C_ARG: - printf(" arg"); - break; - case C_POS: - printf(" pos(%d)",st->stack->stack_data[i].u.num); - break; - default: - printf(" %d,%d",st->stack->stack_data[i].type,st->stack->stack_data[i].u.num); - } - } - printf("\n"); - } -#endif - if(str_data[func].func){ - str_data[func].func(st); - } else { - if(battle_config.error_log) - printf("run_func : %s? (%d(%d))\n",str_buf+str_data[func].str,func,str_data[func].type); - push_val(st->stack,C_INT,0); - } - - pop_stack(st->stack,start_sp,end_sp); - - if(st->state==RETFUNC){ - // ユーザー定義関数からの復帰 - int olddefsp=st->defsp; - int i; - - pop_stack(st->stack,st->defsp,start_sp); // 復帰に邪魔なスタック削除 - if(st->defsp<4 || st->stack->stack_data[st->defsp-1].type!=C_RETINFO){ - printf("script:run_func(return) return without callfunc or callsub!\n"); - st->state=END; - return 0; - } - i = conv_num(st,& (st->stack->stack_data[st->defsp-4])); // 引数の数所得 - st->pos=conv_num(st,& (st->stack->stack_data[st->defsp-1])); // スクリプト位置の復元 - st->script=(char*)conv_num(st,& (st->stack->stack_data[st->defsp-2])); // スクリプトを復元 - st->defsp=conv_num(st,& (st->stack->stack_data[st->defsp-3])); // 基準スタックポインタを復元 - - pop_stack(st->stack,olddefsp-4-i,olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除 - - st->state=GOTO; - } - - return 0; -} - -/*========================================== - * スクリプトの実行メイン部分 - *------------------------------------------ - */ -int run_script_main(char *script,int pos,int rid,int oid,struct script_state *st,char *rootscript) -{ - int c,rerun_pos; - int cmdcount=script_config.check_cmdcount; - int gotocount=script_config.check_gotocount; - struct script_stack *stack=st->stack; - - st->defsp=stack->sp; - st->script=script; - - rerun_pos=st->pos; - for(st->state=0;st->state==0;){ - switch(c= get_com((unsigned char *) script,&st->pos)){ - case C_EOL: - if(stack->sp!=st->defsp){ - if(battle_config.error_log) - printf("stack.sp(%d) != default(%d)\n",stack->sp,st->defsp); - stack->sp=st->defsp; - } - rerun_pos=st->pos; - break; - case C_INT: - push_val(stack,C_INT,get_num((unsigned char *) script,&st->pos)); - break; - case C_POS: - case C_NAME: - push_val(stack,c,(*(int*)(script+st->pos))&0xffffff); - st->pos+=3; - break; - case C_ARG: - push_val(stack,c,0); - break; - case C_STR: - push_str(stack,C_CONSTSTR,(unsigned char *) (script+st->pos)); - while(script[st->pos++]); - break; - case C_FUNC: - run_func(st); - if(st->state==GOTO){ - rerun_pos=st->pos; - script=st->script; - st->state=0; - if( gotocount>0 && (--gotocount)<=0 ){ - printf("run_script: infinity loop !\n"); - st->state=END; - } - } - break; - - case C_ADD: - op_add(st); - break; - - case C_SUB: - case C_MUL: - case C_DIV: - case C_MOD: - case C_EQ: - case C_NE: - case C_GT: - case C_GE: - case C_LT: - case C_LE: - case C_AND: - case C_OR: - case C_XOR: - case C_LAND: - case C_LOR: - case C_R_SHIFT: - case C_L_SHIFT: - op_2(st,c); - break; - - case C_NEG: - case C_NOT: - case C_LNOT: - op_1num(st,c); - break; - - case C_NOP: - st->state=END; - break; - - default: - if(battle_config.error_log) - printf("unknown command : %d @ %d\n",c,pos); - st->state=END; - break; - } - if( cmdcount>0 && (--cmdcount)<=0 ){ - printf("run_script: infinity loop !\n"); - st->state=END; - } - } - switch(st->state){ - case STOP: - break; - case END: - { - struct map_session_data *sd=map_id2sd(st->rid); - st->pos=-1; - if(sd && sd->npc_id==st->oid) - npc_event_dequeue(sd); - } - break; - case RERUNLINE: - { - st->pos=rerun_pos; - } - break; - } - - if( st->state!=END){ - // 再開するためにスタック情報を保存 - struct map_session_data *sd=map_id2sd(st->rid); - if(sd/* && sd->npc_stackbuf==NULL*/){ - if( sd->npc_stackbuf ) - aFree( sd->npc_stackbuf ); - sd->npc_stackbuf = (char *)aCalloc(sizeof(stack->stack_data[0])*stack->sp_max,sizeof(char)); - memcpy(sd->npc_stackbuf, stack->stack_data, sizeof(stack->stack_data[0]) * stack->sp_max); - sd->npc_stack = stack->sp; - sd->npc_stackmax = stack->sp_max; - sd->npc_script=script; - sd->npc_scriptroot=rootscript; - } - } - - return 0; -} - -/*========================================== - * スクリプトの実行 - *------------------------------------------ - */ -int run_script(char *script,int pos,int rid,int oid) -{ - struct script_stack stack; - struct script_state st; - struct map_session_data *sd=map_id2sd(rid); - char *rootscript=script; - - if(script==NULL || pos<0) - return -1; - - if(sd && sd->npc_stackbuf && sd->npc_scriptroot==rootscript){ - // 前回のスタックを復帰 - script=sd->npc_script; - stack.sp=sd->npc_stack; - stack.sp_max=sd->npc_stackmax; - stack.stack_data=(struct script_data *)aCalloc(stack.sp_max,sizeof(stack.stack_data[0])); - memcpy(stack.stack_data,sd->npc_stackbuf,sizeof(stack.stack_data[0])*stack.sp_max); - aFree(sd->npc_stackbuf); - sd->npc_stackbuf=NULL; - }else{ - // スタック初期化 - stack.sp=0; - stack.sp_max=64; - stack.stack_data=(struct script_data *)aCalloc(stack.sp_max,sizeof(stack.stack_data[0])); - } - st.stack=&stack; - st.pos=pos; - st.rid=rid; - st.oid=oid; - run_script_main(script,pos,rid,oid,&st,rootscript); - - aFree(stack.stack_data); - stack.stack_data=NULL; - return st.pos; -} - - -/*========================================== - * マップ変数の変更 - *------------------------------------------ - */ -int mapreg_setreg(int num,int val) -{ - if(val!=0) - numdb_insert(mapreg_db,num,val); - else - numdb_erase(mapreg_db,num); - - mapreg_dirty=1; - return 0; -} -/*========================================== - * 文字列型マップ変数の変更 - *------------------------------------------ - */ -int mapreg_setregstr(int num,const char *str) -{ - char *p; - - if( (p=(char *) numdb_search(mapregstr_db,num))!=NULL ) - aFree(p); - - if( str==NULL || *str==0 ){ - numdb_erase(mapregstr_db,num); - mapreg_dirty=1; - return 0; - } - p=(char *)aCallocA(strlen(str)+1, sizeof(char)); - strcpy(p,str); - numdb_insert(mapregstr_db,num,p); - mapreg_dirty=1; - return 0; -} - -/*========================================== - * 永続的マップ変数の読み込み - *------------------------------------------ - */ -static int script_load_mapreg() -{ - FILE *fp; - char line[1024]; - - if( (fp=fopen(mapreg_txt,"rt"))==NULL ) - return -1; - - while(fgets(line,sizeof(line),fp)){ - char buf1[256],buf2[1024],*p; - int n,v,s,i; - if( sscanf(line,"%255[^,],%d\t%n",buf1,&i,&n)!=2 && - (i=0,sscanf(line,"%[^\t]\t%n",buf1,&n)!=1) ) - continue; - if( buf1[strlen(buf1)-1]=='$' ){ - if( sscanf(line+n,"%[^\n\r]",buf2)!=1 ){ - printf("%s: %s broken data !\n",mapreg_txt,buf1); - continue; - } - p=(char *)aCallocA(strlen(buf2) + 1,sizeof(char)); - strcpy(p,buf2); - s= add_str((unsigned char *) buf1); - numdb_insert(mapregstr_db,(i<<24)|s,p); - }else{ - if( sscanf(line+n,"%d",&v)!=1 ){ - printf("%s: %s broken data !\n",mapreg_txt,buf1); - continue; - } - s= add_str((unsigned char *) buf1); - numdb_insert(mapreg_db,(i<<24)|s,v); - } - } - fclose(fp); - mapreg_dirty=0; - return 0; -} -/*========================================== - * 永続的マップ変数の書き込み - *------------------------------------------ - */ -static int script_save_mapreg_intsub(void *key,void *data,va_list ap) -{ - FILE *fp=va_arg(ap,FILE*); - int num=((int)key)&0x00ffffff, i=((int)key)>>24; - char *name=str_buf+str_data[num].str; - if( name[1]!='@' ){ - if(i==0) - fprintf(fp,"%s\t%d\n", name, (int)data); - else - fprintf(fp,"%s,%d\t%d\n", name, i, (int)data); - } - return 0; -} -static int script_save_mapreg_strsub(void *key,void *data,va_list ap) -{ - FILE *fp=va_arg(ap,FILE*); - int num=((int)key)&0x00ffffff, i=((int)key)>>24; - char *name=str_buf+str_data[num].str; - if( name[1]!='@' ){ - if(i==0) - fprintf(fp,"%s\t%s\n", name, (char *)data); - else - fprintf(fp,"%s,%d\t%s\n", name, i, (char *)data); - } - return 0; -} -static int script_save_mapreg() -{ - FILE *fp; - int lock; - - if( (fp=lock_fopen(mapreg_txt,&lock))==NULL ) - return -1; - numdb_foreach(mapreg_db,script_save_mapreg_intsub,fp); - numdb_foreach(mapregstr_db,script_save_mapreg_strsub,fp); - lock_fclose(fp,mapreg_txt,&lock); - mapreg_dirty=0; - return 0; -} -static int script_autosave_mapreg(int tid,unsigned int tick,int id,int data) -{ - if(mapreg_dirty) - script_save_mapreg(); - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -static int set_posword(char *p) -{ - char* np,* str[15]; - int i=0; - for(i=0;i<11;i++) { - if((np=strchr(p,','))!=NULL) { - str[i]=p; - *np=0; - p=np+1; - } else { - str[i]=p; - p+=strlen(p); - } - if(str[i]) - strcpy(pos[i],str[i]); - } - return 0; -} - -int script_config_read(char *cfgName) -{ - int i; - char line[1024],w1[1024],w2[1024]; - FILE *fp; - - script_config.warn_func_no_comma=1; - script_config.warn_cmd_no_comma=1; - script_config.warn_func_mismatch_paramnum=1; - script_config.warn_cmd_mismatch_paramnum=1; - script_config.check_cmdcount=65535; - script_config.check_gotocount=2048; - - script_config.die_event_name = (char *)aCallocA(24,sizeof(char)); - script_config.kill_event_name = (char *)aCallocA(24,sizeof(char)); - script_config.login_event_name = (char *)aCallocA(24,sizeof(char)); - script_config.logout_event_name = (char *)aCallocA(24,sizeof(char)); - - script_config.event_script_type = 0; - script_config.event_requires_trigger = 1; - - fp=fopen(cfgName,"r"); - if(fp==NULL){ - printf("file not found: %s\n",cfgName); - return 1; - } - while(fgets(line,1020,fp)){ - if(line[0] == '/' && line[1] == '/') - continue; - i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2); - if(i!=2) - continue; - if(strcmpi(w1,"refine_posword")==0) { - set_posword(w2); - } - else if(strcmpi(w1,"warn_func_no_comma")==0) { - script_config.warn_func_no_comma = battle_config_switch(w2); - } - else if(strcmpi(w1,"warn_cmd_no_comma")==0) { - script_config.warn_cmd_no_comma = battle_config_switch(w2); - } - else if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) { - script_config.warn_func_mismatch_paramnum = battle_config_switch(w2); - } - else if(strcmpi(w1,"warn_cmd_mismatch_paramnum")==0) { - script_config.warn_cmd_mismatch_paramnum = battle_config_switch(w2); - } - else if(strcmpi(w1,"check_cmdcount")==0) { - script_config.check_cmdcount = battle_config_switch(w2); - } - else if(strcmpi(w1,"check_gotocount")==0) { - script_config.check_gotocount = battle_config_switch(w2); - } - else if(strcmpi(w1,"event_script_type")==0) { - script_config.event_script_type = battle_config_switch(w2); - } - else if(strcmpi(w1,"die_event_name")==0) { - strcpy(script_config.die_event_name, w2); - } - else if(strcmpi(w1,"kill_event_name")==0) { - strcpy(script_config.kill_event_name, w2); - } - else if(strcmpi(w1,"login_event_name")==0) { - strcpy(script_config.login_event_name, w2); - } - else if(strcmpi(w1,"logout_event_name")==0) { - strcpy(script_config.logout_event_name, w2); - } - else if(strcmpi(w1,"require_set_trigger")==0) { - script_config.event_requires_trigger = battle_config_switch(w2); - } - else if(strcmpi(w1,"import")==0){ - script_config_read(w2); - } - } - fclose(fp); - - return 0; -} - -/*========================================== - * 終了 - *------------------------------------------ - */ -static int mapreg_db_final(void *key,void *data,va_list ap) -{ - return 0; -} -static int mapregstr_db_final(void *key,void *data,va_list ap) -{ - aFree(data); - return 0; -} -static int scriptlabel_db_final(void *key,void *data,va_list ap) -{ - return 0; -} -static int userfunc_db_final(void *key,void *data,va_list ap) -{ - aFree(key); - aFree(data); - return 0; -} -int do_final_script() -{ - if(mapreg_dirty>=0) - script_save_mapreg(); -// if(script_buf) -// aFree(script_buf); - - if(mapreg_db) - numdb_final(mapreg_db,mapreg_db_final); - if(mapregstr_db) - strdb_final(mapregstr_db,mapregstr_db_final); - if(scriptlabel_db) - strdb_final(scriptlabel_db,scriptlabel_db_final); - if(userfunc_db) - strdb_final(userfunc_db,userfunc_db_final); - - if (str_data) - aFree(str_data); - if (str_buf) - aFree(str_buf); - - if (script_config.die_event_name) - aFree(script_config.die_event_name); - if (script_config.kill_event_name) - aFree(script_config.kill_event_name); - if (script_config.login_event_name) - aFree(script_config.login_event_name); - if (script_config.logout_event_name) - aFree(script_config.logout_event_name); - - return 0; -} -/*========================================== - * 初期化 - *------------------------------------------ - */ -int do_init_script() -{ - mapreg_db=numdb_init(); - mapregstr_db=numdb_init(); - script_load_mapreg(); - - add_timer_func_list(script_autosave_mapreg,"script_autosave_mapreg"); - add_timer_interval(gettick()+MAPREG_AUTOSAVE_INTERVAL, - script_autosave_mapreg,0,0,MAPREG_AUTOSAVE_INTERVAL); - - scriptlabel_db=strdb_init(50); - return 0; -} diff --git a/src/map/script.h b/src/map/script.h deleted file mode 100644 index b30201a67..000000000 --- a/src/map/script.h +++ /dev/null @@ -1,59 +0,0 @@ -// $Id: script.h,v 1.2 2004/09/25 05:32:19 MouseJstr Exp $ -#ifndef _SCRIPT_H_ -#define _SCRIPT_H_ - -extern struct Script_Config { - int warn_func_no_comma; - int warn_cmd_no_comma; - int warn_func_mismatch_paramnum; - int warn_cmd_mismatch_paramnum; - int check_cmdcount; - int check_gotocount; - - int event_script_type; - char* die_event_name; - char* kill_event_name; - char* login_event_name; - char* logout_event_name; - int event_requires_trigger; -} script_config; - -struct script_data { - int type; - union { - int num; - char *str; - } u; -}; - -struct script_stack { - int sp,sp_max; - struct script_data *stack_data; -}; -struct script_state { - struct script_stack *stack; - int start,end; - int pos,state; - int rid,oid; - char *script,*new_script; - int defsp,new_pos,new_defsp; -}; - -char * parse_script(unsigned char *,int); -int run_script(char *,int,int,int); - -int set_var(struct map_session_data *sd, char *name, void *val); -int conv_num(struct script_state *st,struct script_data *data); -char* conv_str(struct script_state *st,struct script_data *data); - -struct dbt* script_get_label_db(); -struct dbt* script_get_userfunc_db(); - -int script_config_read(char *cfgName); -int do_init_script(); -int do_final_script(); - -extern char mapreg_txt[]; - -#endif - diff --git a/src/map/skill.c b/src/map/skill.c deleted file mode 100644 index c53a7a9d6..000000000 --- a/src/map/skill.c +++ /dev/null @@ -1,9690 +0,0 @@ -// $Id: skill.c,v 1.8 2004/02/27 5:34:51 PM Celestia $ -/* スキル?係 */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include "timer.h" -#include "nullpo.h" -#include "malloc.h" - -#include "skill.h" -#include "map.h" -#include "clif.h" -#include "pc.h" -#include "status.h" -#include "pet.h" -#include "mob.h" -#include "battle.h" -#include "party.h" -#include "itemdb.h" -#include "script.h" -#include "intif.h" -#include "log.h" -#include "chrif.h" -#include "guild.h" -#include "showmsg.h" -#include "grfio.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -#define SKILLUNITTIMER_INVERVAL 100 -#define STATE_BLIND 0x10 -#define swap(x,y) { int t; t = x; x = y; y = t; } - -const struct skill_name_db skill_names[] = { - { AC_CHARGEARROW, "CHARGEARROW", "Charge_Arrow" } , - { AC_CONCENTRATION, "CONCENTRATION", "Improve_Concentration" } , - { AC_DOUBLE, "DOUBLE", "Double_Strafe" } , - { AC_MAKINGARROW, "MAKINGARROW", "Arrow_Creation" } , - { AC_OWL, "OWL", "Owl's_Eye" } , - { AC_SHOWER, "SHOWER", "Arrow_Shower" } , - { AC_VULTURE, "VULTURE", "Vulture's_Eye" } , - { ALL_RESURRECTION, "RESURRECTION", "Resurrection" } , - { AL_ANGELUS, "ANGELUS", "Angelus" } , - { AL_BLESSING, "BLESSING", "Blessing" } , - { AL_CRUCIS, "CRUCIS", "Signum_Crusis" } , - { AL_CURE, "CURE", "Cure" } , - { AL_DECAGI, "DECAGI", "Decrease_AGI" } , - { AL_DEMONBANE, "DEMONBANE", "Demon_Bane" } , - { AL_DP, "DP", "Divine_Protection" } , - { AL_HEAL, "HEAL", "Heal" } , - { AL_HOLYLIGHT, "HOLYLIGHT", "Holy_Light" } , - { AL_HOLYWATER, "HOLYWATER", "Aqua_Benedicta" } , - { AL_INCAGI, "INCAGI", "Increase_AGI" } , - { AL_PNEUMA, "PNEUMA", "Pneuma" } , - { AL_RUWACH, "RUWACH", "Ruwach" } , - { AL_TELEPORT, "TELEPORT", "Teleport" } , - { AL_WARP, "WARP", "Warp_Portal" } , - { AM_ACIDTERROR, "ACIDTERROR", "Acid_Terror" } , - { AM_AXEMASTERY, "AXEMASTERY", "Axe_Mastery" } , - { AM_BERSERKPITCHER, "BERSERKPITCHER", "Berserk Pitcher" } , - { AM_BIOETHICS, "BIOETHICS", "Bioethics" } , - { AM_BIOTECHNOLOGY, "BIOTECHNOLOGY", "Biotechnology" } , - { AM_CALLHOMUN, "CALLHOMUN", "Call_Homunculus" } , - { AM_CANNIBALIZE, "CANNIBALIZE", "Bio_Cannibalize" } , - { AM_CP_ARMOR, "ARMOR", "Chemical_Protection_Armor" } , - { AM_CP_HELM, "HELM", "Chemical_Protection_Helm" } , - { AM_CP_SHIELD, "SHIELD", "Chemical_Protection_Shield" } , - { AM_CP_WEAPON, "WEAPON", "Chemical_Protection_Weapon" } , - { AM_CREATECREATURE, "CREATECREATURE", "Life_Creation" } , - { AM_CULTIVATION, "CULTIVATION", "Cultivation" } , - { AM_DEMONSTRATION, "DEMONSTRATION", "Demonstration" } , - { AM_DRILLMASTER, "DRILLMASTER", "Drillmaster" } , - { AM_FLAMECONTROL, "FLAMECONTROL", "Flame_Control" } , - { AM_HEALHOMUN, "HEALHOMUN", "Heal_Homunculus" } , - { AM_LEARNINGPOTION, "LEARNINGPOTION", "AM_LEARNINGPOTION" } , - { AM_PHARMACY, "PHARMACY", "Pharmacy" } , - { AM_POTIONPITCHER, "POTIONPITCHER", "Potion_Pitcher" } , - { AM_REST, "REST", "Sabbath" } , - { AM_RESURRECTHOMUN, "RESURRECTHOMUN", "Ressurect_Homunculus" } , - { AM_SPHEREMINE, "SPHEREMINE", "Sphere_Mine" } , - { ASC_BREAKER, "BREAKER", "Breaker" } , - { ASC_CDP, "CDP", "Create_Deadly_Poison" } , - { ASC_EDP, "EDP", "Deadly_Poison_Enchantment" } , - { ASC_HALLUCINATION, "HALLUCINATION", "Hallucination_Walk" } , - { ASC_KATAR, "KATAR", "Advanced_Katar_Mastery" } , - { ASC_METEORASSAULT, "METEORASSAULT", "Meteor_Assault" } , - { AS_CLOAKING, "CLOAKING", "Cloaking" } , - { AS_ENCHANTPOISON, "ENCHANTPOISON", "Enchant_Poison" } , - { AS_GRIMTOOTH, "GRIMTOOTH", "Grimtooth" } , - { AS_KATAR, "KATAR", "Katar_Mastery" } , - { AS_LEFT, "LEFT", "Lefthand_Mastery" } , - { AS_POISONREACT, "POISONREACT", "Poison_React" } , - { AS_RIGHT, "RIGHT", "Righthand_Mastery" } , - { AS_SONICBLOW, "SONICBLOW", "Sonic_Blow" } , - { AS_SPLASHER, "SPLASHER", "Venom_Splasher" } , - { AS_VENOMDUST, "VENOMDUST", "Venom_Dust" } , - { BA_APPLEIDUN, "APPLEIDUN", "Apple_of_Idun" } , - { BA_ASSASSINCROSS, "ASSASSINCROSS", "Assassin_Cross" } , - { BA_DISSONANCE, "DISSONANCE", "Dissonance" } , - { BA_FROSTJOKE, "FROSTJOKE", "Dumb_Joke" } , - { BA_MUSICALLESSON, "MUSICALLESSON", "Musical_Lesson" } , - { BA_MUSICALSTRIKE, "MUSICALSTRIKE", "Musical_Strike" } , - { BA_POEMBRAGI, "POEMBRAGI", "Poem_of_Bragi" } , - { BA_WHISTLE, "WHISTLE", "Whistle" } , - { BD_ADAPTATION, "ADAPTATION", "Adaption" } , - { BD_DRUMBATTLEFIELD, "DRUMBATTLEFIELD", "Drumb_BattleField" } , - { BD_ENCORE, "ENCORE", "Encore" } , - { BD_ETERNALCHAOS, "ETERNALCHAOS", "Eternal_Chaos" } , - { BD_INTOABYSS, "INTOABYSS", "Into_the_Abyss" } , - { BD_LULLABY, "LULLABY", "Lullaby" } , - { BD_RAGNAROK, "RAGNAROK", "Ragnarok" } , - { BD_RICHMANKIM, "RICHMANKIM", "Rich_Mankim" } , - { BD_RINGNIBELUNGEN, "RINGNIBELUNGEN", "Ring_of_Nibelugen" } , - { BD_ROKISWEIL, "ROKISWEIL", "Loki's_Wail" } , - { BD_SIEGFRIED, "SIEGFRIED", "Invulnerable_Siegfried" } , - { BS_ADRENALINE, "ADRENALINE", "Adrenaline_Rush" } , - { BS_ADRENALINE2, "ADRENALINE2", "Adrenaline Rush 2" } , - { BS_AXE, "AXE", "Smith_Axe" } , - { BS_DAGGER, "DAGGER", "Smith_Dagger" } , - { BS_ENCHANTEDSTONE, "ENCHANTEDSTONE", "Enchantedstone_Craft" } , - { BS_FINDINGORE, "FINDINGORE", "Ore_Discovery" } , - { BS_HAMMERFALL, "HAMMERFALL", "Hammer_Fall" } , - { BS_HILTBINDING, "HILTBINDING", "Hilt_Binding" } , - { BS_IRON, "IRON", "Iron_Tempering" } , - { BS_KNUCKLE, "KNUCKLE", "Smith_Knucklebrace" } , - { BS_MACE, "MACE", "Smith_Mace" } , - { BS_MAXIMIZE, "MAXIMIZE", "Power_Maximize" } , - { BS_ORIDEOCON, "ORIDEOCON", "Orideocon_Research" } , - { BS_OVERTHRUST, "OVERTHRUST", "Power-Thrust" } , - { BS_REPAIRWEAPON, "REPAIRWEAPON", "Weapon_Repair" } , - { BS_SKINTEMPER, "SKINTEMPER", "Skin_Tempering" } , - { BS_SPEAR, "SPEAR", "Smith_Spear" } , - { BS_STEEL, "STEEL", "Steel_Tempering" } , - { BS_SWORD, "SWORD", "Smith_Sword" } , - { BS_TWOHANDSWORD, "TWOHANDSWORD", "Smith_Two-handed_Sword" } , - { BS_WEAPONPERFECT, "WEAPONPERFECT", "Weapon_Perfection" } , - { BS_WEAPONRESEARCH, "WEAPONRESEARCH", "Weaponry_Research" } , - { CG_ARROWVULCAN, "ARROWVULCAN", "Vulcan_Arrow" } , - { CG_MARIONETTE, "MARIONETTE", "Marionette_Control" } , - { CG_MOONLIT, "MOONLIT", "Moonlight_Petals" } , - { CH_CHAINCRUSH, "CHAINCRUSH", "Chain_Crush_Combo" } , - { CH_PALMSTRIKE, "PALMSTRIKE", "Palm_Push_Strike" } , - { CH_SOULCOLLECT, "SOULCOLLECT", "Collect_Soul" } , - { CH_TIGERFIST, "TIGERFIST", "Tiger_Knuckle_Fist" } , - { CR_ALCHEMY, "ALCHEMY", "Alchemy" } , - { CR_SLIMPITCHER, "SLIMPITCHER", "Slim_Pitcher" } , - { CR_FULLPROTECTION, "FULLPROTECTION", "Full_Chemical_Protection" } , - { CR_AUTOGUARD, "AUTOGUARD", "Guard" } , - { CR_DEFENDER, "DEFENDER", "Defender" } , - { CR_DEVOTION, "DEVOTION", "Sacrifice" } , - { CR_GRANDCROSS, "GRANDCROSS", "Grand_Cross" } , - { CR_HOLYCROSS, "HOLYCROSS", "Holy_Cross" } , - { CR_PROVIDENCE, "PROVIDENCE", "Providence" } , - { CR_REFLECTSHIELD, "REFLECTSHIELD", "Shield_Reflect" } , - { CR_SHIELDBOOMERANG, "SHIELDBOOMERANG", "Shield_Boomerang" } , - { CR_SHIELDCHARGE, "SHIELDCHARGE", "Shield_Charge" } , - { CR_SPEARQUICKEN, "SPEARQUICKEN", "Spear_Quicken" } , - { CR_SYNTHESISPOTION, "SYNTHESISPOTION", "Potion_Synthesis" } , - { CR_TRUST, "TRUST", "Faith" } , - { DC_DANCINGLESSON, "DANCINGLESSON", "Dancing_Lesson" } , - { DC_DONTFORGETME, "DONTFORGETME", "Don't_Forget_Me" } , - { DC_FORTUNEKISS, "FORTUNEKISS", "Fortune_Kiss" } , - { DC_HUMMING, "HUMMING", "Humming" } , - { DC_SCREAM, "SCREAM", "Scream" } , - { DC_SERVICEFORYOU, "SERVICEFORYOU", "Prostitute" } , - { DC_THROWARROW, "THROWARROW", "Throw_Arrow" } , - { DC_UGLYDANCE, "UGLYDANCE", "Ugly_Dance" } , - { GD_BATTLEORDER, "BATTLEORDER", "Battle_Orders" } , - { GD_REGENERATION, "REGENERATION", "Regeneration" } , - { GD_RESTORE, "RESTORE", "Restore" } , - { GD_EMERGENCYCALL, "EMERGENCYCALL", "Emergency_Call" } , - { HP_ASSUMPTIO, "ASSUMPTIO", "Assumptio" } , - { HP_BASILICA, "BASILICA", "Basilica" } , - { HP_MEDITATIO, "MEDITATIO", "Meditation" } , - { HT_ANKLESNARE, "ANKLESNARE", "Ankle_Snare" } , - { HT_BEASTBANE, "BEASTBANE", "Beast_Bane" } , - { HT_BLASTMINE, "BLASTMINE", "Blast_Mine" } , - { HT_BLITZBEAT, "BLITZBEAT", "Blitz_Beat" } , - { HT_CLAYMORETRAP, "CLAYMORETRAP", "Claymore_Trap" } , - { HT_DETECTING, "DETECTING", "Detect" } , - { HT_FALCON, "FALCON", "Falconry_Mastery" } , - { HT_FLASHER, "FLASHER", "Flasher" } , - { HT_FREEZINGTRAP, "FREEZINGTRAP", "Freezing_Trap" } , - { HT_LANDMINE, "LANDMINE", "Land_Mine" } , - { HT_REMOVETRAP, "REMOVETRAP", "Remove_Trap" } , - { HT_SANDMAN, "SANDMAN", "Sandman" } , - { HT_SHOCKWAVE, "SHOCKWAVE", "Shockwave_Trap" } , - { HT_SKIDTRAP, "SKIDTRAP", "Skid_Trap" } , - { HT_SPRINGTRAP, "SPRINGTRAP", "Spring_Trap" } , - { HT_STEELCROW, "STEELCROW", "Steel_Crow" } , - { HT_TALKIEBOX, "TALKIEBOX", "Talkie_Box" } , - { HW_MAGICCRASHER, "MAGICCRASHER", "Magic_Crasher" } , - { HW_MAGICPOWER, "MAGICPOWER", "Magic_Power" } , - { HW_NAPALMVULCAN, "NAPALMVULCAN", "Napalm_Vulcan" } , - { HW_SOULDRAIN, "SOULDRAIN", "Soul_Drain" } , - { ITM_TOMAHAWK, "TOMAHAWK", "Throw_Tomahawk" } , - { KN_AUTOCOUNTER, "AUTOCOUNTER", "Counter_Attack" } , - { KN_BOWLINGBASH, "BOWLINGBASH", "Bowling_Bash" } , - { KN_BRANDISHSPEAR, "BRANDISHSPEAR", "Brandish_Spear" } , - { KN_CAVALIERMASTERY, "CAVALIERMASTERY", "Cavalier_Mastery" } , - { KN_PIERCE, "PIERCE", "Pierce" } , - { KN_RIDING, "RIDING", "Peco_Peco_Ride" } , - { KN_SPEARBOOMERANG, "SPEARBOOMERANG", "Spear_Boomerang" } , - { KN_SPEARMASTERY, "SPEARMASTERY", "Spear_Mastery" } , - { KN_SPEARSTAB, "SPEARSTAB", "Spear_Stab" } , - { KN_TWOHANDQUICKEN, "TWOHANDQUICKEN", "Twohand_Quicken" } , - { LK_AURABLADE, "AURABLADE", "Aura_Blade" } , - { LK_BERSERK, "BERSERK", "Berserk" } , - { LK_CONCENTRATION, "CONCENTRATION", "Concentration" } , - { LK_FURY, "FURY", "LK_FURY" } , - { LK_HEADCRUSH, "HEADCRUSH", "Head_Crusher" } , - { LK_JOINTBEAT, "JOINTBEAT", "Joint_Beat" } , - { LK_PARRYING, "PARRYING", "Parrying" } , - { LK_SPIRALPIERCE, "SPIRALPIERCE", "Spiral_Pierce" } , - { LK_TENSIONRELAX, "TENSIONRELAX", "Tension_Relax" } , - { MC_CARTREVOLUTION, "CARTREVOLUTION", "Cart_Revolution" } , - { MC_CHANGECART, "CHANGECART", "Change_Cart" } , - { MC_DISCOUNT, "DISCOUNT", "Discount" } , - { MC_IDENTIFY, "IDENTIFY", "Item_Appraisal" } , - { MC_INCCARRY, "INCCARRY", "Enlarge_Weight_Limit" } , - { MC_LOUD, "LOUD", "Lord_Exclamation" } , - { MC_MAMMONITE, "MAMMONITE", "Mammonite" } , - { MC_OVERCHARGE, "OVERCHARGE", "Overcharge" } , - { MC_PUSHCART, "PUSHCART", "Pushcart" } , - { MC_VENDING, "VENDING", "Vending" } , - { MG_COLDBOLT, "COLDBOLT", "Cold_Bolt" } , - { MG_ENERGYCOAT, "ENERGYCOAT", "Energy_Coat" } , - { MG_FIREBALL, "FIREBALL", "Fire_Ball" } , - { MG_FIREBOLT, "FIREBOLT", "Fire_Bolt" } , - { MG_FIREWALL, "FIREWALL", "Fire_Wall" } , - { MG_FROSTDIVER, "FROSTDIVER", "Frost_Diver" } , - { MG_LIGHTNINGBOLT, "LIGHTNINGBOLT", "Lightening_Bolt" } , - { MG_NAPALMBEAT, "NAPALMBEAT", "Napalm_Beat" } , - { MG_SAFETYWALL, "SAFETYWALL", "Safety_Wall" } , - { MG_SIGHT, "SIGHT", "Sight" } , - { MG_SOULSTRIKE, "SOULSTRIKE", "Soul_Strike" } , - { MG_SRECOVERY, "SRECOVERY", "Increase_SP_Recovery" } , - { MG_STONECURSE, "STONECURSE", "Stone_Curse" } , - { MG_THUNDERSTORM, "THUNDERSTORM", "Thunderstorm" } , - { MO_ABSORBSPIRITS, "ABSORBSPIRITS", "Absorb_Spirits" } , - { MO_BLADESTOP, "BLADESTOP", "Blade_Stop" } , - { MO_BODYRELOCATION, "BODYRELOCATION", "Body_Relocation" } , - { MO_CALLSPIRITS, "CALLSPIRITS", "Call_Spirits" } , - { MO_CHAINCOMBO, "CHAINCOMBO", "Chain_Combo" } , - { MO_COMBOFINISH, "COMBOFINISH", "Combo_Finish" } , - { MO_DODGE, "DODGE", "Dodge" } , - { MO_EXPLOSIONSPIRITS, "EXPLOSIONSPIRITS", "Explosion_Spirits" } , - { MO_EXTREMITYFIST, "EXTREMITYFIST", "Extremity_Fist" } , - { MO_FINGEROFFENSIVE, "FINGEROFFENSIVE", "Finger_Offensive" } , - { MO_INVESTIGATE, "INVESTIGATE", "Investigate" } , - { MO_IRONHAND, "IRONHAND", "Iron_Hand" } , - { MO_SPIRITSRECOVERY, "SPIRITSRECOVERY", "Spirit_Recovery" } , - { MO_STEELBODY, "STEELBODY", "Steel_Body" } , - { MO_TRIPLEATTACK, "TRIPLEATTACK", "Triple_Blows" } , - { NPC_ATTRICHANGE, "ATTRICHANGE", "NPC_ATTRICHANGE" } , - { NPC_BARRIER, "BARRIER", "NPC_BARRIER" } , - { NPC_BLINDATTACK, "BLINDATTACK", "NPC_BLINDATTACK" } , - { NPC_BLOODDRAIN, "BLOODDRAIN", "NPC_BLOODDRAIN" } , - { NPC_CHANGEDARKNESS, "CHANGEDARKNESS", "NPC_CHANGEDARKNESS" } , - { NPC_CHANGEFIRE, "CHANGEFIRE", "NPC_CHANGEFIRE" } , - { NPC_CHANGEGROUND, "CHANGEGROUND", "NPC_CHANGEGROUND" } , - { NPC_CHANGEHOLY, "CHANGEHOLY", "NPC_CHANGEHOLY" } , - { NPC_CHANGEPOISON, "CHANGEPOISON", "NPC_CHANGEPOISON" } , - { NPC_CHANGETELEKINESIS, "CHANGETELEKINESIS", "NPC_CHANGETELEKINESIS" } , - { NPC_CHANGEWATER, "CHANGEWATER", "NPC_CHANGEWATER" } , - { NPC_CHANGEWIND, "CHANGEWIND", "NPC_CHANGEWIND" } , - { NPC_COMBOATTACK, "COMBOATTACK", "NPC_COMBOATTACK" } , - { NPC_CRITICALSLASH, "CRITICALSLASH", "NPC_CRITICALSLASH" } , - { NPC_CURSEATTACK, "CURSEATTACK", "NPC_CURSEATTACK" } , - { NPC_DARKBLESSING, "DARKBLESSING", "NPC_DARKBLESSING" } , - { NPC_DARKBREATH, "DARKBREATH", "NPC_DARKBREATH" } , - { NPC_DARKCROSS, "DARKCROSS", "NPC_DARKCROSS" } , - { NPC_DARKNESSATTACK, "DARKNESSATTACK", "NPC_DARKNESSATTACK" } , - { NPC_DEFENDER, "DEFENDER", "NPC_DEFENDER" } , - { NPC_EMOTION, "EMOTION", "NPC_EMOTION" } , - { NPC_ENERGYDRAIN, "ENERGYDRAIN", "NPC_ENERGYDRAIN" } , - { NPC_FIREATTACK, "FIREATTACK", "NPC_FIREATTACK" } , - { NPC_GROUNDATTACK, "GROUNDATTACK", "NPC_GROUNDATTACK" } , - { NPC_GUIDEDATTACK, "GUIDEDATTACK", "NPC_GUIDEDATTACK" } , - { NPC_HALLUCINATION, "HALLUCINATION", "NPC_HALLUCINATION" } , - { NPC_HOLYATTACK, "HOLYATTACK", "NPC_HOLYATTACK" } , - { NPC_KEEPING, "KEEPING", "NPC_KEEPING" } , - { NPC_LICK, "LICK", "NPC_LICK" } , - { NPC_MAGICALATTACK, "MAGICALATTACK", "NPC_MAGICALATTACK" } , - { NPC_MENTALBREAKER, "MENTALBREAKER", "NPC_MENTALBREAKER" } , - { NPC_METAMORPHOSIS, "METAMORPHOSIS", "NPC_METAMORPHOSIS" } , - { NPC_PETRIFYATTACK, "PETRIFYATTACK", "NPC_PETRIFYATTACK" } , - { NPC_PIERCINGATT, "PIERCINGATT", "NPC_PIERCINGATT" } , - { NPC_POISON, "POISON", "NPC_POISON" } , - { NPC_POISONATTACK, "POISONATTACK", "NPC_POISONATTACK" } , - { NPC_PROVOCATION, "PROVOCATION", "NPC_PROVOCATION" } , - { NPC_RANDOMATTACK, "RANDOMATTACK", "NPC_RANDOMATTACK" } , - { NPC_RANGEATTACK, "RANGEATTACK", "NPC_RANGEATTACK" } , - { NPC_REBIRTH, "REBIRTH", "NPC_REBIRTH" } , - { NPC_SELFDESTRUCTION, "SELFDESTRUCTION", "Kabooooom!" } , - { NPC_SELFDESTRUCTION2, "SELFDESTRUCTION2", "NPC_SELFDESTRUCTION2" } , - { NPC_SILENCEATTACK, "SILENCEATTACK", "NPC_SILENCEATTACK" } , - { NPC_SLEEPATTACK, "SLEEPATTACK", "NPC_SLEEPATTACK" } , - { NPC_SMOKING, "SMOKING", "NPC_SMOKING" } , - { NPC_SPLASHATTACK, "SPLASHATTACK", "NPC_SPLASHATTACK" } , - { NPC_STUNATTACK, "STUNATTACK", "NPC_STUNATTACK" } , - { NPC_SUICIDE, "SUICIDE", "NPC_SUICIDE" } , - { NPC_SUMMONMONSTER, "SUMMONMONSTER", "NPC_SUMMONMONSTER" } , - { NPC_SUMMONSLAVE, "SUMMONSLAVE", "NPC_SUMMONSLAVE" } , - { NPC_TELEKINESISATTACK, "TELEKINESISATTACK", "NPC_TELEKINESISATTACK" } , - { NPC_TRANSFORMATION, "TRANSFORMATION", "NPC_TRANSFORMATION" } , - { NPC_WATERATTACK, "WATERATTACK", "NPC_WATERATTACK" } , - { NPC_WINDATTACK, "WINDATTACK", "NPC_WINDATTACK" } , - { NV_BASIC, "BASIC", "Basic_Skill" } , - { NV_FIRSTAID, "FIRSTAID", "First Aid" } , - { NV_TRICKDEAD, "TRICKDEAD", "Play_Dead" } , - { PA_GOSPEL, "GOSPEL", "Gospel" } , - { PA_PRESSURE, "PRESSURE", "Pressure" } , - { PA_SACRIFICE, "SACRIFICE", "Sacrificial_Ritual" } , - { PF_FOGWALL, "FOGWALL", "Wall_of_Fog" } , - { PF_HPCONVERSION, "HPCONVERSION", "Health_Conversion" } , - { PF_MEMORIZE, "MEMORIZE", "Memorize" } , - { PF_MINDBREAKER, "MINDBREAKER", "Mind_Breaker" } , - { PF_SOULBURN, "SOULBURN", "Soul_Burn" } , - { PF_SOULCHANGE, "SOULCHANGE", "Soul_Change" } , - { PF_SPIDERWEB, "SPIDERWEB", "Spider_Web" } , - { PR_ASPERSIO, "ASPERSIO", "Aspersio" } , - { PR_BENEDICTIO, "BENEDICTIO", "B.S_Sacramenti" } , - { PR_GLORIA, "GLORIA", "Gloria" } , - { PR_IMPOSITIO, "IMPOSITIO", "Impositio_Manus" } , - { PR_KYRIE, "KYRIE", "Kyrie_Eleison" } , - { PR_LEXAETERNA, "LEXAETERNA", "Lex_Aeterna" } , - { PR_LEXDIVINA, "LEXDIVINA", "Lex_Divina" } , - { PR_MACEMASTERY, "MACEMASTERY", "Mace_Mastery" } , - { PR_MAGNIFICAT, "MAGNIFICAT", "Magnificat" } , - { PR_MAGNUS, "MAGNUS", "Magnus_Exorcismus" } , - { PR_SANCTUARY, "SANCTUARY", "Santuary" } , - { PR_SLOWPOISON, "SLOWPOISON", "Slow_Poison" } , - { PR_STRECOVERY, "STRECOVERY", "Status_Recovery" } , - { PR_SUFFRAGIUM, "SUFFRAGIUM", "Suffragium" } , - { PR_TURNUNDEAD, "TURNUNDEAD", "Turn_Undead" } , - { RG_BACKSTAP, "BACKSTAP", "Back_Stab" } , - { RG_CLEANER, "CLEANER", "Remover" } , - { RG_COMPULSION, "COMPULSION", "Compulsion_Discount" } , - { RG_FLAGGRAFFITI, "FLAGGRAFFITI", "Flag_Graffity" } , - { RG_GANGSTER, "GANGSTER", "Gangster's_Paradise" } , - { RG_GRAFFITI, "GRAFFITI", "Graffiti" } , - { RG_INTIMIDATE, "INTIMIDATE", "Intimidate" } , - { RG_PLAGIARISM, "PLAGIARISM", "Plagiarism" } , - { RG_RAID, "RAID", "Raid" } , - { RG_SNATCHER, "SNATCHER", "Snatcher" } , - { RG_STEALCOIN, "STEALCOIN", "Steal_Coin" } , - { RG_STRIPARMOR, "STRIPARMOR", "Strip_Armor" } , - { RG_STRIPHELM, "STRIPHELM", "Strip_Helm" } , - { RG_STRIPSHIELD, "STRIPSHIELD", "Strip_Shield" } , - { RG_STRIPWEAPON, "STRIPWEAPON", "Strip_Weapon" } , - { RG_TUNNELDRIVE, "TUNNELDRIVE", "Tunnel_Drive" } , - { SA_ABRACADABRA, "ABRACADABRA", "Hocus-pocus" } , - { SA_ADVANCEDBOOK, "ADVANCEDBOOK", "Advanced_Book" } , - { SA_AUTOSPELL, "AUTOSPELL", "Auto_Cast" } , - { SA_CASTCANCEL, "CASTCANCEL", "Cast_Cancel" } , - { SA_CLASSCHANGE, "CLASSCHANGE", "Class_Change" } , - { SA_COMA, "COMA", "Coma" } , - { SA_DEATH, "DEATH", "Death" } , - { SA_DELUGE, "DELUGE", "Deluge" } , - { SA_DISPELL, "DISPELL", "Dispel" } , - { SA_DRAGONOLOGY, "DRAGONOLOGY", "Dragonology" } , - { SA_FLAMELAUNCHER, "FLAMELAUNCHER", "Flame_Launcher" } , - { SA_FORTUNE, "FORTUNE", "Fortune" } , - { SA_FREECAST, "FREECAST", "Cast_Freedom" } , - { SA_FROSTWEAPON, "FROSTWEAPON", "Frost_Weapon" } , - { SA_FULLRECOVERY, "FULLRECOVERY", "Full_Recovery" } , - { SA_GRAVITY, "GRAVITY", "Gravity" } , - { SA_INSTANTDEATH, "INSTANTDEATH", "Instant_Death" } , - { SA_LANDPROTECTOR, "LANDPROTECTOR", "Land_Protector" } , - { SA_LEVELUP, "LEVELUP", "Level_Up" } , - { SA_LIGHTNINGLOADER, "LIGHTNINGLOADER", "Lightning_Loader" } , - { SA_MAGICROD, "MAGICROD", "Magic_Rod" } , - { SA_MONOCELL, "MONOCELL", "Monocell" } , - { SA_QUESTION, "QUESTION", "Question?" } , - { SA_REVERSEORCISH, "REVERSEORCISH", "Reverse_Orcish" } , - { SA_SEISMICWEAPON, "SEISMICWEAPON", "Seismic_Weapon" } , - { SA_SPELLBREAKER, "SPELLBREAKER", "Break_Spell" } , - { SA_SUMMONMONSTER, "SUMMONMONSTER", "Summon_Monster" } , - { SA_TAMINGMONSTER, "TAMINGMONSTER", "Taming_Monster" } , - { SA_VIOLENTGALE, "VIOLENTGALE", "Violent_Gale" } , - { SA_VOLCANO, "VOLCANO", "Volcano" } , - { SG_DEVIL, "DEVIL", "Devil" } , - { SG_FEEL, "FEEL", "Feel" } , - { SG_FRIEND, "FRIEND", "Friend" } , - { SG_FUSION, "FUSION", "Fusion" } , - { SG_HATE, "HATE", "Hate" } , - { SG_KNOWLEDGE, "KNOWLEDGE", "Knowledge" } , - { SG_MOON_ANGER, "ANGER", "Moon Anger" } , - { SG_MOON_BLESS, "BLESS", "Moon Bless" } , - { SG_MOON_COMFORT, "COMFORT", "Moon Comfort" } , - { SG_MOON_WARM, "WARM", "Moon Warm" } , - { SG_STAR_ANGER, "ANGER", "Star Anger" } , - { SG_STAR_BLESS, "BLESS", "Star Bless" } , - { SG_STAR_COMFORT, "COMFORT", "Star Comfort" } , - { SG_STAR_WARM, "WARM", "Star Warm" } , - { SG_SUN_ANGER, "ANGER", "Sun Anger" } , - { SG_SUN_BLESS, "BLESS", "Sun Bless" } , - { SG_SUN_COMFORT, "COMFORT", "Sun Comfort" } , - { SG_SUN_WARM, "WARM", "Sun Warm" } , - { SL_ALCHEMIST, "ALCHEMIST", "Alchemist" } , - { SL_ASSASIN, "ASSASIN", "Assasin" } , - { SL_BARDDANCER, "BARDDANCER", "Bard Dancer" } , - { SL_BLACKSMITH, "BLACKSMITH", "Black Smith" } , - { SL_CRUSADER, "CRUSADER", "Crusader" } , - { SL_HUNTER, "HUNTER", "Hunter" } , - { SL_KAAHI, "KAAHI", "Kaahi" } , - { SL_KAINA, "KAINA", "Kaina" } , - { SL_KAITE, "KAITE", "Kaite" } , - { SL_KAIZEL, "KAIZEL", "Kaizel" } , - { SL_KAUPE, "KAUPE", "Kaupe" } , - { SL_KNIGHT, "KNIGHT", "Knight" } , - { SL_MONK, "MONK", "Monk" } , - { SL_PRIEST, "PRIEST", "Priest" } , - { SL_ROGUE, "ROGUE", "Rogue" } , - { SL_SAGE, "SAGE", "Sage" } , - { SL_SKA, "SKA", "SKA" } , - { SL_SKE, "SKE", "SKE" } , - { SL_SMA, "SMA", "SMA" } , - { SL_SOULLINKER, "SOULLINKER", "Soul Linker" } , - { SL_STAR, "STAR", "Star" } , - { SL_STIN, "STIN", "Stin" } , - { SL_STUN, "STUN", "Stun" } , - { SL_SUPERNOVICE, "SUPERNOVICE", "Super Novice" } , - { SL_SWOO, "SWOO", "Swoo" } , - { SL_WIZARD, "WIZARD", "Wizard" } , - { SM_AUTOBERSERK, "AUTOBERSERK", "Auto_Berserk" } , - { SM_BASH, "BASH", "Bash" } , - { SM_ENDURE, "ENDURE", "Endure" } , - { SM_FATALBLOW, "FATALBLOW", "Attack_Weak_Point" } , - { SM_MAGNUM, "MAGNUM", "Magnum_Break" } , - { SM_MOVINGRECOVERY, "MOVINGRECOVERY", "Moving_HP_Recovery" } , - { SM_PROVOKE, "PROVOKE", "Provoke" } , - { SM_RECOVERY, "RECOVERY", "Increase_HP_Recovery" } , - { SM_SWORD, "SWORD", "Sword_Mastery" } , - { SM_TWOHAND, "TWOHAND", "Two-Handed_Sword_Mastery" } , - { SN_FALCONASSAULT, "FALCONASSAULT", "Falcon_Assault" } , - { SN_SHARPSHOOTING, "SHARPSHOOTING", "Sharpshooting" } , - { SN_SIGHT, "SIGHT", "True_Sight" } , - { SN_WINDWALK, "WINDWALK", "Wind_Walk" } , - { ST_CHASEWALK, "CHASEWALK", "Chase_Walk" } , - { ST_REJECTSWORD, "REJECTSWORD", "Reject_Sword" } , - { ST_STEALBACKPACK, "STEALBACKPACK", "Steal_Backpack" } , - { ST_PRESERVE, "PRESERVE", "Preserve" } , - { ST_FULLSTRIP, "FULLSTRIP", "Full_Strip" } , - { TF_BACKSLIDING, "BACKSLIDING", "Back_Sliding" } , - { TF_DETOXIFY, "DETOXIFY", "Detoxify" } , - { TF_DOUBLE, "DOUBLE", "Double_Attack" } , - { TF_HIDING, "HIDING", "Hiding" } , - { TF_MISS, "MISS", "Improve_Dodge" } , - { TF_PICKSTONE, "PICKSTONE", "Take_Stone" } , - { TF_POISON, "POISON", "Envenom" } , - { TF_SPRINKLESAND, "SPRINKLESAND", "Throw_Sand" } , - { TF_STEAL, "STEAL", "Steal" } , - { TF_THROWSTONE, "THROWSTONE", "Throw_Stone" } , - { TK_COUNTER, "COUNTER", "Counter" } , - { TK_DODGE, "DODGE", "Dodge" } , - { TK_DOWNKICK, "DOWNKICK", "Down Kick" } , - { TK_HIGHJUMP, "HIGHJUMP", "High Jump" } , - { TK_HPTIME, "HPTIME", "HP Time" } , - { TK_JUMPKICK, "JUMPKICK", "Jump Kick" } , - { TK_POWER, "POWER", "Power" } , - { TK_READYCOUNTER, "READYCOUNTER", "Ready Counter" } , - { TK_READYDOWN, "READYDOWN", "Ready Down" } , - { TK_READYSTORM, "READYSTORM", "Ready Storm" } , - { TK_READYTURN, "READYTURN", "Ready Turn" } , - { TK_RUN, "RUN", "TK_RUN" } , - { TK_SEVENWIND, "SEVENWIND", "Seven Wind" } , - { TK_SPTIME, "SPTIME", "SP Time" } , - { TK_STORMKICK, "STORMKICK", "Storm Kick" } , - { TK_TURNKICK, "TURNKICK", "Turn Kick" } , - { WE_BABY, "BABY", "I Love Mama and Fafa" } , - { WE_CALLBABY, "CALLBABY", "Come With Me, Baby" } , - { WE_CALLPARENT, "CALLPARENT", "I Miss My Parents" } , - { WE_CALLPARTNER, "CALLPARTNER", "I Want to See You" } , - { WE_FEMALE, "FEMALE", "I Only Look Up to You" } , - { WE_MALE, "MALE", "I Will Protect You" } , - { WS_CARTBOOST, "CARTBOOST", "Cart_Boost" } , - { WS_CREATECOIN, "CREATECOIN", "Create_Coins" } , - { WS_CREATENUGGET, "CREATENUGGET", "Create_Nuggets" } , - { WS_MELTDOWN, "MELTDOWN", "Meltdown" } , - { WS_SYSTEMCREATE, "SYSTEMCREATE", "Create_System_tower" } , - { WS_WEAPONREFINE, "WEAPONREFINE", "Weapon_Refine" } , - { WZ_EARTHSPIKE, "EARTHSPIKE", "Earth_Spike" } , - { WZ_ESTIMATION, "ESTIMATION", "Sense" } , - { WZ_FIREIVY, "FIREIVY", "Fire_Ivy" } , - { WZ_FIREPILLAR, "FIREPILLAR", "Fire_Pillar" } , - { WZ_FROSTNOVA, "FROSTNOVA", "Frost_Nova" } , - { WZ_HEAVENDRIVE, "HEAVENDRIVE", "Heaven's_Drive" } , - { WZ_ICEWALL, "ICEWALL", "Ice_Wall" } , - { WZ_JUPITEL, "JUPITEL", "Jupitel_Thunder" } , - { WZ_METEOR, "METEOR", "Meteor_Storm" } , - { WZ_QUAGMIRE, "QUAGMIRE", "Quagmire" } , - { WZ_SIGHTRASHER, "SIGHTRASHER", "Sightrasher" } , - { WZ_STORMGUST, "STORMGUST", "Storm_Gust" } , - { WZ_VERMILION, "VERMILION", "Lord_of_Vermilion" } , - { WZ_WATERBALL, "WATERBALL", "Water_Ball" } , - { 0, 0, 0 } -}; - -static const int dirx[8]={0,-1,-1,-1,0,1,1,1}; -static const int diry[8]={1,1,0,-1,-1,-1,0,1}; - -static int rdamage; - -/* スキルデ?タベ?ス */ -struct skill_db skill_db[MAX_SKILL_DB]; - -/* アイテム作成デ?タベ?ス */ -struct skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB]; - -/* 矢作成スキルデ?タベ?ス */ -struct skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB]; - -/* アブラカダブラ?動スキルデ?タベ?ス */ -struct skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB]; - -// macros to check for out of bounds errors [celest] -// i: Skill ID, l: Skill Level, var: Value to return after checking -// for values that don't require level just put a one (putting 0 will trigger return 0; instead -// for values that might need to use a different function just skill_chk would suffice. -#define skill_chk(i, l) \ - if (i >= 10000 && i < 10015) {i -= 9500;} \ - if (i < 1 || i > MAX_SKILL_DB) {return 0;} \ - if (l <= 0 || l > MAX_SKILL_LEVEL) {return 0;} -#define skill_get(var, i, l) \ - { skill_chk(i, l); return var; } - -// Skill DB -int skill_get_hit( int id ){ skill_get (skill_db[id].hit, id, 1); } -int skill_get_inf( int id ){ skill_chk (id, 1); return (id < 500) ? skill_db[id].inf : guild_skill_get_inf(id); } -int skill_get_pl( int id ){ skill_get (skill_db[id].pl, id, 1); } -int skill_get_nk( int id ){ skill_get (skill_db[id].nk, id, 1); } -int skill_get_max( int id ){ skill_chk (id, 1); return (id < 500) ? skill_db[id].max : guild_skill_get_max(id); } -int skill_get_range( int id , int lv ){ skill_chk (id, lv); return (id < 500) ? skill_db[id].range[lv-1] : guild_skill_get_range(id); } -int skill_get_hp( int id ,int lv ){ skill_get (skill_db[id].hp[lv-1], id, lv); } -int skill_get_sp( int id ,int lv ){ skill_get (skill_db[id].sp[lv-1], id, lv); } -int skill_get_zeny( int id ,int lv ){ skill_get (skill_db[id].zeny[lv-1], id, lv); } -int skill_get_num( int id ,int lv ){ skill_get (skill_db[id].num[lv-1], id, lv); } -int skill_get_cast( int id ,int lv ){ skill_get (skill_db[id].cast[lv-1], id, lv); } -int skill_get_delay( int id ,int lv ){ skill_get (skill_db[id].delay[lv-1], id, lv); } -int skill_get_time( int id ,int lv ){ skill_get (skill_db[id].upkeep_time[lv-1], id, lv); } -int skill_get_time2( int id ,int lv ){ skill_get (skill_db[id].upkeep_time2[lv-1], id, lv); } -int skill_get_castdef( int id ){ skill_get (skill_db[id].cast_def_rate, id, 1); } -int skill_get_weapontype( int id ){ skill_get (skill_db[id].weapon, id, 1); } -int skill_get_inf2( int id ){ skill_get (skill_db[id].inf2, id, 1); } -int skill_get_castcancel( int id ){ skill_get (skill_db[id].castcancel, id, 1); } -int skill_get_maxcount( int id ){ skill_get (skill_db[id].maxcount, id, 1); } -int skill_get_blewcount( int id ,int lv ){ skill_get (skill_db[id].blewcount[lv-1], id, lv); } -int skill_get_mhp( int id ,int lv ){ skill_get (skill_db[id].mhp[lv-1], id, lv); } -int skill_get_castnodex( int id ,int lv ){ skill_get (skill_db[id].castnodex[lv-1], id, lv); } -int skill_get_delaynodex( int id ,int lv ){ skill_get (skill_db[id].delaynodex[lv-1], id, lv); } -int skill_get_nocast ( int id ){ skill_get (skill_db[id].nocast, id, 1); } -int skill_get_unit_id ( int id, int flag ){ skill_get (skill_db[id].unit_id[flag], id, 1); } -int skill_get_unit_layout_type( int id ,int lv ){ skill_get (skill_db[id].unit_layout_type[lv-1], id, lv); } -int skill_get_unit_interval( int id ){ skill_get (skill_db[id].unit_interval, id, 1); } -int skill_get_unit_range( int id ){ skill_get (skill_db[id].unit_range, id, 1); } -int skill_get_unit_target( int id ){ skill_get (skill_db[id].unit_target, id, 1); } -int skill_get_unit_flag( int id ){ skill_get (skill_db[id].unit_flag, id, 1); } - -int skill_tree_get_max(int id, int b_class){ - struct pc_base_job s_class = pc_calc_base_job(b_class); - int i, skillid; - for(i=0;(skillid=skill_tree[s_class.upper][s_class.job][i].id)>0;i++) - if (id == skillid) return skill_tree[s_class.upper][s_class.job][i].max; - return skill_get_max (id); -} - -/* プロトタイプ */ -//struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,int flag); -int skill_check_condition( struct map_session_data *sd,int type); -int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); -int skill_frostjoke_scream(struct block_list *bl,va_list ap); -int status_change_timer_sub(struct block_list *bl, va_list ap ); -int skill_attack_area(struct block_list *bl,va_list ap); -int skill_clear_element_field(struct block_list *bl); -int skill_landprotector(struct block_list *bl, va_list ap ); -int skill_trap_splash(struct block_list *bl, va_list ap ); -int skill_count_target(struct block_list *bl, va_list ap ); -struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl,struct skill_unit_group *sg,int tick); -int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int tick); -int skill_unit_effect(struct block_list *bl,va_list ap); - -int enchant_eff[5] = { 10, 14, 17, 19, 20 }; -int deluge_eff[5] = { 5, 9, 12, 14, 15 }; - -// [MouseJstr] - skill ok to cast? and when? -int skillnotok(int skillid, struct map_session_data *sd) -{ - nullpo_retr (1, sd); - //if (sd == 0) - //return 0; - //return 1; - // I think it was meant to be "no skills allowed when not a valid sd" - - if (!(skillid >= 10000 && skillid < 10015)) - if ((skillid > MAX_SKILL) || (skillid < 0)) - return 1; - - { - int i = skillid; - if (i >= 10000 && i < 10015) - i -= 9500; - if (sd->blockskill[i] > 0) - return 1; - } - - if (pc_isGM(sd) >= 20) - return 0; // gm's can do anything damn thing they want - - // Check skill restrictions [Celest] - if(!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.gvg && skill_get_nocast (skillid) & 1) - return 1; - if(map[sd->bl.m].flag.pvp && skill_get_nocast (skillid) & 2) - return 1; - if(map[sd->bl.m].flag.gvg && skill_get_nocast (skillid) & 4) - return 1; - if (agit_flag && skill_get_nocast (skillid) & 8) - return 1; - if (battle_config.pk_mode && !map[sd->bl.m].flag.nopvp && skill_get_nocast (skillid) & 16) - return 1; - - switch (skillid) { - case AL_WARP: - case AL_TELEPORT: - case MC_VENDING: - case MC_IDENTIFY: - return 0; // always allowed - default: - return (map[sd->bl.m].flag.noskill); - } -} - - -static int distance(int x0,int y0,int x1,int y1) -{ - int dx,dy; - - dx = abs(x0 - x1); - dy = abs(y0 - y1); - return dx > dy ? dx : dy; -} - -/* スキルユニットの配置情報を返す */ -struct skill_unit_layout skill_unit_layout[MAX_SKILL_UNIT_LAYOUT]; -int firewall_unit_pos; -int icewall_unit_pos; - -struct skill_unit_layout *skill_get_unit_layout (int skillid, int skilllv, struct block_list *src, int x, int y) -{ - int pos = skill_get_unit_layout_type(skillid,skilllv); - int dir; - - if (pos != -1) - return &skill_unit_layout[pos]; - - if (src->x == x && src->y == y) - dir = 2; - else - dir = map_calc_dir(src,x,y); - - if (skillid == MG_FIREWALL) - return &skill_unit_layout [firewall_unit_pos + dir]; - else if (skillid == WZ_ICEWALL) - return &skill_unit_layout [icewall_unit_pos + dir]; - - printf("Unknown unit layout for skill %d, %d\n",skillid,skilllv); - return &skill_unit_layout[0]; -} - -// 0x89,0x8a,0x8b 表示無し -// 0x9a 炎?性の詠唱みたいなエフェクト -// 0x9b 水?性の詠唱みたいなエフェクト -// 0x9c 風?性の詠唱みたいなエフェクト -// 0x9d 白い小さなエフェクト -// 0xb1 Alchemist Demonstration -// 0xb2 = Pink Warp Portal -// 0xb3 = Gospel For Paladin -// 0xb4 = Basilica -// 0xb5 = Empty -// 0xb6 = Fog Wall for Professor -// 0xb7 = Spider Web for Professor -// 0xb8 = Empty -// 0xb9 = - -/*========================================== - * スキル追加?果 - *------------------------------------------ - */ -int skill_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, unsigned int tick) -{ - /* MOB追加?果スキル用 */ - const int sc[]={ - SC_POISON, SC_BLIND, SC_SILENCE, SC_STAN, - SC_STONE, SC_CURSE, SC_SLEEP - }; - const int sc2[]={ - MG_STONECURSE,MG_FROSTDIVER,NPC_STUNATTACK, - NPC_SLEEPATTACK,TF_POISON,NPC_CURSEATTACK, - NPC_SILENCEATTACK,0,NPC_BLINDATTACK - }; - - struct map_session_data *sd=NULL; - struct map_session_data *dstsd=NULL; - struct mob_data *md=NULL; - struct mob_data *dstmd=NULL; - struct pet_data *pd=NULL; - - int skill,skill2; - int rate; - - int sc_def_mdef,sc_def_vit,sc_def_int,sc_def_luk; - int sc_def_mdef2,sc_def_vit2,sc_def_int2,sc_def_luk2; - - nullpo_retr(0, src); - nullpo_retr(0, bl); - - if(skillid < 0) - { // remove the debug print when this case is finished - printf("skill_additional_effect: skillid=%i\ncall: %p %p %i %i %i %i",skillid, - src, bl,skillid,skilllv,attack_type,tick); - return 0; - } - if(skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest - - if (src->type == BL_PC){ - nullpo_retr(0, sd = (struct map_session_data *)src); - } else if (src->type == BL_MOB){ - nullpo_retr(0, md = (struct mob_data *)src); //未使用? - } else if (src->type == BL_PET){ - nullpo_retr(0, pd = (struct pet_data *)src); // [Valaris] - } - - if(bl->type == BL_PC) { - nullpo_retr(0, dstsd=(struct map_session_data *)bl); - } else if(bl->type == BL_MOB) { - nullpo_retr(0, dstmd=(struct mob_data *)bl); //未使用? - } - - //?象の耐性 - sc_def_mdef = status_get_sc_def_mdef(bl); - sc_def_vit = status_get_sc_def_vit(bl); - sc_def_int = status_get_sc_def_int(bl); - sc_def_luk = status_get_sc_def_luk(bl); - - //自分の耐性 - sc_def_mdef2 = status_get_sc_def_mdef(src); - sc_def_vit2 = status_get_sc_def_vit(src); - sc_def_int2 = status_get_sc_def_int(src); - sc_def_luk2 = status_get_sc_def_luk(src); - - switch(skillid){ - case 0: /* 通常攻? */ - /* 自動鷹 */ - if(sd) { - struct status_change *sc_data = status_get_sc_data(bl); - if (pc_isfalcon(sd) && sd->status.weapon == 11 && (skill=pc_checkskill(sd,HT_BLITZBEAT))>0 && - rand()%1000 <= sd->paramc[5]*10/3+1 ) { - int lv=(sd->status.job_level+9)/10; - skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<lv)?skill:lv,tick,0xf00000); - } - // スナッチャ? - if(sd->status.weapon != 11 && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0 && - (skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > rand()%1000) { - if(pc_steal_item(sd,bl)) - clif_skill_nodamage(src,bl,TF_STEAL,skill2,1); - else if (battle_config.display_snatcher_skill_fail) - clif_skill_fail(sd,skillid,0,0); - } - // enchant poison has a chance of poisoning enemy - if (sd->sc_data[SC_ENCPOISON].timer != -1 && sc_data && sc_data[SC_POISON].timer == -1 && - rand() % 100 < sd->sc_data[SC_ENCPOISON].val1 * sc_def_vit / 100) { - status_change_start(bl,SC_POISON,sd->sc_data[SC_ENCPOISON].val1, - 0,0,0,skill_get_time2(AS_ENCHANTPOISON,sd->sc_data[SC_ENCPOISON].val1),0); - } - // エンチャントデットリ?ポイズン(猛毒?果) - if (sd->sc_data[SC_EDP].timer != -1 && sc_data && sc_data[SC_DPOISON].timer == -1 && - rand() % 100 < sd->sc_data[SC_EDP].val2 * sc_def_vit / 100) - status_change_start(bl,SC_DPOISON,sd->sc_data[SC_EDP].val1, - 0,0,0,skill_get_time2(ASC_EDP,sd->sc_data[SC_EDP].val1),0); - } - break; - - case SM_BASH: /* バッシュ(急所攻?) */ - if( sd && (skill=pc_checkskill(sd,SM_FATALBLOW))>0 ){ - if( rand()%100 < 6*(skilllv-5)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0); - } - break; - - case TF_POISON: /* インベナム */ - case AS_SPLASHER: /* ベナムスプラッシャ? */ - if(rand()%100< (2*skilllv+10)*sc_def_vit/100 ) - status_change_start(bl,SC_POISON,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - else{ - if(sd && skillid==TF_POISON) - clif_skill_fail(sd,skillid,0,0); - } - break; - - case AS_SONICBLOW: /* ソニックブロ? */ - if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case AS_GRIMTOOTH: - if (bl->type == BL_MOB) { - struct status_change *sc_data = status_get_sc_data(bl); - if (sc_data && sc_data[SC_SLOWDOWN].timer == -1) - status_change_start(bl,SC_SLOWDOWN,0,0,0,0,1000,0); - } - break; - - case HT_FREEZINGTRAP: /* フリ?ジングトラップ */ - rate=skilllv*3+35; - if(rand()%100 < rate*sc_def_mdef/100) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case MG_FROSTDIVER: /* フロストダイバ? */ - case WZ_FROSTNOVA: /* フロストノヴァ */ - { - struct status_change *sc_data = status_get_sc_data(bl); - rate = (skilllv*3+35)*sc_def_mdef/100-(status_get_int(bl)+status_get_luk(bl))/15; - if (rate <= 5) - rate = 5; - if(sc_data && sc_data[SC_FREEZE].timer == -1 && rand()%100 < rate) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv)*(1-sc_def_mdef/100),0); - else if (sd && skillid == MG_FROSTDIVER) - clif_skill_fail(sd,skillid,0,0); - } - break; - - case WZ_STORMGUST: /* スト?ムガスト */ - { - struct status_change *sc_data = status_get_sc_data(bl); - if(sc_data) { - sc_data[SC_FREEZE].val3++; - if(sc_data[SC_FREEZE].val3 >= 3) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - } - } - break; - - case HT_LANDMINE: /* ランドマイン */ - if( rand()%100 < (5*skilllv+30)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case HT_SHOCKWAVE: /* ショックウェ?ブトラップ */ - if(map[bl->m].flag.pvp && dstsd){ - dstsd->status.sp -= dstsd->status.sp*(5+15*skilllv)/100; - status_calc_pc(dstsd,0); - } - break; - case HT_SANDMAN: /* サンドマン */ - if( rand()%100 < (5*skilllv+30)*sc_def_int/100 ) - status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case TF_SPRINKLESAND: /* 砂まき */ - if( rand()%100 < 20*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case TF_THROWSTONE: /* 石投げ */ - if( rand()%100 < 7*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case CR_HOLYCROSS: /* ホ?リ?クロス */ - if( rand()%100 < 3*skilllv*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case CR_GRANDCROSS: /* グランドクロス */ - case NPC_DARKGRANDCROSS: /*闇グランドクロス*/ - { - int race = status_get_race(bl); - if( (battle_check_undead(race,status_get_elem_type(bl)) || race == 6) && rand()%100 < 100000*sc_def_int/100) //?制付?だが完全耐性には無? - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - } - break; - - case AM_ACIDTERROR: - if( rand()%100 < (skilllv*3)*sc_def_vit/100 ) - status_change_start(bl,SC_BLEEDING,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case CR_SHIELDCHARGE: /* シ?ルドチャ?ジ */ - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case RG_RAID: /* サプライズアタック */ - if( rand()%100 < (10+3*skilllv)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if( rand()%100 < (10+3*skilllv)*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case BA_FROSTJOKE: - if(rand()%100 < (15+5*skilllv)*sc_def_mdef/100) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case DC_SCREAM: - if( rand()%100 < (25+5*skilllv)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case BD_LULLABY: /* 子守唄 */ - if( rand()%100 < 15*sc_def_int/100 ) - status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - /* MOBの追加?果付きスキル */ - - case NPC_PETRIFYATTACK: - if(rand()%100 < sc_def_mdef) - status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case NPC_POISON: - case NPC_SILENCEATTACK: - case NPC_STUNATTACK: - if(rand()%100 < sc_def_vit && src->type!=BL_PET) - status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if(src->type==BL_PET) - status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skilllv*1000,0); - break; - case NPC_CURSEATTACK: - if(rand()%100 < sc_def_luk) - status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case NPC_SLEEPATTACK: - case NPC_BLINDATTACK: - if(rand()%100 < sc_def_int) - status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case NPC_MENTALBREAKER: - if(dstsd) { - int sp = dstsd->status.max_sp*(10+skilllv)/100; - if(sp < 1) sp = 1; - pc_heal(dstsd,0,-sp); - } - break; - -// -- moonsoul (adding status effect chance given to wizard aoe skills meteor and vermillion) -// - case WZ_METEOR: - if(rand()%100 < sc_def_vit) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case WZ_VERMILION: - if(rand()%100 < sc_def_int) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - -// -- moonsoul (stun ability of new champion skill tigerfist) -// - case CH_TIGERFIST: - if (rand()%100 < (10 + skilllv*10)*sc_def_vit/100) { - int sec = skill_get_time2 (skillid,skilllv) - status_get_agi(bl)/10; - if (dstsd) { - dstsd->canmove_tick += sec; - dstsd->canact_tick += sec; - } else if (dstmd) - dstmd->canmove_tick += sec; - } - break; - - case LK_SPIRALPIERCE: - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case ST_REJECTSWORD: /* フリ?ジングトラップ */ - if( rand()%100 < (skilllv*15) ) - status_change_start(bl,SC_AUTOCOUNTER,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case PF_FOGWALL: /* ホ?リ?クロス */ - if (src != bl) { - struct status_change *sc_data = status_get_sc_data(bl); - if (sc_data && sc_data[SC_DELUGE].timer == -1) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - } - break; - case LK_HEADCRUSH: /* ヘッドクラッシュ */ - {//?件が良く分からないので適?に - int race=status_get_race(bl); - if( !(battle_check_undead(race,status_get_elem_type(bl)) || race == 6) && rand()%100 < (2*skilllv+10)*sc_def_vit/100 ) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - } - break; - case LK_JOINTBEAT: /* ジョイントビ?ト */ - //?件が良く分からないので適?に - if( rand()%100 < (5*skilllv+5)*sc_def_vit/100 ) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case PF_SPIDERWEB: /* スパイダ?ウェッブ */ - { - int sec = skill_get_time2(skillid,skilllv); - if(map[src->m].flag.pvp) //PvPでは拘束時間半減? - sec = sec/2; - battle_stopwalking(bl,1); - status_change_start(bl,SC_SPIDERWEB,skilllv,0,0,0,sec,0); - } - break; - case ASC_METEORASSAULT: /* メテオアサルト */ - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) //?態異常は詳細が分からないので適?に - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if( rand()%100 < (10+3*skilllv)*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case MO_EXTREMITYFIST: /* 阿修羅覇凰拳 */ - //阿修羅を使うと5分間自然回復しないようになる - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 ); - break; - case HW_NAPALMVULCAN: /* ナパ?ムバルカン */ - // skilllv*5%の確率で呪い - if (rand()%10000 < 5*skilllv*sc_def_luk) - status_change_start(bl,SC_CURSE,7,0,0,0,skill_get_time2(NPC_CURSEATTACK,7),0); - break; - } - - if((sd||dstsd) && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */ - int i, type; - int sc_def_card=100; - - for(i=SC_STONE;i<=SC_BLIND;i++){ - type=i-SC_STONE; - //?象に?態異常 - switch (i) { - case SC_STONE: - case SC_FREEZE: - sc_def_card=sc_def_mdef; - break; - case SC_STAN: - case SC_POISON: - case SC_SILENCE: - sc_def_card=sc_def_vit; - break; - case SC_SLEEP: - case SC_CONFUSION: - case SC_BLIND: - sc_def_card=sc_def_int; - break; - case SC_CURSE: - sc_def_card=sc_def_luk; - } - - if (sd) { - if(!sd->state.arrow_atk) { - if(rand()%10000 < (sd->addeff[type])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",sd->bl.id,i,sd->addeff[type]); - status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0); - } - } - else { - if(rand()%10000 < (sd->addeff[type]+sd->arrow_addeff[type])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",sd->bl.id,i,sd->addeff[type]); - status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0); - } - } - } - //自分に?態異常 - switch (i) { - case SC_STONE: - case SC_FREEZE: - sc_def_card=sc_def_mdef2; - break; - case SC_STAN: - case SC_POISON: - case SC_SILENCE: - sc_def_card=sc_def_vit2; - break; - case SC_SLEEP: - case SC_CONFUSION: - case SC_BLIND: - sc_def_card=sc_def_int2; - break; - case SC_CURSE: - sc_def_card=sc_def_luk2; - } - - if (sd) { - if(!sd->state.arrow_atk) { - if(rand()%10000 < (sd->addeff2[type])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,sd->addeff2[type]); - status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0); - } - } - else { - if(rand()%10000 < (sd->addeff2[type]+sd->arrow_addeff2[type])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,sd->addeff2[type]); - status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0); - } - } - } - if (dstsd && rand()%10000 < dstsd->addeff3[type]*sc_def_card/100){ - if (dstsd->addeff3_type[type] != 1 && ((sd && !sd->state.arrow_atk) || (status_get_range(src)<=2))) - continue; - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,dstsd->addeff3[type]); - status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0); - } - } - } - return 0; -} - -/*========================================================================= - スキル攻?吹き飛ばし?理 --------------------------------------------------------------------------*/ -int skill_blown( struct block_list *src, struct block_list *target,int count) -{ - int dx=0,dy=0,nx,ny; - int x=target->x,y=target->y; - int dir,ret,prev_state=MS_IDLE; - int moveblock; - struct map_session_data *sd=NULL; - struct mob_data *md=NULL; - struct pet_data *pd=NULL; - struct skill_unit *su=NULL; - - nullpo_retr(0, src); - nullpo_retr(0, target); - - if(target->type==BL_PC){ - sd=(struct map_session_data *)target; - }else if(target->type==BL_MOB){ - md=(struct mob_data *)target; - }else if(target->type==BL_PET){ - pd=(struct pet_data *)target; - }else if(target->type==BL_SKILL){ - su=(struct skill_unit *)target; - }else return 0; - - if (count&0xf00000) - dir = (count>>20)&0xf; - else if (count&0x10000 || (target->x==src->x && target->y==src->y)) - dir = status_get_dir(target); - else - dir = map_calc_dir(target,src->x,src->y); - if (dir>=0 && dir<8){ - dx = -dirx[dir]; - dy = -diry[dir]; - } - - ret=path_blownpos(target->m,x,y,dx,dy,count&0xffff); - nx=ret>>16; - ny=ret&0xffff; - moveblock=( x/BLOCK_SIZE != nx/BLOCK_SIZE || y/BLOCK_SIZE != ny/BLOCK_SIZE); - - if(count&0x20000) { - battle_stopwalking(target,1); - if(sd){ - sd->to_x=nx; - sd->to_y=ny; - sd->walktimer = 1; - clif_walkok(sd); - clif_movechar(sd); - } - else if(md) { - md->to_x=nx; - md->to_y=ny; - prev_state = md->state.state; - md->state.state = MS_WALK; - clif_fixmobpos(md); - } - else if(pd) { - pd->to_x=nx; - pd->to_y=ny; - prev_state = pd->state.state; - pd->state.state = MS_WALK; - clif_fixpetpos(pd); - } - } - else - battle_stopwalking(target,2); - - dx = nx - x; - dy = ny - y; - - if(sd) /* ?面外に出たので消去 */ - map_foreachinmovearea(clif_pcoutsight,target->m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,0,sd); - else if(md) - map_foreachinmovearea(clif_moboutsight,target->m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,md); - else if(pd) - map_foreachinmovearea(clif_petoutsight,target->m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,pd); - - if(su){ - skill_unit_move_unit_group(su->group,target->m,dx,dy); - }else{ - int tick = gettick(); - skill_unit_move(target,tick,0); - if(moveblock) map_delblock(target); - target->x=nx; - target->y=ny; - if(moveblock) map_addblock(target); - skill_unit_move(target,tick,1); - } - - if(sd) { /* ?面?に入ってきたので表示 */ - map_foreachinmovearea(clif_pcinsight,target->m,nx-AREA_SIZE,ny-AREA_SIZE,nx+AREA_SIZE,ny+AREA_SIZE,-dx,-dy,0,sd); - if(count&0x20000) - sd->walktimer = -1; - } - else if(md) { - map_foreachinmovearea(clif_mobinsight,target->m,nx-AREA_SIZE,ny-AREA_SIZE,nx+AREA_SIZE,ny+AREA_SIZE,-dx,-dy,BL_PC,md); - if(count&0x20000) - md->state.state = prev_state; - } - else if(pd) { - map_foreachinmovearea(clif_petinsight,target->m,nx-AREA_SIZE,ny-AREA_SIZE,nx+AREA_SIZE,ny+AREA_SIZE,-dx,-dy,BL_PC,pd); - if(count&0x20000) - pd->state.state = prev_state; - } - - return 0; -} - - -/* - * ========================================================================= - * スキル攻??果?理まとめ - * flagの?明。16進? - * 00XRTTff - * ff = magicで計算に渡される) - * TT = パケットのtype部分(0でデフォルト) - * X = パケットのスキルLv - * R = 予約(skill_area_subで使用する) - *------------------------------------------------------------------------- - */ - -int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc, - struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ) -{ - struct Damage dmg; - struct status_change *sc_data; - int type,lv,damage; - static int tmpdmg = 0; - - if(skillid > 0 && skilllv <= 0) return 0; - - rdamage = 0; - nullpo_retr(0, src); - nullpo_retr(0, dsrc); - nullpo_retr(0, bl); - - sc_data = status_get_sc_data(bl); - -//何もしない判定ここから - if(dsrc->m != bl->m) //?象が同じマップにいなければ何もしない - return 0; - if(src->prev == NULL || dsrc->prev == NULL || bl->prev == NULL) //prevよくわからない※ - return 0; - if(src->type == BL_PC && pc_isdead((struct map_session_data *)src)) //術者?がPCですでに死んでいたら何もしない - return 0; - if(src != dsrc && dsrc->type == BL_PC && pc_isdead((struct map_session_data *)dsrc)) //術者?がPCですでに死んでいたら何もしない - return 0; - if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl)) //?象がPCですでに死んでいたら何もしない - return 0; - if(bl->type == BL_PC && skillnotok(skillid, (struct map_session_data *)bl)) - return 0; // [MouseJstr] - if(sc_data && sc_data[SC_HIDING].timer != -1) { //ハイディング?態で - if(skill_get_pl(skillid) != 2) //スキルの?性が地?性でなければ何もしない - return 0; - } - if(sc_data && sc_data[SC_TRICKDEAD].timer != -1) //死んだふり中は何もしない - return 0; - if(skillid == WZ_STORMGUST) { //使用スキルがスト?ムガストで - if(sc_data && sc_data[SC_FREEZE].timer != -1) //凍結?態なら何もしない - return 0; - } - if(skillid == WZ_FROSTNOVA && dsrc->x == bl->x && dsrc->y == bl->y) //使用スキルがフロストノヴァで、dsrcとblが同じ場所なら何もしない - return 0; - if(src->type == BL_PC && ((struct map_session_data *)src)->chatID) //術者がPCでチャット中なら何もしない - return 0; - if(dsrc->type == BL_PC && ((struct map_session_data *)dsrc)->chatID) //術者がPCでチャット中なら何もしない - return 0; - if(src->type == BL_PC && bl && mob_gvmobcheck(((struct map_session_data *)src),bl)==0) - return 0; - -//何もしない判定ここまで - - type=-1; - lv=(flag>>20)&0xf; - dmg=battle_calc_attack(attack_type,src,bl,skillid,skilllv,flag&0xff ); //ダメ?ジ計算 - -//マジックロッド?理ここから - if(attack_type&BF_MAGIC && sc_data && sc_data[SC_MAGICROD].timer != -1 && src == dsrc) { //魔法攻?でマジックロッド?態でsrc=dsrcなら - dmg.damage = dmg.damage2 = 0; //ダメ?ジ0 - if(bl->type == BL_PC) { //?象がPCの場合 - struct map_session_data *sd = (struct map_session_data *)bl; - if (sd) { - int sp = skill_get_sp(skillid,skilllv); //使用されたスキルのSPを吸? - sp = sp * sc_data[SC_MAGICROD].val2 / 100; //吸?率計算 - if(skillid == WZ_WATERBALL && skilllv > 1) //ウォ?タ?ボ?ルLv1以上 - sp = sp/((skilllv|1)*(skilllv|1)); //さらに計算? - if(sp > 0x7fff) sp = 0x7fff; //SP多すぎの場合は理論最大値 - else if(sp < 1) sp = 1; //1以下の場合は1 - if(sd->status.sp + sp > sd->status.max_sp) { //回復SP+現在のSPがMSPより大きい場合 - sp = sd->status.max_sp - sd->status.sp; //SPをMSP-現在SPにする - sd->status.sp = sd->status.max_sp; //現在のSPにMSPを代入 - } - else //回復SP+現在のSPがMSPより小さい場合は回復SPを加算 - sd->status.sp += sp; - clif_heal(sd->fd,SP_SP,sp); //SP回復エフェクトの表示 - sd->canact_tick = tick + skill_delayfix(bl, skill_get_delay(SA_MAGICROD,sc_data[SC_MAGICROD].val1)); // - } - } - clif_skill_nodamage(bl,bl,SA_MAGICROD,sc_data[SC_MAGICROD].val1,1); //マジックロッドエフェクトを表示 - } -//マジックロッド?理ここまで - - if(src->type==BL_PET) { // [Valaris] - dmg.damage=battle_attr_fix(skilllv, skill_get_pl(skillid), status_get_element(bl) ); - dmg.damage2=0; - } - - damage = dmg.damage + dmg.damage2; - - if(lv==15) - lv=-1; - - if( flag&0xff00 ) - type=(flag&0xff00)>>8; - - if(damage <= 0 || damage < dmg.div_) //吹き飛ばし判定?※ - dmg.blewcount = 0; - - if(skillid == CR_GRANDCROSS||skillid == NPC_DARKGRANDCROSS) {//グランドクロス - if(battle_config.gx_disptype) dsrc = src; // 敵ダメ?ジ白文字表示 - if( src == bl) type = 4; // 反動はダメ?ジモ?ションなし - } - -//使用者がPCの場合の?理ここから - if(src->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)src; - nullpo_retr(0, sd); -//連打掌(MO_CHAINCOMBO)ここから - if(skillid == MO_CHAINCOMBO) { - int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); //基本ディレイの計算 - if(damage < status_get_hp(bl)) { //ダメ?ジが?象のHPより小さい場合 - if(pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0) //猛龍拳(MO_COMBOFINISH)取得&?球保持時は+300ms - delay += 300 * battle_config.combo_delay_rate /100; //追加ディレイをconfにより調整 - - status_change_start(src,SC_COMBO,MO_CHAINCOMBO,skilllv,0,0,delay,0); //コンボ?態に - } - sd->attackabletime = sd->canmove_tick = tick + delay; - clif_combo_delay(src,delay); //コンボディレイパケットの送信 - } -//連打掌(MO_CHAINCOMBO)ここまで -//猛龍拳(MO_COMBOFINISH)ここから - else if(skillid == MO_COMBOFINISH) { - int delay = 700 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - if(damage < status_get_hp(bl)) { - //阿修羅覇凰拳(MO_EXTREMITYFIST)取得&?球4個保持&爆裂波動(MO_EXPLOSIONSPIRITS)?態時は+300ms - //伏虎拳(CH_TIGERFIST)取得時も+300ms - if((pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball >= 4 && sd->sc_data[SC_EXPLOSIONSPIRITS].timer != -1) || - (pc_checkskill(sd, CH_TIGERFIST) > 0 && sd->spiritball > 0) || - (pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)) - delay += 300 * battle_config.combo_delay_rate /100; //追加ディレイをconfにより調整 - - status_change_start(src,SC_COMBO,MO_COMBOFINISH,skilllv,0,0,delay,0); //コンボ?態に - } - sd->attackabletime = sd->canmove_tick = tick + delay; - clif_combo_delay(src,delay); //コンボディレイパケットの送信 - } -//猛龍拳(MO_COMBOFINISH)ここまで -//伏虎拳(CH_TIGERFIST)ここから - else if(skillid == CH_TIGERFIST) { - int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - if(damage < status_get_hp(bl)) { - if(pc_checkskill(sd, CH_CHAINCRUSH) > 0) //連柱崩?(CH_CHAINCRUSH)取得時は+300ms - delay += 300 * battle_config.combo_delay_rate /100; //追加ディレイをconfにより調整 - - status_change_start(src,SC_COMBO,CH_TIGERFIST,skilllv,0,0,delay,0); //コンボ?態に - } - sd->attackabletime = sd->canmove_tick = tick + delay; - clif_combo_delay(src,delay); //コンボディレイパケットの送信 - } -//伏虎拳(CH_TIGERFIST)ここまで -//連柱崩?(CH_CHAINCRUSH)ここから - else if(skillid == CH_CHAINCRUSH) { - int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - if(damage < status_get_hp(bl)) { - //阿修羅覇凰拳(MO_EXTREMITYFIST)取得&?球4個保持&爆裂波動(MO_EXPLOSIONSPIRITS)?態時は+300ms - if(pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball >= 4 && sd->sc_data[SC_EXPLOSIONSPIRITS].timer != -1) - delay += 300 * battle_config.combo_delay_rate /100; //追加ディレイをconfにより調整 - - status_change_start(src,SC_COMBO,CH_CHAINCRUSH,skilllv,0,0,delay,0); //コンボ?態に - } - sd->attackabletime = sd->canmove_tick = tick + delay; - clif_combo_delay(src,delay); //コンボディレイパケットの送信 - } -//連柱崩?(CH_CHAINCRUSH)ここまで - } -//使用者がPCの場合の?理ここまで -//武器スキル?ここから - //AppleGirl Was Here - if(attack_type&BF_MAGIC && damage > 0 && src != bl && src == dsrc) { //Blah Blah - if(bl->type == BL_PC) { //Blah Blah - struct map_session_data *tsd = (struct map_session_data *)bl; - if(tsd->magic_damage_return > 0) { //More Blah - rdamage += damage * tsd->magic_damage_return / 100; - if(rdamage < 1) rdamage = 1; - } - } - } - //Stop Here - if(attack_type&BF_WEAPON && damage > 0 && src != bl && src == dsrc) { //武器スキル&ダメ?ジあり&使用者と?象者が違う&src=dsrc - if(dmg.flag&BF_SHORT) { //近距離攻?時?※ - if(bl->type == BL_PC) { //?象がPCの時 - struct map_session_data *tsd = (struct map_session_data *)bl; - nullpo_retr(0, tsd); - if(tsd->short_weapon_damage_return > 0) { //近距離攻?跳ね返し?※ - rdamage += damage * tsd->short_weapon_damage_return / 100; - if(rdamage < 1) rdamage = 1; - } - } - if(sc_data && sc_data[SC_REFLECTSHIELD].timer != -1) { //リフレクトシ?ルド時 - rdamage += damage * sc_data[SC_REFLECTSHIELD].val2 / 100; //跳ね返し計算 - if(rdamage < 1) rdamage = 1; - } - } - else if(dmg.flag&BF_LONG) { //遠距離攻?時?※ - if(bl->type == BL_PC) { //?象がPCの時 - struct map_session_data *tsd = (struct map_session_data *)bl; - nullpo_retr(0, tsd); - if(tsd->long_weapon_damage_return > 0) { //遠距離攻?跳ね返し?※ - rdamage += damage * tsd->long_weapon_damage_return / 100; - if(rdamage < 1) rdamage = 1; - } - } - } - if(rdamage > 0) - clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); - } -//武器スキル?ここまで - - switch(skillid){ - case AS_SPLASHER: - clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5); - break; - case ASC_BREAKER: // [celest] - if (attack_type&BF_MAGIC) { // only display damage for the 2nd attack - if (damage + tmpdmg != 0) // if both attacks missed, do not display a 2nd 'miss' - clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, damage+tmpdmg, dmg.div_, skillid, skilllv, type); - tmpdmg = 0; // clear the temporary damage - } else { - if (damage == 0) // if weapon attack missed, display the 'miss' - clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, 0, dmg.div_, skillid, skilllv, type); - tmpdmg = damage; // store the temporary weapon damage - } - break; - case NPC_SELFDESTRUCTION: - case NPC_SELFDESTRUCTION2: - break; - case SN_SHARPSHOOTING: - clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,0,0,0); - break; - default: - clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, (skillid==0)? 5:type ); - } - /* 吹き飛ばし処理とそのパケット */ - if (dmg.blewcount > 0 && bl->type!=BL_SKILL && !map[src->m].flag.gvg) { - skill_blown(dsrc,bl,dmg.blewcount); - if(bl->type == BL_MOB) - clif_fixmobpos((struct mob_data *)bl); - else if(bl->type == BL_PET) - clif_fixpetpos((struct pet_data *)bl); - else - clif_fixpos(bl); - } - - map_freeblock_lock(); - /* ?際にダメ?ジ?理を行う */ - if (skillid || flag) { - if (attack_type&BF_WEAPON) - battle_delay_damage(tick+dmg.amotion,src,bl,damage,0); - else - battle_damage(src,bl,damage,0); - } - if(skillid == RG_INTIMIDATE && damage > 0 && !(status_get_mode(bl)&0x20) && !map[src->m].flag.gvg ) { - int s_lv = status_get_lv(src),t_lv = status_get_lv(bl); - int rate = 50 + skilllv * 5; - rate = rate + (s_lv - t_lv); - if(rand()%100 < rate) - skill_addtimerskill(src,tick + 800,bl->id,0,0,skillid,skilllv,0,flag); - } - if(damage > 0 && dmg.flag&BF_SKILL && bl->type==BL_PC && pc_checkskill((struct map_session_data *)bl,RG_PLAGIARISM) && sc_data[SC_PRESERVE].timer == -1){ - struct map_session_data *tsd = (struct map_session_data *)bl; - nullpo_retr(0, tsd); - if(!tsd->status.skill[skillid].id && !tsd->status.skill[skillid].lv - && !(skillid > NPC_PIERCINGATT && skillid < NPC_SUMMONMONSTER) - && !(skillid > NPC_SELFDESTRUCTION2 && skillid < NPC_UNDEADATTACK)){ - //?に?んでいるスキルがあれば該?スキルを消す - if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag==13){ - tsd->status.skill[tsd->cloneskill_id].id=0; - tsd->status.skill[tsd->cloneskill_id].flag=0; - } - tsd->cloneskill_id=skillid; - tsd->status.skill[skillid].id=skillid; - tsd->status.skill[skillid].lv=(pc_checkskill(tsd,RG_PLAGIARISM) > skill_get_max(skillid))? - skill_get_max(skillid):pc_checkskill(tsd,RG_PLAGIARISM); - tsd->status.skill[skillid].flag=13;//cloneskill flag - clif_skillinfoblock(tsd); - } - } - /* ダメ?ジがあるなら追加?果判定 */ - if(bl->prev != NULL){ - if(!status_isdead(bl)) { - if(damage > 0) - skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick); - if(bl->type==BL_MOB && src!=bl) /* スキル使用?件のMOBスキル */ - { - struct mob_data *md=(struct mob_data *)bl; - nullpo_retr(0, md); - if(battle_config.mob_changetarget_byskill == 1) - { - int target; - target=md->target_id; - if(src->type == BL_PC) - md->target_id=src->id; - mobskill_use(md,tick,MSC_SKILLUSED|(skillid<<16)); - md->target_id=target; - } - else - mobskill_use(md,tick,MSC_SKILLUSED|(skillid<<16)); - } - } - } - - if(src->type == BL_PC && dmg.flag&BF_WEAPON && src != bl && src == dsrc && damage > 0) { - struct map_session_data *sd = (struct map_session_data *)src; - int hp = 0,sp = 0; - nullpo_retr(0, sd); - if(sd->hp_drain_rate && sd->hp_drain_per > 0 && dmg.damage > 0 && rand()%100 < sd->hp_drain_rate) { - hp += (dmg.damage * sd->hp_drain_per)/100; - if(sd->hp_drain_rate > 0 && hp < 1) hp = 1; - else if(sd->hp_drain_rate < 0 && hp > -1) hp = -1; - } - if(sd->hp_drain_rate_ && sd->hp_drain_per_ > 0 && dmg.damage2 > 0 && rand()%100 < sd->hp_drain_rate_) { - hp += (dmg.damage2 * sd->hp_drain_per_)/100; - if(sd->hp_drain_rate_ > 0 && hp < 1) hp = 1; - else if(sd->hp_drain_rate_ < 0 && hp > -1) hp = -1; - } - if(sd->sp_drain_rate > 0 && sd->sp_drain_per > 0 && dmg.damage > 0 && rand()%100 < sd->sp_drain_rate) { - sp += (dmg.damage * sd->sp_drain_per)/100; - if(sd->sp_drain_rate > 0 && sp < 1) sp = 1; - else if(sd->sp_drain_rate < 0 && sp > -1) sp = -1; - } - if(sd->sp_drain_rate_ > 0 && sd->sp_drain_per_ > 0 && dmg.damage2 > 0 && rand()%100 < sd->sp_drain_rate_) { - sp += (dmg.damage2 * sd->sp_drain_per_)/100; - if(sd->sp_drain_rate_ > 0 && sp < 1) sp = 1; - else if(sd->sp_drain_rate_ < 0 && sp > -1) sp = -1; - } - if(hp || sp) - pc_heal(sd,hp,sp); - if (sd->sp_drain_type && bl->type == BL_PC) - battle_heal(NULL,bl,0,-sp,0); - } - - if ((skillid || flag) && rdamage>0) { - if (attack_type&BF_WEAPON) - battle_delay_damage(tick+dmg.amotion,bl,src,rdamage,0); - else - battle_damage(bl,src,rdamage,0); - } - - if(attack_type&BF_WEAPON && sc_data && sc_data[SC_AUTOCOUNTER].timer != -1 && sc_data[SC_AUTOCOUNTER].val4 > 0) { - if(sc_data[SC_AUTOCOUNTER].val3 == dsrc->id) - battle_weapon_attack(bl,dsrc,tick,0x8000|sc_data[SC_AUTOCOUNTER].val1); - status_change_end(bl,SC_AUTOCOUNTER,-1); - } - - map_freeblock_unlock(); - - return (dmg.damage+dmg.damage2); /* ?ダメを返す */ -} - -/*========================================== - * スキル範?攻?用(map_foreachinareaから呼ばれる) - * flagについて:16進?を確認 - * MSB <- 00fTffff ->LSB - * T =タ?ゲット選?用(BCT_*) - * ffff=自由に使用可能 - * 0 =予約。0に固定 - *------------------------------------------ - */ -static int skill_area_temp[8]; /* 一時??。必要なら使う。 */ -typedef int (*SkillFunc)(struct block_list *,struct block_list *,int,int,unsigned int,int); -int skill_area_sub( struct block_list *bl,va_list ap ) -{ - struct block_list *src; - int skill_id,skill_lv,flag; - unsigned int tick; - SkillFunc func; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - if(bl->type!=BL_PC && bl->type!=BL_MOB && bl->type!=BL_SKILL) - return 0; - - src=va_arg(ap,struct block_list *); //ここではsrcの値を?照していないのでNULLチェックはしない - skill_id=va_arg(ap,int); - skill_lv=va_arg(ap,int); - tick=va_arg(ap,unsigned int); - flag=va_arg(ap,int); - func=va_arg(ap,SkillFunc); - - if(battle_check_target(src,bl,flag) > 0) - func(src,bl,skill_id,skill_lv,tick,flag); - return 0; -} - -static int skill_check_unit_range_sub( struct block_list *bl,va_list ap ) -{ - struct skill_unit *unit; - int *c; - int skillid,unit_id; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, unit = (struct skill_unit *)bl); - nullpo_retr(0, c = va_arg(ap,int *)); - - if(bl->prev == NULL || bl->type != BL_SKILL) - return 0; - - if(!unit->alive) - return 0; - - skillid = va_arg(ap,int); - unit_id = unit->group->unit_id; - - if (skillid==MG_SAFETYWALL || skillid==AL_PNEUMA) { - if(unit_id != 0x7e && unit_id != 0x85) - return 0; - } else if (skillid==AL_WARP) { - if ((unit_id<0x8f || unit_id>0x99) && unit_id!=0x92) - return 0; - } else if ((skillid>=HT_SKIDTRAP && skillid<=HT_CLAYMORETRAP) || skillid==HT_TALKIEBOX) { - if ((unit_id<0x8f || unit_id>0x99) && unit_id!=0x92) - return 0; - } else if (skillid==WZ_FIREPILLAR) { - if (unit_id!=0x87) - return 0; - } else if (skillid==HP_BASILICA) { - if ((unit_id<0x8f || unit_id>0x99) && unit_id!=0x92 && unit_id!=0x83) - return 0; - } else - return 0; - - (*c)++; - - return 0; -} - -int skill_check_unit_range(int m,int x,int y,int skillid,int skilllv) -{ - int c = 0; - int range = skill_get_unit_range(skillid); - int layout_type = skill_get_unit_layout_type(skillid,skilllv); - if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) { - printf("skill_check_unit_range: unsupported layout type %d for skill %d\n",layout_type,skillid); - return 0; - } - - // とりあえず正方形のユニットレイアウトのみ対応 - range += layout_type; - map_foreachinarea(skill_check_unit_range_sub,m, - x-range,y-range,x+range,y+range,BL_SKILL,&c,skillid); - - return c; -} - -static int skill_check_unit_range2_sub( struct block_list *bl,va_list ap ) -{ - int *c; - int skillid; - - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, c = va_arg(ap,int *)); - - if(bl->prev == NULL || (bl->type != BL_PC && bl->type != BL_MOB)) - return 0; - - if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl)) - return 0; - - skillid = va_arg(ap,int); - if (skillid==HP_BASILICA && bl->type==BL_PC) - return 0; - - (*c)++; - - return 0; -} - -int skill_check_unit_range2(struct block_list *bl, int m,int x,int y,int skillid, int skilllv) -{ - int c = 0, range, type; - - switch (skillid) { // to be expanded later - case WZ_ICEWALL: - range = 2; - break; - default: - { - int layout_type = skill_get_unit_layout_type(skillid,skilllv); - if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) { - printf("skill_check_unit_range2: unsupported layout type %d for skill %d\n",layout_type,skillid); - return 0; - } - // とりあえず正方形のユニットレイアウトのみ対応 - range = skill_get_unit_range(skillid) + layout_type; - } - break; - } - - // if the caster is a monster/NPC, only check for players - // otherwise just check everything - if (bl->type == BL_PC) - type = 0; - else type = BL_PC; - - map_foreachinarea(skill_check_unit_range2_sub, m, - x - range, y - range, x + range, y + range, - type, &c, skillid); - - return c; -} - -int skill_guildaura_sub (struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - struct guild *g; - int gid, id; - int flag = 0; - - nullpo_retr(0, sd=(struct map_session_data *)bl); - - nullpo_retr(0, ap); - id = va_arg(ap,int); - gid = va_arg(ap,int); - if (sd->status.guild_id != gid) - return 0; - - g = va_arg(ap,struct guild *); - if (guild_checkskill(g, GD_LEADERSHIP)>0) flag |= 1<<0; - if (guild_checkskill(g, GD_GLORYWOUNDS)>0) flag |= 1<<1; - if (guild_checkskill(g, GD_SOULCOLD)>0) flag |= 1<<2; - if (guild_checkskill(g, GD_HAWKEYES)>0) flag |= 1<<3; - if (guild_checkskill(g, GD_CHARISMA)>0) flag |= 1<<4; - - if (flag > 0) { - if (sd->sc_count && sd->sc_data[SC_GUILDAURA].timer != -1) { - if (sd->sc_data[SC_GUILDAURA].val4 != flag) { - sd->sc_data[SC_GUILDAURA].val4 = flag; - status_calc_pc (sd, 0); - } - return 0; - } - status_change_start(&sd->bl, SC_GUILDAURA,1,id,0,flag,0,0 ); - } - - return 0; -} - -/*========================================================================= - * 範?スキル使用?理小分けここから - */ -/* ?象の?をカウントする。(skill_area_temp[0]を初期化しておくこと) */ -int skill_area_sub_count(struct block_list *src,struct block_list *target,int skillid,int skilllv,unsigned int tick,int flag) -{ - if(skill_area_temp[0] < 0xffff) - skill_area_temp[0]++; - return 0; -} - -int skill_count_water(struct block_list *src,int range) -{ - int i,x,y,cnt = 0,size = range*2+1; - struct skill_unit *unit; - - for (i=0;i<size*size;i++) { - x = src->x+(i%size-range); - y = src->y+(i/size-range); - if (map_getcell(src->m,x,y,CELL_CHKWATER)) { - cnt++; - continue; - } - unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL); - if (unit) { - cnt++; - skill_delunit(unit); - } - } - return cnt; -} - -/*========================================== - * - *------------------------------------------ - */ -static int skill_timerskill(int tid, unsigned int tick, int id,int data ) -{ - struct map_session_data *sd = NULL; - struct mob_data *md = NULL; - struct pet_data *pd = NULL; - struct block_list *src = map_id2bl(id),*target; - struct skill_timerskill *skl = NULL; - int range; - - nullpo_retr(0, src); - - if(src->prev == NULL) - return 0; - - if(src->type == BL_PC) { - nullpo_retr(0, sd = (struct map_session_data *)src); - skl = &sd->skilltimerskill[data]; - } - else if(src->type == BL_MOB) { - nullpo_retr(0, md = (struct mob_data *)src); - skl = &md->skilltimerskill[data]; - } - else if(src->type == BL_PET) { // [Valaris] - nullpo_retr(0, pd = (struct pet_data *)src); - skl = &pd->skilltimerskill[data]; - } - - else - return 0; - - nullpo_retr(0, skl); - - skl->timer = -1; - if (sd) { - sd->timerskill_count--; - } - - if(skl->target_id) { - struct block_list tbl; - target = map_id2bl(skl->target_id); - if(skl->skill_id == RG_INTIMIDATE) { - if(target == NULL) { - target = &tbl; //初期化してないのにアドレス突っ?んでいいのかな? - target->type = BL_NUL; - target->m = src->m; - target->prev = target->next = NULL; - } - } - if(target == NULL) - return 0; - if(target->prev == NULL && skl->skill_id != RG_INTIMIDATE) - return 0; - if(src->m != target->m) - return 0; - if(sd && pc_isdead(sd)) - return 0; - if(target->type == BL_PC && pc_isdead((struct map_session_data *)target) && skl->skill_id != RG_INTIMIDATE) - return 0; - - switch(skl->skill_id) { - case TF_BACKSLIDING: - clif_skill_nodamage(src,src,skl->skill_id,skl->skill_lv,1); - break; - case RG_INTIMIDATE: - if(sd && !map[src->m].flag.noteleport) { - int x,y,i,j; - pc_randomwarp(sd,3); - for(i=0;i<16;i++) { - j = rand()%8; - x = sd->bl.x + dirx[j]; - y = sd->bl.y + diry[j]; - if(map_getcell(sd->bl.m,x,y,CELL_CHKPASS)) - break; - } - if(i >= 16) { - x = sd->bl.x; - y = sd->bl.y; - } - if(target->prev != NULL) { - if(target->type == BL_PC && !pc_isdead((struct map_session_data *)target)) - pc_setpos((struct map_session_data *)target,map[sd->bl.m].name,x,y,3); - else if(target->type == BL_MOB) - mob_warp((struct mob_data *)target,-1,x,y,3); - } - } - else if(md && !map[src->m].flag.monster_noteleport) { - int x,y,i,j; - mob_warp(md,-1,-1,-1,3); - for(i=0;i<16;i++) { - j = rand()%8; - x = md->bl.x + dirx[j]; - y = md->bl.y + diry[j]; - if(map_getcell(md->bl.m,x,y,CELL_CHKPASS)) - break; - } - if(i >= 16) { - x = md->bl.x; - y = md->bl.y; - } - if(target->prev != NULL) { - if(target->type == BL_PC && !pc_isdead((struct map_session_data *)target)) - pc_setpos((struct map_session_data *)target,map[md->bl.m].name,x,y,3); - else if(target->type == BL_MOB) - mob_warp((struct mob_data *)target,-1,x,y,3); - } - } - break; - - case BA_FROSTJOKE: /* 寒いジョ?ク */ - case DC_SCREAM: /* スクリ?ム */ - range=battle_config.area_size; //視界全? - map_foreachinarea(skill_frostjoke_scream,src->m,src->x-range,src->y-range, - src->x+range,src->y+range,0,src,skl->skill_id,skl->skill_lv,tick); - break; - - case WZ_WATERBALL: - if (skl->type>1) { - skl->timer = 0; // skill_addtimerskillで使用されないように - skill_addtimerskill(src,tick+150,target->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag); - skl->timer = -1; - } - skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); - if (skl->type <= 1) { // partial fix: it still doesn't end if the target dies - // should put outside of the switch, but since this is the only - // mage targetted spell for now, - struct status_change *sc_data = status_get_sc_data(src); - if(sc_data && sc_data[SC_MAGICPOWER].timer != -1) //マジックパワ?の?果終了 - status_change_end(src,SC_MAGICPOWER,-1); - } - break; - default: - skill_attack(skl->type,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); - break; - } - } - else { - if(src->m != skl->map) - return 0; - switch(skl->skill_id) { - case WZ_METEOR: - if(skl->type >= 0) { - skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->type>>16,skl->type&0xFFFF,0); - clif_skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick); - } - else - skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,0); - break; - } - } - - return 0; -} - -/*========================================== - * - *------------------------------------------ - */ -int skill_addtimerskill(struct block_list *src,unsigned int tick,int target,int x,int y,int skill_id,int skill_lv,int type,int flag) -{ - int i; - - nullpo_retr(1, src); - - if(src->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)src; - nullpo_retr(1, sd); - for(i=0;i<MAX_SKILLTIMERSKILL;i++) { - if(sd->skilltimerskill[i].timer == -1) { - sd->skilltimerskill[i].timer = add_timer(tick, skill_timerskill, src->id, i); - sd->skilltimerskill[i].src_id = src->id; - sd->skilltimerskill[i].target_id = target; - sd->skilltimerskill[i].skill_id = skill_id; - sd->skilltimerskill[i].skill_lv = skill_lv; - sd->skilltimerskill[i].map = src->m; - sd->skilltimerskill[i].x = x; - sd->skilltimerskill[i].y = y; - sd->skilltimerskill[i].type = type; - sd->skilltimerskill[i].flag = flag; - sd->timerskill_count++; - - return 0; - } - } - return 1; - } - else if(src->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)src; - nullpo_retr(1, md); - for(i=0;i<MAX_MOBSKILLTIMERSKILL;i++) { - if(md->skilltimerskill[i].timer == -1) { - md->skilltimerskill[i].timer = add_timer(tick, skill_timerskill, src->id, i); - md->skilltimerskill[i].src_id = src->id; - md->skilltimerskill[i].target_id = target; - md->skilltimerskill[i].skill_id = skill_id; - md->skilltimerskill[i].skill_lv = skill_lv; - md->skilltimerskill[i].map = src->m; - md->skilltimerskill[i].x = x; - md->skilltimerskill[i].y = y; - md->skilltimerskill[i].type = type; - md->skilltimerskill[i].flag = flag; - - return 0; - } - } - return 1; - } - else if(src->type == BL_PET) { // [Valaris] - struct pet_data *pd = (struct pet_data *)src; - nullpo_retr(1, pd); - for(i=0;i<MAX_MOBSKILLTIMERSKILL;i++) { - if(pd->skilltimerskill[i].timer == -1) { - pd->skilltimerskill[i].timer = add_timer(tick, skill_timerskill, src->id, i); - pd->skilltimerskill[i].src_id = src->id; - pd->skilltimerskill[i].target_id = target; - pd->skilltimerskill[i].skill_id = skill_id; - pd->skilltimerskill[i].skill_lv = skill_lv; - pd->skilltimerskill[i].map = src->m; - pd->skilltimerskill[i].x = x; - pd->skilltimerskill[i].y = y; - pd->skilltimerskill[i].type = type; - pd->skilltimerskill[i].flag = flag; - - return 0; - } - } - return 1; - } - return 1; -} - -/*========================================== - * - *------------------------------------------ - */ -int skill_cleartimerskill(struct block_list *src) -{ - int i; - - nullpo_retr(0, src); - - if(src->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)src; - nullpo_retr(0, sd); - - if (sd->timerskill_count <= 0) - return 0; - - for(i=0;i<MAX_SKILLTIMERSKILL;i++) { - if(sd->skilltimerskill[i].timer != -1) { - delete_timer(sd->skilltimerskill[i].timer, skill_timerskill); - sd->skilltimerskill[i].timer = -1; - sd->timerskill_count--; - } - } - } - else if(src->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)src; - nullpo_retr(0, md); - for(i=0;i<MAX_MOBSKILLTIMERSKILL;i++) { - if(md->skilltimerskill[i].timer != -1) { - delete_timer(md->skilltimerskill[i].timer, skill_timerskill); - md->skilltimerskill[i].timer = -1; - } - } - } - - return 0; -} - -/* 範?スキル使用?理小分けここまで - * ------------------------------------------------------------------------- - */ - -/*========================================== - * スキル使用(詠唱完了、ID指定攻?系) - * (スパゲッティに向けて1?前進!(ダメポ)) - *------------------------------------------ - */ -int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag) -{ - struct map_session_data *sd = NULL, *tsd = NULL; - struct status_change *sc_data; - int i; - - if(skillid < 0) - { // remove the debug print when this case is finished - printf("skill_castend_damage_id: skillid=%i\ncall: %p %p %i %i %i %i",skillid, - src, bl,skillid,skilllv,tick,flag); - return 0; - } - if(skillid > 0 && skilllv <= 0) return 0; - - nullpo_retr(1, src); - nullpo_retr(1, bl); - - sc_data = status_get_sc_data(src); - - if (src->type == BL_PC) - sd = (struct map_session_data *)src; - if (sd && pc_isdead(sd)) - return 1; - - if ((skillid == CR_GRANDCROSS || skillid == NPC_DARKGRANDCROSS) && src != bl) - bl = src; - if (bl->prev == NULL) - return 1; - if (bl->type == BL_PC) - tsd = (struct map_session_data *)bl; - if (tsd && pc_isdead(tsd)) - return 1; - map_freeblock_lock(); - - switch(skillid) - { - /* 武器攻?系スキル */ - case SM_BASH: /* バッシュ */ - case MC_MAMMONITE: /* メマ?ナイト */ - case AC_DOUBLE: /* ダブルストレイフィング */ - case AS_SONICBLOW: /* ソニックブロ? */ - case KN_PIERCE: /* ピア?ス */ - case KN_SPEARBOOMERANG: /* スピアブ?メラン */ - case KN_BRANDISHSPEAR: /* ブランディッシュスピア */ - case TF_POISON: /* インベナム */ - case TF_SPRINKLESAND: /* 砂まき */ - case AC_CHARGEARROW: /* チャ?ジアロ? */ - case RG_RAID: /* サプライズアタック */ - case RG_INTIMIDATE: /* インティミデイト */ - case BA_MUSICALSTRIKE: /* ミュ?ジカルストライク */ - case DC_THROWARROW: /* 矢?ち */ - case BA_DISSONANCE: /* 不協和音 */ - case CR_HOLYCROSS: /* ホ?リ?クロス */ - case CR_SHIELDCHARGE: - case CR_SHIELDBOOMERANG: - /* 以下MOB?用 */ - /* ??攻?、SP減少攻?、遠距離攻?、防御無視攻?、多段攻? */ - case NPC_PIERCINGATT: - case NPC_MENTALBREAKER: - case NPC_RANGEATTACK: - case NPC_CRITICALSLASH: - case NPC_COMBOATTACK: - /* 必中攻?、毒攻?、暗?攻?、沈?攻?、スタン攻? */ - case NPC_GUIDEDATTACK: - case NPC_POISON: - case NPC_BLINDATTACK: - case NPC_SILENCEATTACK: - case NPC_STUNATTACK: - /* 石化攻?、呪い攻?、睡眠攻?、ランダムATK攻? */ - case NPC_PETRIFYATTACK: - case NPC_CURSEATTACK: - case NPC_SLEEPATTACK: - case NPC_RANDOMATTACK: - /* 水?性攻?、地?性攻?、火?性攻?、風?性攻? */ - case NPC_WATERATTACK: - case NPC_GROUNDATTACK: - case NPC_FIREATTACK: - case NPC_WINDATTACK: - /* 毒?性攻?、聖?性攻?、闇?性攻?、念?性攻?、SP減少攻? */ - case NPC_POISONATTACK: - case NPC_HOLYATTACK: - case NPC_DARKNESSATTACK: - case NPC_TELEKINESISATTACK: - case NPC_UNDEADATTACK: - case NPC_BREAKARMOR: - case NPC_BREAKWEAPON: - case NPC_BREAKHELM: - case NPC_BREAKSHIELD: - case LK_AURABLADE: /* オ?ラブレ?ド */ - case LK_SPIRALPIERCE: /* スパイラルピア?ス */ - case LK_HEADCRUSH: /* ヘッドクラッシュ */ - case LK_JOINTBEAT: /* ジョイントビ?ト */ - case CG_ARROWVULCAN: /* アロ?バルカン */ - case HW_MAGICCRASHER: /* マジッククラッシャ? */ - case ASC_METEORASSAULT: /* メテオアサルト */ - case ITM_TOMAHAWK: - case MO_COMBOFINISH: /* 猛龍拳 */ - case CH_CHAINCRUSH: /* 連柱崩? */ - case CH_PALMSTRIKE: /* 猛虎硬派山 */ - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - break; - - case ASC_BREAKER: /* ソウルブレ?カ? */ // [DracoRPG] - // separate weapon and magic attacks - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - break; - - case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ - map_foreachinpath (skill_attack_area,src->m, // function, map - src->x,src->y, // source xy - bl->x,bl->y, // target xy - 2,0, // range, type - BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); // varargs - break; - - case PA_PRESSURE: /* プレッシャ? */ - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (rand()%100 < 50) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(PA_PRESSURE,skilllv),0); - else - status_change_start(bl,SC_BLEEDING,skilllv,0,0,0,skill_get_time2(PA_PRESSURE,skilllv),0); - if (tsd) { - int sp = tsd->status.max_sp * 10 * skilllv / 100; - if (sp > tsd->status.sp) sp = tsd->status.sp; - tsd->status.sp -= sp; - clif_updatestatus(tsd,SP_SP); - } - break; - - case NPC_DARKBREATH: - clif_emotion(src,7); - skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag); - break; - - case MO_INVESTIGATE: /* ?勁 */ - { - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (sc_data && sc_data[SC_BLADESTOP].timer != -1) - status_change_end(src,SC_BLADESTOP,-1); - } - break; - - case SN_FALCONASSAULT: /* ファルコンアサルト */ - skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag); - break; - - case RG_BACKSTAP: /* バックスタブ */ - { - int dir = map_calc_dir(src,bl->x,bl->y), t_dir = status_get_dir(bl); - int dist = distance(src->x, src->y, bl->x, bl->y); - if ((dist > 0 && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) { - if (sc_data && sc_data[SC_HIDING].timer != -1) - status_change_end(src, SC_HIDING, -1); // ハイディング解除 - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag); - dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest] - if (tsd) - tsd->dir = dir; - else if (bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)bl; - if (md) md->dir = dir; - } - clif_changed_dir(bl); - } - else if (sd) - clif_skill_fail(sd,sd->skillid,0,0); - } - break; - - case AM_ACIDTERROR: /* アシッドテラ? */ - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag); - if (tsd && battle_config.equipment_breaking && rand()%100 < skill_get_time(skillid,skilllv)) { - pc_breakarmor(tsd); - clif_emotion(bl, 23); - } - break; - - case MO_FINGEROFFENSIVE: /* 指? */ - { - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (battle_config.finger_offensive_type && sd) { - for (i = 1; i < sd->spiritball_old; i++) - skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag); - sd->canmove_tick = tick + (sd->spiritball_old - 1) * 200; - } - if (sc_data && sc_data[SC_BLADESTOP].timer != -1) - status_change_end(src,SC_BLADESTOP,-1); - } - break; - - case MO_CHAINCOMBO: /* 連打掌 */ - { - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (sc_data && sc_data[SC_BLADESTOP].timer != -1) - status_change_end(src,SC_BLADESTOP,-1); - } - break; - - case CH_TIGERFIST: /* 伏虎拳 */ - if (tsd && !(map[bl->m].flag.gvg || map[bl->m].flag.pvp)) { - map_freeblock_unlock(); - return 1; - } - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - break; - - case MO_EXTREMITYFIST: /* 阿修羅覇鳳拳 */ - { - if(sd) { - struct walkpath_data wpd; - int dx,dy; - - dx = bl->x - sd->bl.x; - dy = bl->y - sd->bl.y; - if(dx > 0) dx++; - else if(dx < 0) dx--; - if (dy > 0) dy++; - else if(dy < 0) dy--; - if(dx == 0 && dy == 0) dx++; - if (path_search(&wpd,src->m,sd->bl.x,sd->bl.y,sd->bl.x+dx,sd->bl.y+dy,1) == -1) { - dx = bl->x - sd->bl.x; - dy = bl->y - sd->bl.y; - if(path_search(&wpd,src->m,sd->bl.x,sd->bl.y,sd->bl.x+dx,sd->bl.y+dy,1) == -1) { - clif_skill_fail(sd,sd->skillid,0,0); - break; - } - } - sd->to_x = sd->bl.x + dx; - sd->to_y = sd->bl.y + dy; - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - clif_walkok(sd); - clif_movechar(sd); - if(dx < 0) dx = -dx; - if(dy < 0) dy = -dy; - sd->attackabletime = sd->canmove_tick = tick + 100 + sd->speed * ((dx > dy)? dx:dy); - if(sd->canact_tick < sd->canmove_tick) - sd->canact_tick = sd->canmove_tick; - pc_movepos(sd,sd->to_x,sd->to_y); - status_change_end(&sd->bl,SC_COMBO,-1); - } - else - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - status_change_end(src, SC_EXPLOSIONSPIRITS, -1); - if (sc_data && sc_data[SC_BLADESTOP].timer != -1) - status_change_end(src,SC_BLADESTOP,-1); - } - break; - - /* 武器系範?攻?スキル */ - case AC_SHOWER: /* アロ?シャワ? */ - case AS_GRIMTOOTH: /* グリムトゥ?ス */ - case MC_CARTREVOLUTION: /* カ?トレヴォリュ?ション */ - case NPC_SPLASHATTACK: /* スプラッシュアタック */ - case AS_SPLASHER: /* [Valaris] */ - if(flag&1){ - /* 個別にダメ?ジを?える */ - if(bl->id!=skill_area_temp[1]){ - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick, - 0x0500); - } - } else { - int ar = 1; - int x = bl->x, y = bl->y; - switch (skillid) { - case AC_SHOWER: - ar=2; - break; - case NPC_SPLASHATTACK: - ar=3; - break; - } - - skill_area_temp[1]=bl->id; - skill_area_temp[2]=x; - skill_area_temp[3]=y; - /* まずタ?ゲットに攻?を加える */ - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); - /* その後タ?ゲット以外の範??の敵全?に?理を行う */ - map_foreachinarea(skill_area_sub, - bl->m,x-ar,y-ar,x+ar,y+ar,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - } - break; - - case SM_MAGNUM: /* マグナムブレイク [celest] */ - if(flag&1 && bl->id != skill_area_temp[1]){ - int dist = distance (bl->x, bl->y, skill_area_temp[2], skill_area_temp[3]); - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick, - 0x0500|dist); - } else { - skill_area_temp[1]=src->id; - skill_area_temp[2]=src->x; - skill_area_temp[3]=src->y; - map_foreachinarea(skill_area_sub, - src->m,src->x-2,src->y-2,src->x+2,src->y+2,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - status_change_start (src,SC_FLAMELAUNCHER,0,0,0,0,10000,0); - clif_skill_nodamage (src,src,skillid,skilllv,1); - } - break; - - case KN_BOWLINGBASH: /* ボウリングバッシュ */ - if(flag&1){ - /* 個別にダメ?ジを?える */ - if(bl->id!=skill_area_temp[1]) - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500); - } else { - int i,c; /* 他人から聞いた動きなので間違ってる可能性大&?率が?いっす>< */ - /* まずターゲットに攻撃を加える */ - if (!skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0)) - break; - c = skill_get_blewcount(skillid,skilllv); - if(map[bl->m].flag.gvg) c = 0; - for(i=0;i<c;i++){ - skill_blown(src,bl,1); - if(bl->type == BL_MOB) - clif_fixmobpos((struct mob_data *)bl); - else if(bl->type == BL_PET) - clif_fixpetpos((struct pet_data *)bl); - else - clif_fixpos(bl); - skill_area_temp[0]=0; - map_foreachinarea(skill_area_sub, - bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY , - skill_area_sub_count); - if(skill_area_temp[0]>1) break; - } - skill_area_temp[1]=bl->id; - /* その後タ?ゲット以外の範??の敵全?に?理を行う */ - map_foreachinarea(skill_area_sub, - bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - } - break; - - case KN_SPEARSTAB: /* スピアスタブ */ - if(flag&1){ - /* 個別にダメージを与える */ - if (bl->id==skill_area_temp[1]) - break; - if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500)) - skill_blown(src,bl,skill_area_temp[2]); - } else { - int x=bl->x,y=bl->y,i,dir; - /* まずターゲットに攻撃を加える */ - dir = map_calc_dir(bl,src->x,src->y); - skill_area_temp[1] = bl->id; - skill_area_temp[2] = skill_get_blewcount(skillid,skilllv)|dir<<20; - if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0)) - skill_blown(src,bl,skill_area_temp[2]); - for (i=0;i<4;i++) { - map_foreachinarea(skill_area_sub,bl->m,x,y,x,y,0, - src,skillid,skilllv,tick,flag|BCT_ENEMY|1, - skill_castend_damage_id); - x += dirx[dir]; - y += diry[dir]; - } - } - break; - - case ALL_RESURRECTION: /* リザレクション */ - case PR_TURNUNDEAD: /* タ?ンアンデッド */ - if(bl->type != BL_PC && battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - else { - map_freeblock_unlock(); - return 1; - } - break; - - /* 魔法系スキル */ - case MG_SOULSTRIKE: /* ソウルストライク */ - case NPC_DARKSOULSTRIKE: /*闇ソウルストライク*/ - case MG_COLDBOLT: /* コールドボルト */ - case MG_FIREBOLT: /* ファイアーボルト */ - case MG_LIGHTNINGBOLT: /* ライトニングボルト */ - case WZ_EARTHSPIKE: /* アーススパイク */ - case AL_HEAL: /* ヒール */ - case AL_HOLYLIGHT: /* ホーリーライト */ - case WZ_JUPITEL: /* ユピテルサンダー */ - case NPC_DARKJUPITEL: /*闇ユピテル*/ - case NPC_MAGICALATTACK: /* MOB:魔法打?攻? */ - case PR_ASPERSIO: /* アスペルシオ */ - case MG_FROSTDIVER: /* フロストダイバー */ - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - break; - - case WZ_WATERBALL: /* ウォ?タ?ボ?ル */ - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - if (skilllv>1) { - int cnt,range; - range = skilllv>5?2:skilllv/2; - if (sd) - cnt = skill_count_water(src,range)-1; - else - cnt = skill_get_num(skillid,skilllv)-1; - if (cnt>0) - skill_addtimerskill(src,tick+150,bl->id,0,0, - skillid,skilllv,cnt,flag); - } - break; - - case PR_BENEDICTIO: /* 聖?降福 */ - if(status_get_race(bl)==1 || status_get_race(bl)==6) - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - break; - - /* 魔法系範?攻?スキル */ - case MG_NAPALMBEAT: /* ナパ?ムビ?ト */ - case MG_FIREBALL: /* ファイヤ?ボ?ル */ - case WZ_SIGHTRASHER: /* サイトラッシャー */ - if (flag & 1) { - /* 個別にダメ?ジを?える */ - if (bl->id != skill_area_temp[1]){ - if(skillid == MG_FIREBALL){ /* ファイヤ?ボ?ルなら中心からの距離を計算 */ - skill_area_temp[0] = distance(bl->x, bl->y, skill_area_temp[2], skill_area_temp[3]); - } - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, - skill_area_temp[0]| 0x0500); - } - } else { - int ar; - skill_area_temp[0]=0; - skill_area_temp[1]=bl->id; - switch (skillid) { - case MG_NAPALMBEAT: - ar = 1; - /* ナパームビートは分散ダメージなので敵の数を数える */ - map_foreachinarea(skill_area_sub, - bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,0, - src,skillid,skilllv,tick,flag|BCT_ENEMY, - skill_area_sub_count); - break; - case MG_FIREBALL: - ar = 2; - skill_area_temp[2]=bl->x; - skill_area_temp[3]=bl->y; - /* ターゲットに攻撃を加える(スキルエフェクト表示) */ - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, - skill_area_temp[0]); - break; - case WZ_SIGHTRASHER: - default: - ar = 3; - bl = src; - status_change_end(src,SC_SIGHT,-1); - break; - } - if (skillid==WZ_SIGHTRASHER) { - /* スキルエフェクト表示 */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } else { - /* ターゲットに攻撃を加える(スキルエフェクト表示) */ - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, - skill_area_temp[0]); - } - /* ターゲット以外の範囲内の敵全体に処理を行う */ - map_foreachinarea(skill_area_sub, - bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - } - break; - - case HW_NAPALMVULCAN: // Fixed By SteelViruZ - if(flag&1){ - if(bl->id!=skill_area_temp[1]){ - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, - skill_area_temp[0]); - } - }else{ - int ar=(skillid==HW_NAPALMVULCAN)?1:2; - skill_area_temp[1]=bl->id; - if(skillid==HW_NAPALMVULCAN){ - skill_area_temp[0]=0; - map_foreachinarea(skill_area_sub, - bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY , - skill_area_sub_count); - }else{ - skill_area_temp[0]=0; - skill_area_temp[2]=bl->x; - skill_area_temp[3]=bl->y; - } - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, - skill_area_temp[0] ); - map_foreachinarea(skill_area_sub, - bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - } - break; - - case WZ_FROSTNOVA: /* フロストノヴァ */ - map_foreachinarea(skill_attack_area,src->m,src->x-5,bl->y-5,bl->x+5,bl->y+5,0,BF_MAGIC,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); - break; - - /* その他 */ - case HT_BLITZBEAT: /* ブリッツビ?ト */ - if(flag&1){ - /* 個別にダメ?ジを?える */ - if(bl->id!=skill_area_temp[1]) - skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,skill_area_temp[0]|(flag&0xf00000)); - }else{ - skill_area_temp[0]=0; - skill_area_temp[1]=bl->id; - if(flag&0xf00000) - map_foreachinarea(skill_area_sub,bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY ,skill_area_sub_count); - /* まずタ?ゲットに攻?を加える */ - skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,skill_area_temp[0]|(flag&0xf00000)); - /* その後タ?ゲット以外の範??の敵全?に?理を行う */ - map_foreachinarea(skill_area_sub, - bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - } - break; - - case CR_GRANDCROSS: /* グランドクロス */ - case NPC_DARKGRANDCROSS: /*闇グランドクロス*/ - /* スキルユニット配置 */ - skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0); - if(sd) - sd->canmove_tick = tick + 1000; - else if(src->type == BL_MOB) - mob_changestate((struct mob_data *)src,MS_DELAY,1000); - break; - - case TF_THROWSTONE: /* 石投げ */ - case NPC_SMOKING: /* スモ?キング */ - skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,0 ); - break; - - // Celest - case PF_SOULBURN: - { - int per = skilllv < 5 ? 20+ skilllv*10 : 60; - if (rand()%100 < per) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (skilllv == 5) - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,0 ); - if (tsd && (map[src->m].flag.pvp || map[src->m].flag.gvg)) { - tsd->status.sp = 0; - clif_updatestatus(tsd,SP_SP); - } - } else { - clif_skill_nodamage(src,src,skillid,skilllv,1); - if (skilllv == 5) - skill_attack(BF_MAGIC,src,src,src,skillid,skilllv,tick,0 ); - if (sd) { - sd->status.sp = 0; - clif_updatestatus(sd,SP_SP); - } - } - if (sd) - pc_blockskill_start (sd, skillid, (skilllv < 5 ? 10000: 15000)); - } - break; - - case NPC_SELFDESTRUCTION: /* 自爆 */ - case NPC_SELFDESTRUCTION2: /* 自爆2 */ - if(flag&1){ - /* 個別にダメ?ジを?える */ - if(src->type==BL_MOB){ - struct mob_data* mb = (struct mob_data*)src; - nullpo_retr(1, mb); - mb->hp=skill_area_temp[2]; - if(bl->id!=skill_area_temp[1]) - skill_attack(BF_MISC,src,src,bl,NPC_SELFDESTRUCTION,skilllv,tick,flag ); - mb->hp=1; - } - }else{ - struct mob_data *md; - if((md=(struct mob_data *)src)){ - skill_area_temp[1]=bl->id; - skill_area_temp[2]=status_get_hp(src); - clif_skill_nodamage(src,src,NPC_SELFDESTRUCTION,-1,1); - map_foreachinarea(skill_area_sub, - bl->m,bl->x-5,bl->y-5,bl->x+5,bl->y+5,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - battle_damage(src,src,md->hp,0); - } - } - break; - - /* HP吸?/HP吸?魔法 */ - case NPC_BLOODDRAIN: - case NPC_ENERGYDRAIN: - { - int heal; - heal = skill_attack((skillid==NPC_BLOODDRAIN)?BF_WEAPON:BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - if( heal > 0 ){ - struct block_list tbl; - tbl.id = 0; - tbl.m = src->m; - tbl.x = src->x; - tbl.y = src->y; - clif_skill_nodamage(&tbl,src,AL_HEAL,heal,1); - battle_heal(NULL,src,heal,0,0); - } - } - break; - - // unknown skills [Celest] - case NPC_BIND: - case NPC_EXPLOSIONSPIRITS: - case NPC_INCAGI: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - break; - - case 0: - if(sd) { - if(flag&3){ - if(bl->id!=skill_area_temp[1]) - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500); - } - else{ - int ar=sd->splash_range; - skill_area_temp[1]=bl->id; - map_foreachinarea(skill_area_sub, - bl->m, bl->x - ar, bl->y - ar, bl->x + ar, bl->y + ar, 0, - src, skillid, skilllv, tick, flag | BCT_ENEMY | 1, - skill_castend_damage_id); - } - } - break; - - default: - printf("Unknown skill used:%d\n",skillid); - map_freeblock_unlock(); - return 1; - } - if(sc_data) { - if (sc_data[SC_MAGICPOWER].timer != -1 && skillid != HW_MAGICPOWER) //マジックパワ?の?果終了 - status_change_end(src,SC_MAGICPOWER,-1); - } - map_freeblock_unlock(); - - return 0; -} - -/*========================================== - * スキル使用(詠唱完了、ID指定支援系) - *------------------------------------------ - */ -int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag) -{ - struct map_session_data *sd = NULL; - struct map_session_data *dstsd = NULL; - struct mob_data *md = NULL; - struct mob_data *dstmd = NULL; - int i; - int sc_def_vit, sc_def_mdef; - int sc_dex, sc_luk; - - if(skillid < 0) - { // remove the debug print when this case is finished - printf("skill_castend_damage_id: skillid=%i\ncall: %p %p %i %i %i %i",skillid, - src, bl,skillid,skilllv,tick,flag); - return 0; - } - if(skillid > 0 && skilllv <= 0) return 0; // celest - - nullpo_retr(1, src); - nullpo_retr(1, bl); - - if (src->type == BL_PC) { - nullpo_retr (1, sd = (struct map_session_data *)src); - } else if (src->type == BL_MOB) { - nullpo_retr (1, md = (struct mob_data *)src); - } - - sc_dex = status_get_mdef (bl); - sc_luk = status_get_luk (bl); - sc_def_vit = status_get_sc_def_vit (bl); - sc_def_mdef = status_get_sc_def_mdef (bl); - - if (bl->type == BL_PC){ - nullpo_retr (1, dstsd = (struct map_session_data *)bl); - } else if (bl->type == BL_MOB){ - nullpo_retr (1, dstmd = (struct mob_data *)bl); - } - - if(bl->prev == NULL) - return 1; - if(sd && pc_isdead(sd)) - return 1; - if(dstsd && pc_isdead(dstsd) && skillid != ALL_RESURRECTION) - return 1; - if(status_get_class(bl) == 1288) - return 1; - if (sd && skillnotok(skillid, sd)) // [MouseJstr] - return 0; - - map_freeblock_lock(); - switch(skillid) - { - case AL_HEAL: /* ヒ?ル */ - { - int heal = skill_calc_heal(src, skilllv); - int heal_get_jobexp; - int skill; - - if (skilllv > 10) - heal = 9999; //9999ヒール - if (dstsd && dstsd->special_state.no_magic_damage) - heal=0; /* ?金蟲カ?ド(ヒ?ル量0) */ - if (sd) { - if ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) // メディテイティオ - heal += heal * skill * 2 / 100; - if (sd && dstsd && sd->status.partner_id == dstsd->status.char_id && - pc_calc_base_job2(sd->status.class_) == 23 && sd->status.sex == 0) //自分も?象もPC、?象が自分のパ?トナ?、自分がスパノビ、自分が♀なら - heal = heal*2; //スパノビの嫁が旦那にヒ?ルすると2倍になる - } - - clif_skill_nodamage (src, bl, skillid, heal, 1); - heal_get_jobexp = battle_heal(NULL,bl,heal,0,0); - - // JOB??値獲得 - if(sd && dstsd && heal > 0 && sd != dstsd && battle_config.heal_exp > 0){ - heal_get_jobexp = heal_get_jobexp * battle_config.heal_exp / 100; - if (heal_get_jobexp <= 0) - heal_get_jobexp = 1; - pc_gainexp (sd, 0, heal_get_jobexp); - } - } - break; - - case ALL_RESURRECTION: /* リザレクション */ - if(dstsd) { - int per = 0; - if (map[bl->m].flag.pvp && dstsd->pvp_point < 0) - break; /* PVPで復活不可能?態 */ - - if (pc_isdead(dstsd)) { /* 死亡判定 */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - switch(skilllv){ - case 1: per=10; break; - case 2: per=30; break; - case 3: per=50; break; - case 4: per=80; break; - } - dstsd->status.hp = dstsd->status.max_hp * per / 100; - if (dstsd->status.hp <= 0) dstsd->status.hp = 1; - if (dstsd->special_state.restart_full_recover) { /* オシリスカ?ド */ - dstsd->status.hp = dstsd->status.max_hp; - dstsd->status.sp = dstsd->status.max_sp; - } - pc_setstand(dstsd); - if(battle_config.pc_invincible_time > 0) - pc_setinvincibletimer(dstsd, battle_config.pc_invincible_time); - clif_updatestatus(dstsd, SP_HP); - clif_resurrection(bl, 1); - if(sd && sd != dstsd && battle_config.resurrection_exp > 0) { - int exp = 0,jexp = 0; - int lv = dstsd->status.base_level - sd->status.base_level, jlv = dstsd->status.job_level - sd->status.job_level; - if(lv > 0) { - exp = (int)((double)dstsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.); - if (exp < 1) exp = 1; - } - if(jlv > 0) { - jexp = (int)((double)dstsd->status.job_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.); - if (jexp < 1) jexp = 1; - } - if(exp > 0 || jexp > 0) - pc_gainexp (sd, exp, jexp); - } - } - } - break; - - case AL_DECAGI: /* 速度減少 */ - if (dstsd && dstsd->special_state.no_magic_damage) - break; - if (rand() % 100 < (50 + skilllv * 3 + (status_get_lv(src) + status_get_int(src) / 5) - sc_def_mdef)) { - clif_skill_nodamage (src, bl, skillid, skilllv, 1); - status_change_start (bl, SkillStatusChangeTable[skillid], skilllv, 0, 0, 0, skill_get_time(skillid,skilllv), 0); - } - break; - - case AL_CRUCIS: - if (flag & 1) { - int race = status_get_race (bl), ele = status_get_elem_type (bl); - if (battle_check_target (src, bl, BCT_ENEMY) && (race == 6 || battle_check_undead (race, ele))) { - int slv = status_get_lv (src),tlv = status_get_lv (bl); - int rate = 25 + skilllv*2 + slv - tlv; - if (rand()%100 < rate) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,0,0); - } - } else { - clif_skill_nodamage(src, bl, skillid, skilllv, 1); - map_foreachinarea(skill_area_sub, - src->m, src->x-15, src->y-15, src->x+15, src->y+15, 0, - src, skillid, skilllv, tick, flag|BCT_ENEMY|1, - skill_castend_nodamage_id); - } - break; - - case PR_LEXDIVINA: /* レックスディビ?ナ */ - { - struct status_change *sc_data = status_get_sc_data(bl); - clif_skill_nodamage (src, bl, skillid, skilllv, 1); - if (dstsd && dstsd->special_state.no_magic_damage) - break; - if (sc_data && sc_data[SC_DIVINA].timer != -1) - status_change_end(bl,SC_DIVINA, -1); - else if (rand() % 100 < sc_def_vit) { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - } - } - break; - - case SA_ABRACADABRA: - { - int abra_skillid = 0, abra_skilllv; - //require 1 yellow gemstone even with mistress card or Into the Abyss - if ((i = pc_search_inventory(sd, 715)) < 0 ) { //bug fixed by Lupus (item pos can be 0, too!) - clif_skill_fail(sd,sd->skillid,0,0); - break; - } - pc_delitem(sd, i, 1, 0); - do { - abra_skillid = rand() % 331; - if (skill_abra_db[abra_skillid].req_lv > skilllv || - rand()%10000 >= skill_abra_db[abra_skillid].per || //dbに基づくレベル?確率判定 - (abra_skillid >= NPC_PIERCINGATT && abra_skillid <= NPC_SUMMONMONSTER) || //NPCスキルはダメ - skill_get_unit_flag(abra_skillid) & UF_DANCE) //演奏スキルはダメ - abra_skillid = 0; // reset to get a new id - } while (abra_skillid == 0); - abra_skilllv = skill_get_max(abra_skillid) > skilllv ? skilllv : skill_get_max(abra_skillid); - clif_skill_nodamage (src, bl, skillid, skilllv, 1); - sd->skillitem = abra_skillid; - sd->skillitemlv = abra_skilllv; - clif_item_skill (sd, abra_skillid, abra_skilllv, "Abracadabra"); - } - break; - - case SA_COMA: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstsd) { - if (dstsd->special_state.no_magic_damage) - break; - dstsd->status.hp = 1; - dstsd->status.sp = 1; - clif_updatestatus(dstsd, SP_HP); - clif_updatestatus(dstsd, SP_SP); - } - if(dstmd) dstmd->hp = 1; - break; - case SA_FULLRECOVERY: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstsd) { - if (dstsd->special_state.no_magic_damage) - break; - pc_heal (dstsd, dstsd->status.max_hp, dstsd->status.max_sp); - } - if (dstmd) dstmd->hp = status_get_max_hp(bl); - break; - case SA_SUMMONMONSTER: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (sd) mob_once_spawn(sd,map[src->m].name,src->x,src->y,"--ja--",-1,1,""); - break; - case SA_LEVELUP: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (sd && pc_nextbaseexp(sd)) pc_gainexp(sd, pc_nextbaseexp(sd) * 10 / 100, 0); - break; - case SA_INSTANTDEATH: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (sd) pc_damage(NULL,sd,sd->status.max_hp); - break; - case SA_QUESTION: - case SA_GRAVITY: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - break; - case SA_CLASSCHANGE: - { - //クラスチェンジ用ボスモンスタ?ID - int changeclass[]={1038,1039,1046,1059,1086,1087,1112,1115 - ,1157,1159,1190,1272,1312,1373,1492}; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstmd) mob_class_change(dstmd,changeclass); - } - break; - case SA_MONOCELL: - { - int poringclass[]={1002}; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstmd) mob_class_change(dstmd,poringclass); - } - break; - case SA_DEATH: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstsd) pc_damage(NULL,dstsd,dstsd->status.max_hp); - if (dstmd) mob_damage(NULL,dstmd,dstmd->hp,1); - break; - case SA_REVERSEORCISH: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstsd) pc_setoption(dstsd,dstsd->status.option|0x0800); - break; - case SA_FORTUNE: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(sd) pc_getzeny(sd,status_get_lv(bl)*100); - break; - case SA_TAMINGMONSTER: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstmd) { - for (i = 0; i < MAX_PET_DB; i++) { - if (dstmd->class_ == pet_db[i].class_) { - pet_catch_process1 (sd, dstmd->class_); - break; - } - } - } - break; - - case AL_INCAGI: /* 速度?加 */ - case AL_BLESSING: /* ブレッシング */ - case PR_SLOWPOISON: - case PR_IMPOSITIO: /* イムポシティオマヌス */ - case PR_LEXAETERNA: /* レックスエ?テルナ */ - case PR_SUFFRAGIUM: /* サフラギウム */ - case PR_BENEDICTIO: /* 聖?降福 */ - case CR_PROVIDENCE: /* プロヴィデンス */ - if (dstsd && dstsd->special_state.no_magic_damage) - clif_skill_nodamage(src,bl,skillid,skilllv,1); - else { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - - case CG_MARIONETTE: /* マリオネットコントロ?ル */ - if (sd && dstsd){ - struct status_change *sc_data = status_get_sc_data(src); - struct status_change *tsc_data = status_get_sc_data(bl); - int sc = SkillStatusChangeTable[skillid]; - int sc2 = SC_MARIONETTE2; - - if ((sd == dstsd) - || (!sd->status.party_id) - || (sd->status.party_id != dstsd->status.party_id)) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 1; - } - if(sc_data && tsc_data){ - if (sc_data[sc].timer == -1 && tsc_data[sc2].timer == -1) { - status_change_start (src,sc,skilllv,0,bl->id,0,skill_get_time(skillid,skilllv),0); - status_change_start (bl,sc2,skilllv,0,src->id,0,skill_get_time(skillid,skilllv),0); - } - else if (sc_data[sc].timer != -1 && tsc_data[sc2].timer != -1 && - sc_data[sc].val3 == bl->id && tsc_data[sc2].val3 == src->id) { - status_change_end(src, sc, -1); - status_change_end(bl, sc2, -1); - } - else { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 1; - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - } - break; - - case SA_FLAMELAUNCHER: // added failure chance and chance to break weapon if turned on [Valaris] - case SA_FROSTWEAPON: - case SA_LIGHTNINGLOADER: - case SA_SEISMICWEAPON: - if (dstsd) { - if (dstsd->special_state.no_magic_damage) { - clif_skill_nodamage(src,bl,skillid,skilllv,0); - break; - } - if(dstsd->status.weapon == 0 || - (sd && sd->status.party_id > 0 && sd->status.party_id != dstsd->status.party_id) || - dstsd->sc_data[SC_FLAMELAUNCHER].timer != -1 || - dstsd->sc_data[SC_FROSTWEAPON].timer != -1 || - dstsd->sc_data[SC_LIGHTNINGLOADER].timer != -1 || - dstsd->sc_data[SC_SEISMICWEAPON].timer != -1 || - dstsd->sc_data[SC_ENCPOISON].timer != -1) { - if (sd) clif_skill_fail(sd,skillid,0,0); - clif_skill_nodamage(src,bl,skillid,skilllv,0); - break; - } - } - if(skilllv < 5 && rand()%100 > (60+skilllv*10) ) { //fixed by Lupus (4 -> 5) or else it has 100% success even at lv4 - if (sd) clif_skill_fail(sd,skillid,0,0); - clif_skill_nodamage(src,bl,skillid,skilllv,0); - if(dstsd && battle_config.equipment_breaking) { - if(sd && sd != dstsd) clif_displaymessage(sd->fd,"You broke target's weapon"); - pc_breakweapon(dstsd); - } - break; - } else { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - - case PR_ASPERSIO: /* アスペルシオ */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstsd && dstsd->special_state.no_magic_damage) - break; - if (dstmd) - break; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case PR_KYRIE: /* キリエエレイソン */ - clif_skill_nodamage(bl,bl,skillid,skilllv,1); - if (dstsd && dstsd->special_state.no_magic_damage) - break; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case KN_AUTOCOUNTER: /* オ?トカウンタ? */ - case KN_TWOHANDQUICKEN: /* ツ?ハンドクイッケン */ - case CR_SPEARQUICKEN: /* スピアクイッケン */ - case CR_REFLECTSHIELD: - case AS_POISONREACT: /* ポイズンリアクト */ - case MC_LOUD: /* ラウドボイス */ - case MG_ENERGYCOAT: /* エナジ?コ?ト */ -// case SM_ENDURE: /* インデュア */ - case MG_SIGHT: /* サイト */ - case AL_RUWACH: /* ルアフ */ - case MO_EXPLOSIONSPIRITS: // 爆裂波動 - case MO_STEELBODY: // 金剛 - case LK_AURABLADE: /* オ?ラブレ?ド */ - case LK_PARRYING: /* パリイング */ - case LK_CONCENTRATION: /* コンセントレ?ション */ -// case LK_BERSERK: /* バ?サ?ク */ - case HP_ASSUMPTIO: /* */ - case WS_CARTBOOST: /* カ?トブ?スト */ - case SN_SIGHT: /* トゥル?サイト */ - case WS_MELTDOWN: /* メルトダウン */ - case ST_REJECTSWORD: /* リジェクトソ?ド */ - case HW_MAGICPOWER: /* 魔法力?幅 */ - case PF_MEMORIZE: /* メモライズ */ - case PA_SACRIFICE: - case ASC_EDP: // [Celest] - case CG_MOONLIT: /* 月明りの泉に落ちる花びら */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case SM_ENDURE: /* インデュア */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - if (sd) - pc_blockskill_start (sd, skillid, 10000); - break; - - case SM_AUTOBERSERK: // Celest - { - struct status_change *tsc_data = status_get_sc_data(bl); - int sc = SkillStatusChangeTable[skillid]; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (tsc_data && tsc_data[sc].timer != -1) - status_change_end(bl, sc, -1); - else - status_change_start(bl,sc,skilllv,0,0,0,0,0); - } - break; - - case AS_ENCHANTPOISON: // Prevent spamming [Valaris] - if (dstsd) { - if(dstsd->sc_data[SC_FLAMELAUNCHER].timer != -1 || - dstsd->sc_data[SC_FROSTWEAPON].timer != -1 || - dstsd->sc_data[SC_LIGHTNINGLOADER].timer != -1 || - dstsd->sc_data[SC_SEISMICWEAPON].timer != -1 || - dstsd->sc_data[SC_ENCPOISON].timer != -1) { - clif_skill_nodamage(src,bl,skillid,skilllv,0); - clif_skill_fail(sd,skillid,0,0); - break; - } - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case LK_TENSIONRELAX: /* テンションリラックス */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - pc_setsit(sd); - clif_sitting(sd); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - case LK_BERSERK: /* バ?サ?ク */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - //sd->status.hp = sd->status.max_hp * 3; - break; - - case MC_CHANGECART: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - break; - - case AC_CONCENTRATION: /* 集中力向上 */ - { - int range = 1; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - map_foreachinarea( status_change_timer_sub, - src->m, src->x-range, src->y-range, src->x+range,src->y+range,0, - src,SkillStatusChangeTable[skillid],tick); - } - break; - - case SM_PROVOKE: /* プロボック */ - { - struct status_change *sc_data = status_get_sc_data(bl); - - /* MVPmobと不死には?かない */ - if((dstmd && status_get_mode(bl)&0x20) || battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) { //不死には?かない - map_freeblock_unlock(); - return 1; - } - - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - - if(dstmd && dstmd->skilltimer!=-1 && dstmd->state.skillcastcancel) // 詠唱妨害 - skill_castcancel(bl,0); - if(dstsd && dstsd->skilltimer!=-1 && (!dstsd->special_state.no_castcancel || map[bl->m].flag.gvg) - && dstsd->state.skillcastcancel && !dstsd->special_state.no_castcancel2) - skill_castcancel(bl,0); - - if(sc_data){ - if(sc_data[SC_FREEZE].timer!=-1) - status_change_end(bl,SC_FREEZE,-1); - if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) - status_change_end(bl,SC_STONE,-1); - if(sc_data[SC_SLEEP].timer!=-1) - status_change_end(bl,SC_SLEEP,-1); - } - - if(dstmd) { - int range = skill_get_range(skillid,skilllv); - dstmd->state.provoke_flag = src->id; - mob_target(dstmd,src,range); - } - } - break; - - case CR_DEVOTION: /* ディボ?ション */ - if(sd && dstsd){ - //?生や養子の場合の元の職業を算出する - int s_class = pc_calc_base_job2 (dstsd->status.class_); - - int lv = sd->status.base_level - dstsd->status.base_level; - if (lv < 0) lv = -lv; - if ((sd == dstsd) // 相手はPCじゃないとだめ - || (sd->bl.id == dstsd->bl.id) // 相手が自分はだめ - || (lv > battle_config.devotion_level_difference) // レベル差±10まで - || (!sd->status.party_id && !sd->status.guild_id) // PTにもギルドにも所?無しはだめ - || ((sd->status.party_id != dstsd->status.party_id) // 同じパ?ティ?か、 - &&(sd->status.guild_id != dstsd->status.guild_id)) // 同じギルドじゃないとだめ - || (s_class == 14 || s_class == 21)) { // クルセだめ - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 1; - } - for (i = 0; i < skilllv; i++) { - if (!sd->dev.val1[i]) { // 空きがあったら入れる - sd->dev.val1[i] = bl->id; - sd->dev.val2[i] = bl->id; - break; - } else if (i == skilllv - 1) { // 空きがなかった - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 1; - } - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - clif_devotion(sd,bl->id); - status_change_start(bl,SkillStatusChangeTable[skillid],src->id,1,0,0,1000*(15+15*skilllv),0 ); - } - else clif_skill_fail(sd,skillid,0,0); - break; - - case MO_CALLSPIRITS: // ?功 - if(sd) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - pc_addspiritball(sd,skill_get_time(skillid,skilllv),skilllv); - } - break; - - case CH_SOULCOLLECT: // 狂?功 - if(sd) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - for (i = 0; i < 5; i++) - pc_addspiritball(sd,skill_get_time(skillid,skilllv),5); - } - break; - - case MO_BLADESTOP: // 白刃取り - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case MO_ABSORBSPIRITS: // ?奪 - i=0; - if (dstsd) { - if ((sd && sd == dstsd) || map[src->m].flag.pvp || map[src->m].flag.gvg) { - if (dstsd->spiritball > 0) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - i = dstsd->spiritball * 7; - pc_delspiritball(dstsd,dstsd->spiritball,0); - if(i > 0x7FFF) - i = 0x7FFF; - if(sd && sd->status.sp + i > sd->status.max_sp) - i = sd->status.max_sp - sd->status.sp; - } - } - } else if (dstmd) { //?象がモンスタ?の場合 - //20%の確率で?象のLv*2のSPを回復する。成功したときはタ?ゲット(σ?Д?)σ????!! - if(rand() % 100 < 20) { - i = 2 * mob_db[dstmd->class_].lv; - mob_target(dstmd,src,0); - } - } - if (i && sd){ - sd->status.sp += i; - clif_heal(sd->fd,SP_SP,i); - } else clif_skill_nodamage(src,bl,skillid,skilllv,0); - break; - - case AC_MAKINGARROW: /* 矢作成 */ - if(sd) { - clif_arrow_create_list(sd); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - - case AM_PHARMACY: /* ポ?ション作成 */ - if(sd) { - clif_skill_produce_mix_list(sd,32); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - case WS_CREATECOIN: /* クリエイトコイン */ - if(sd) { - clif_skill_produce_mix_list(sd,64); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - case WS_CREATENUGGET: /* 塊製造 */ - if(sd) { - clif_skill_produce_mix_list(sd,128); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - case ASC_CDP: // [DracoRPG] - // notes: success rate (from emperium.org) = 20 + [(20*Dex)/50] + [(20*Luk)/100] - if(sd) { - clif_skill_produce_mix_list(sd,256); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - case BS_HAMMERFALL: /* ハンマ?フォ?ル */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_weapon_damage) - break; - if(rand() % 100 < (20 + 10 * skilllv) * sc_def_vit / 100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case RG_RAID: /* サプライズアタック */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - map_foreachinarea(skill_area_sub, - bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - status_change_end(src, SC_HIDING, -1); // ハイディング解除 - break; - - case ASC_METEORASSAULT: /* メテオアサルト */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - map_foreachinarea(skill_area_sub, - bl->m,bl->x-2,bl->y-2,bl->x+2,bl->y+2,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - break; - - case KN_BRANDISHSPEAR: /*ブランディッシュスピア*/ - { - int c,n=4,ar; - int dir = map_calc_dir(src,bl->x,bl->y); - struct square tc; - int x=bl->x,y=bl->y; - ar=skilllv/3; - skill_brandishspear_first(&tc,dir,x,y); - skill_brandishspear_dir(&tc,dir,4); - /* 範?C */ - if(skilllv == 10){ - for(c=1;c<4;c++){ - map_foreachinarea(skill_area_sub, - bl->m,tc.val1[c],tc.val2[c],tc.val1[c],tc.val2[c],0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|n, - skill_castend_damage_id); - } - } - /* 範?BA */ - if(skilllv > 6){ - skill_brandishspear_dir(&tc,dir,-1); - n--; - }else{ - skill_brandishspear_dir(&tc,dir,-2); - n-=2; - } - - if(skilllv > 3){ - for(c=0;c<5;c++){ - map_foreachinarea(skill_area_sub, - bl->m,tc.val1[c],tc.val2[c],tc.val1[c],tc.val2[c],0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|n, - skill_castend_damage_id); - if(skilllv > 6 && n==3 && c==4){ - skill_brandishspear_dir(&tc,dir,-1); - n--;c=-1; - } - } - } - /* 範?@ */ - for(c=0;c<10;c++){ - if(c==0||c==5) skill_brandishspear_dir(&tc,dir,-1); - map_foreachinarea(skill_area_sub, - bl->m,tc.val1[c%5],tc.val2[c%5],tc.val1[c%5],tc.val2[c%5],0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - } - } - break; - - /* パ?ティスキル */ - case AL_ANGELUS: /* エンジェラス */ - case PR_MAGNIFICAT: /* マグニフィカ?ト */ - case PR_GLORIA: /* グロリア */ - case SN_WINDWALK: /* ウインドウォ?ク */ - if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) { - /* 個別の?理 */ - clif_skill_nodamage(bl,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage) - break; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - } else if (sd) { - /* パ?ティ全?への?理 */ - party_foreachsamemap (skill_area_sub, - sd,1, - src,skillid,skilllv,tick, flag|BCT_PARTY|1, - skill_castend_nodamage_id); - } - break; - - case BS_ADRENALINE: /* アドレナリンラッシュ */ - case BS_WEAPONPERFECT: /* ウェポンパ?フェクション */ - case BS_OVERTHRUST: /* オ?バ?トラスト */ - if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) { - /* 個別の?理 */ - clif_skill_nodamage(bl,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,(src == bl)? 1:0,0,0,skill_get_time(skillid,skilllv),0); - } else if (sd) { - /* パ?ティ全?への?理 */ - party_foreachsamemap(skill_area_sub, - sd,1, - src,skillid,skilllv,tick, flag|BCT_PARTY|1, - skill_castend_nodamage_id); - } - break; - - /*(付加と解除が必要) */ - case BS_MAXIMIZE: /* マキシマイズパワ? */ - case NV_TRICKDEAD: /* 死んだふり */ - case CR_DEFENDER: /* ディフェンダ? */ - case CR_AUTOGUARD: /* オ?トガ?ド */ - { - struct status_change *tsc_data = status_get_sc_data(bl); - int sc = SkillStatusChangeTable[skillid]; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (tsc_data && tsc_data[sc].timer != -1) - status_change_end(bl, sc, -1); - else - status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - } - break; - - case TF_HIDING: /* ハイディング */ - { - struct status_change *tsc_data = status_get_sc_data(bl); - int sc = SkillStatusChangeTable[skillid]; - clif_skill_nodamage(src,bl,skillid,-1,1); - if (tsc_data && tsc_data[sc].timer != -1) - status_change_end(bl, sc, -1); - else - status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - } - break; - - case AS_CLOAKING: /* クロ?キング */ - { - struct status_change *tsc_data = status_get_sc_data(bl); - int sc=SkillStatusChangeTable[skillid]; - clif_skill_nodamage(src,bl,skillid,-1,1); - if(tsc_data && tsc_data[sc].timer!=-1 ) - /* 解除する */ - status_change_end(bl, sc, -1); - else - /* 付加する */ - status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - //skill_check_cloaking(bl); - } - break; - - case ST_CHASEWALK: /* ハイディング */ - { - struct status_change *tsc_data = status_get_sc_data(bl); - int sc=SkillStatusChangeTable[skillid]; - clif_skill_nodamage(src,bl,skillid,-1,1); - if(tsc_data && tsc_data[sc].timer!=-1 ) - /* 解除する */ - status_change_end(bl, sc, -1); - else - /* 付加する */ - status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - } - break; - - /* ?地スキル */ - case BD_LULLABY: /* 子守唄 */ - case BD_RICHMANKIM: /* ニヨルドの宴 */ - case BD_ETERNALCHAOS: /* 永遠の混沌 */ - case BD_DRUMBATTLEFIELD: /* ?太鼓の響き */ - case BD_RINGNIBELUNGEN: /* ニ?ベルングの指輪 */ - case BD_ROKISWEIL: /* ロキの叫び */ - case BD_INTOABYSS: /* 深淵の中に */ - case BD_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - case BA_DISSONANCE: /* 不協和音 */ - case BA_POEMBRAGI: /* ブラギの詩 */ - case BA_WHISTLE: /* 口笛 */ - case BA_ASSASSINCROSS: /* 夕陽のアサシンクロス */ - case BA_APPLEIDUN: /* イドゥンの林檎 */ - case DC_UGLYDANCE: /* 自分勝手なダンス */ - case DC_HUMMING: /* ハミング */ - case DC_DONTFORGETME: /* 私を忘れないで… */ - case DC_FORTUNEKISS: /* 幸運のキス */ - case DC_SERVICEFORYOU: /* サ?ビスフォ?ユ? */ -// case CG_MOONLIT: /* 月明りの泉に落ちる花びら */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_unitsetting(src,skillid,skilllv,src->x,src->y,0); - break; - - case HP_BASILICA: /* バジリカ */ - { - struct skill_unit_group *sg; - battle_stopwalking(src,1); - skill_clear_unitgroup(src); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0); - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,(int)sg, - skill_get_time(skillid,skilllv),0); - } - break; - - case PA_GOSPEL: /* ゴスペル */ - skill_clear_unitgroup(src); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_unitsetting(src,skillid,skilllv,src->x,src->y,0); - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,BCT_SELF,skill_get_time(skillid,skilllv),0); - break; - - case BD_ADAPTATION: /* アドリブ */ - { - struct status_change *sc_data = status_get_sc_data(src); - if(sc_data && sc_data[SC_DANCING].timer!=-1){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_stop_dancing(src,0); - } - } - break; - - case BA_FROSTJOKE: /* 寒いジョ?ク */ - case DC_SCREAM: /* スクリ?ム */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_addtimerskill(src,tick+3000,bl->id,0,0,skillid,skilllv,0,flag); - break; - - case TF_STEAL: // スティ?ル - if(sd) { - if(pc_steal_item(sd,bl)) - clif_skill_nodamage(src,bl,skillid,skilllv,1); - else - clif_skill_fail(sd,skillid,0x0a,0); - } - break; - - case RG_STEALCOIN: // スティ?ルコイン - if(sd) { - if(pc_steal_coin(sd,bl)) { - int range = skill_get_range(skillid,skilllv); - if(range < 0) - range = status_get_range(src) - (range + 1); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - mob_target((struct mob_data *)bl,src,range); - } - else - clif_skill_fail(sd,skillid,0,0); - } - break; - - case MG_STONECURSE: /* スト?ンカ?ス */ - { - struct status_change *sc_data = status_get_sc_data(bl); - // Level 6-10 doesn't consume a red gem if it fails [celest] - int i, gem_flag = 1, fail_flag = 0; - if (dstmd && status_get_mode(bl)&0x20) { - clif_skill_fail(sd,sd->skillid,0,0); - break; - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage ) - break; - if (sc_data && sc_data[SC_STONE].timer != -1) { - status_change_end(bl,SC_STONE,-1); - if (sd) { - fail_flag = 1; - clif_skill_fail(sd,skillid,0,0); - } - } - else if( rand()%100 < skilllv*4+20 && !battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) - status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - else if(sd) { - if (skilllv > 5) gem_flag = 0; - clif_skill_fail(sd,skillid,0,0); - fail_flag = 1; - } - if (dstmd) - mob_target(dstmd,src,skill_get_range(skillid,skilllv)); - if (sd && gem_flag) { - if ((i=pc_search_inventory(sd, skill_db[skillid].itemid[0])) < 0 ) { - if (!fail_flag) clif_skill_fail(sd,sd->skillid,0,0); - break; - } - pc_delitem(sd, i, skill_db[skillid].amount[0], 0); - } - } - break; - - case NV_FIRSTAID: /* ?急手? */ - clif_skill_nodamage(src,bl,skillid,5,1); - battle_heal(NULL,bl,5,0,0); - break; - - case AL_CURE: /* キュア? */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage ) - break; - status_change_end(bl, SC_SILENCE , -1 ); - status_change_end(bl, SC_BLIND , -1 ); - status_change_end(bl, SC_CONFUSION, -1 ); - if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//アンデッドなら暗闇?果 - status_change_start(bl, SC_CONFUSION,1,0,0,0,6000,0); - } - break; - - case TF_DETOXIFY: /* 解毒 */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_end(bl, SC_POISON , -1 ); - status_change_end(bl, SC_DPOISON , -1 ); - break; - - case PR_STRECOVERY: /* リカバリ? */ - { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage) - break; - status_change_end(bl, SC_FREEZE , -1 ); - status_change_end(bl, SC_STONE , -1 ); - status_change_end(bl, SC_SLEEP , -1 ); - status_change_end(bl, SC_STAN , -1 ); - if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//アンデッドなら暗闇?果 - if(rand()%100 < (100-(status_get_int(bl)/2+status_get_vit(bl)/3+status_get_luk(bl)/10))) { - status_change_start(bl, SC_BLIND,1,0,0,0, - 1000 * 30 * (100-(status_get_int(bl)+status_get_vit(bl))/2)/100,0); - } - } - if(dstmd){ - dstmd->attacked_id=0; - dstmd->target_id=0; - dstmd->state.targettype = NONE_ATTACKABLE; - dstmd->state.skillstate=MSS_IDLE; - dstmd->next_walktime=tick+rand()%3000+3000; - } - } - break; - - case WZ_ESTIMATION: /* モンスタ?情報 */ - if(sd) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - clif_skill_estimation((struct map_session_data *)src,bl); - } - break; - - case MC_IDENTIFY: /* アイテム鑑定 */ - if(sd) - clif_item_identify_list(sd); - break; - - case BS_REPAIRWEAPON: /* 武器修理 */ - if(sd) { -//動作しないのでとりあえずコメントアウト - /*if (pc_search_inventory(sd, 999) < 0 ) { //fixed by Lupus (item pos can be = 0!) - clif_skill_fail(sd,sd->skillid,0,0); - map_freeblock_unlock(); - return 1; - }*/ - clif_item_repair_list(sd); - } - break; - - case MC_VENDING: /* 露店開設 */ - if(sd) - clif_openvendingreq(sd,2+sd->skilllv); - break; - - case AL_TELEPORT: /* テレポ?ト */ - if(sd) { - if (map[sd->bl.m].flag.noteleport) { /* テレポ禁止 */ - clif_skill_teleportmessage(sd,0); - break; - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(sd->skilllv == 1) - clif_skill_warppoint(sd,sd->skillid,"Random","","",""); - else { - clif_skill_warppoint(sd,sd->skillid,"Random", - sd->status.save_point.map,"",""); - } - } else if(dstmd) - mob_warp(dstmd,-1,-1,-1,3); - break; - - case AL_HOLYWATER: /* アクアベネディクタ */ - if(sd) { - int eflag; - struct item item_tmp; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = 523; - item_tmp.identify = 1; - if(battle_config.holywater_name_input) { - item_tmp.card[0] = 0xfe; - item_tmp.card[1] = 0; - *((unsigned long *)(&item_tmp.card[2]))=sd->char_id; /* キャラID */ - } - eflag = pc_additem(sd,&item_tmp,1); - if(eflag) { - clif_additem(sd,0,0,eflag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - break; - case TF_PICKSTONE: - if(sd) { - int eflag; - struct item item_tmp; - struct block_list tbl; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - memset(&item_tmp,0,sizeof(item_tmp)); - memset(&tbl,0,sizeof(tbl)); // [MouseJstr] - item_tmp.nameid = 7049; - item_tmp.identify = 1; - tbl.id = 0; - clif_takeitem(&sd->bl,&tbl); - eflag = pc_additem(sd,&item_tmp,1); - if(eflag) { - clif_additem(sd,0,0,eflag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - break; - - case RG_STRIPWEAPON: /* ストリップウェポン */ - case RG_STRIPSHIELD: /* ストリップシールド */ - case RG_STRIPARMOR: /* ストリップアーマー */ - case RG_STRIPHELM: /* ストリップヘルム */ - { - struct status_change *tsc_data; - int strip_time, strip_per, strip_fix; - int scid, cp_scid = 0, equip; - - tsc_data = status_get_sc_data(bl); - scid = SkillStatusChangeTable[skillid]; - switch (skillid) { - case RG_STRIPWEAPON: - equip = EQP_WEAPON; - cp_scid = SC_CP_WEAPON; - break; - case RG_STRIPSHIELD: - equip = EQP_SHIELD; - cp_scid = SC_CP_SHIELD; - break; - case RG_STRIPARMOR: - equip = EQP_ARMOR; - cp_scid = SC_CP_ARMOR; - break; - case RG_STRIPHELM: - equip = EQP_HELM; - cp_scid = SC_CP_HELM; - break; - default: - map_freeblock_unlock(); - return 1; - } - - if (tsc_data && (tsc_data[scid].timer != -1 || tsc_data[cp_scid].timer != -1)) - break; - if (dstsd && dstsd->unstripable_equip & equip) - break; - - strip_fix = status_get_dex(src) - status_get_dex(bl); - if(strip_fix < 0) - strip_fix=0; - strip_per = 5+5*skilllv+strip_fix/5; - if (rand()%100 >= strip_per) - break; - - if (dstsd) { - for (i=0;i<MAX_INVENTORY;i++) { - if (dstsd->status.inventory[i].equip && (dstsd->status.inventory[i].equip & equip)){ - pc_unequipitem(dstsd,i,3); - break; - } - } - if (i == MAX_INVENTORY) - break; - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - status_change_start(bl,scid,skilllv,0,0,0,strip_time,0 ); - break; - } - case ST_FULLSTRIP: // Celest - { - struct status_change *tsc_data; - int i, j, strip_time, strip_per, strip_fix; - int equip[4] = { EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM }; - int scid[4] = { SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM }; - int cp_scid[4] = { SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM }; - - tsc_data = status_get_sc_data(bl); - strip_fix = status_get_dex(src) - status_get_dex(bl); - if(strip_fix < 0) - strip_fix = 0; - strip_per = 5+5*skilllv+strip_fix/5; - if (rand()%100 >= strip_per) - break; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - - for (i=0; i<4; i++) { - if (dstsd) { - if (tsc_data && (tsc_data[scid[i]].timer != -1 || tsc_data[cp_scid[i]].timer != -1)) - continue; - if (dstsd->unstripable_equip & equip[i]) - continue; - for (j=0; j<MAX_INVENTORY; j++) { - if (dstsd->status.inventory[j].equip && (dstsd->status.inventory[j].equip & equip[i])){ - pc_unequipitem(dstsd,j,3); - break; - } - } - if (j == MAX_INVENTORY) - continue; - } - status_change_start(bl,scid[i],skilllv,0,0,0,strip_time,0 ); - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - break; - } - - /* PotionPitcher */ - case AM_POTIONPITCHER: /* ポ?ションピッチャ? */ - { - struct block_list tbl; - int i,x,hp = 0,sp = 0; - if(sd) { - x = skilllv%11 - 1; - i = pc_search_inventory(sd,skill_db[skillid].itemid[x]); - if(i < 0 || skill_db[skillid].itemid[x] <= 0) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 1; - } - if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill_db[skillid].amount[x]) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 1; - } - sd->state.potionpitcher_flag = 1; - sd->potion_hp = sd->potion_sp = sd->potion_per_hp = sd->potion_per_sp = 0; - sd->skilltarget = bl->id; - run_script(sd->inventory_data[i]->use_script,0,sd->bl.id,0); - pc_delitem(sd,i,skill_db[skillid].amount[x],0); - sd->state.potionpitcher_flag = 0; - if(sd->potion_per_hp > 0 || sd->potion_per_sp > 0) { - hp = status_get_max_hp(bl) * sd->potion_per_hp / 100; - hp = hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100; - if(dstsd) { - sp = dstsd->status.max_sp * sd->potion_per_sp / 100; - sp = sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100; - } - } - else { - if(sd->potion_hp > 0) { - hp = sd->potion_hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100; - hp = hp * (100 + (status_get_vit(bl)<<1)) / 100; - if(dstsd) - hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100; - } - if(sd->potion_sp > 0) { - sp = sd->potion_sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100; - sp = sp * (100 + (status_get_int(bl)<<1)) / 100; - if(dstsd) - sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10) / 100; - } - } - } - else { - hp = (1 + rand()%400) * (100 + skilllv*10) / 100; - hp = hp * (100 + (status_get_vit(bl)<<1)) / 100; - if(dstsd) - hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100; - } - tbl.id = 0; - tbl.m = src->m; - tbl.x = src->x; - tbl.y = src->y; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(hp > 0 || (hp <= 0 && sp <= 0)) - clif_skill_nodamage(&tbl,bl,AL_HEAL,hp,1); - if(sp > 0) - clif_skill_nodamage(&tbl,bl,MG_SRECOVERY,sp,1); - battle_heal(src,bl,hp,sp,0); - } - break; - case AM_CP_WEAPON: - case AM_CP_SHIELD: - case AM_CP_ARMOR: - case AM_CP_HELM: - { - int scid = SC_STRIPWEAPON + (skillid - AM_CP_WEAPON); - struct status_change *tsc_data = status_get_sc_data(bl); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(tsc_data && tsc_data[scid].timer != -1) - status_change_end(bl, scid, -1 ); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - } - break; - - case SA_DISPELL: /* ディスペル */ - { - int i; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage ) - break; - for(i=0;i<136;i++){ - if(i==SC_RIDING || i== SC_FALCON || i==SC_HALLUCINATION || i==SC_WEIGHT50 - || i==SC_WEIGHT90 || i==SC_STRIPWEAPON || i==SC_STRIPSHIELD || i==SC_STRIPARMOR - || i==SC_STRIPHELM || i==SC_CP_WEAPON || i==SC_CP_SHIELD || i==SC_CP_ARMOR - || i==SC_CP_HELM || i==SC_COMBO) - continue; - status_change_end(bl,i,-1); - } - } - break; - - case TF_BACKSLIDING: /* バックステップ */ - battle_stopwalking(src,1); - skill_blown(src,bl,skill_get_blewcount(skillid,skilllv)|0x10000); - if (sd) - clif_fixpos(src); - else if (md) - clif_fixmobpos(md); - else if (src->type == BL_PET) - clif_fixpetpos((struct pet_data *)src); - skill_addtimerskill(src,tick + 200,src->id,0,0,skillid,skilllv,0,flag); - break; - - case SA_CASTCANCEL: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_castcancel(src,1); - if(sd) { - int sp = skill_get_sp(sd->skillid_old,sd->skilllv_old); - sp = sp * (90 - (skilllv-1)*20) / 100; - if(sp < 0) sp = 0; - pc_heal(sd,0,-sp); - } - break; - case SA_SPELLBREAKER: // スペルブレイカ? - { - struct status_change *sc_data = status_get_sc_data(bl); - int sp; - if(sc_data && sc_data[SC_MAGICROD].timer != -1) { - if(dstsd) { - sp = skill_get_sp(skillid,skilllv); - sp = sp * sc_data[SC_MAGICROD].val2 / 100; - if(sp > 0x7fff) sp = 0x7fff; - else if(sp < 1) sp = 1; - if(dstsd->status.sp + sp > dstsd->status.max_sp) { - sp = dstsd->status.max_sp - dstsd->status.sp; - dstsd->status.sp = dstsd->status.max_sp; - } - else - dstsd->status.sp += sp; - clif_heal(dstsd->fd,SP_SP,sp); - } - clif_skill_nodamage(bl,bl,SA_MAGICROD,sc_data[SC_MAGICROD].val1,1); - if(sd) { - sp = sd->status.max_sp/5; - if(sp < 1) sp = 1; - pc_heal(sd,0,-sp); - } - } - else { - int bl_skillid=0,bl_skilllv=0; - if(bl->type == BL_PC) { - if(dstsd && dstsd->skilltimer != -1) { - bl_skillid = dstsd->skillid; - bl_skilllv = dstsd->skilllv; - } - } - else if(bl->type == BL_MOB) { - if(dstmd && dstmd->skilltimer != -1) { - bl_skillid = dstmd->skillid; - bl_skilllv = dstmd->skilllv; - } - } - if(bl_skillid > 0 && skill_db[bl_skillid].skill_type == BF_MAGIC) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_castcancel(bl,0); - sp = skill_get_sp(bl_skillid,bl_skilllv); - if(dstsd) - pc_heal(dstsd,0,-sp); - if(sd) { - sp = sp*(25*(skilllv-1))/100; - if(skilllv > 1 && sp < 1) sp = 1; - if(sp > 0x7fff) sp = 0x7fff; - else if(sp < 1) sp = 1; - if(sd->status.sp + sp > sd->status.max_sp) { - sp = sd->status.max_sp - sd->status.sp; - sd->status.sp = sd->status.max_sp; - } - else - sd->status.sp += sp; - clif_heal(sd->fd,SP_SP,sp); - } - } - else if(sd) - clif_skill_fail(sd,skillid,0,0); - } - } - break; - case SA_MAGICROD: - if (dstsd && dstsd->special_state.no_magic_damage ) - break; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - case SA_AUTOSPELL: /* オ?トスペル */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(sd) - clif_autospell(sd,skilllv); - else { - int maxlv=1,spellid=0; - static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT }; - if(skilllv >= 10) { - spellid = MG_FROSTDIVER; - maxlv = skilllv - 9; - } - else if(skilllv >=8) { - spellid = MG_FIREBALL; - maxlv = skilllv - 7; - } - else if(skilllv >=5) { - spellid = MG_SOULSTRIKE; - maxlv = skilllv - 4; - } - else if(skilllv >=2) { - int i = rand()%3; - spellid = spellarray[i]; - maxlv = skilllv - 1; - } - else if(skilllv > 0) { - spellid = MG_NAPALMBEAT; - maxlv = 3; - } - if(spellid > 0) - status_change_start(src,SC_AUTOSPELL,skilllv,spellid,maxlv,0, - skill_get_time(SA_AUTOSPELL,skilllv),0); - } - break; - - /* ランダム?性?化、水?性?化、地、火、風 */ - case NPC_ATTRICHANGE: - case NPC_CHANGEWATER: - case NPC_CHANGEGROUND: - case NPC_CHANGEFIRE: - case NPC_CHANGEWIND: - /* 毒、聖、念、闇 */ - case NPC_CHANGEPOISON: - case NPC_CHANGEHOLY: - case NPC_CHANGEDARKNESS: - case NPC_CHANGETELEKINESIS: - if(md){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - md->def_ele=skill_get_pl(skillid); - if(md->def_ele==0) /* ランダム?化、ただし、*/ - md->def_ele=rand()%10; /* 不死?性は除く */ - md->def_ele+=(1+rand()%4)*20; /* ?性レベルはランダム */ - } - break; - - case NPC_PROVOCATION: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(md) - clif_pet_performance(src,mob_db[md->class_].skill[md->skillidx].val[0]); - break; - - case NPC_HALLUCINATION: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage ) - break; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case NPC_KEEPING: - case NPC_BARRIER: - { - int skill_time = skill_get_time(skillid,skilllv); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_time,0 ); - if (md) - mob_changestate(md,MS_DELAY,skill_time); - else if (sd) - sd->attackabletime = sd->canmove_tick = tick + skill_time; - } - break; - - case NPC_DARKBLESSING: - { - int sc_def = 100 - status_get_mdef(bl); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && dstsd->special_state.no_magic_damage ) - break; - if(status_get_elem_type(bl) == 7 || status_get_race(bl) == 6) - break; - if(rand()%100 < sc_def*(50+skilllv*5)/100) { - if(dstsd) { - int hp = status_get_hp(bl)-1; - pc_heal(dstsd,-hp,0); - } - else if(dstmd) - dstmd->hp = 1; - } - } - break; - - case NPC_SELFDESTRUCTION: /* 自爆 */ - case NPC_SELFDESTRUCTION2: /* 自爆2 */ - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0); - break; - case NPC_LICK: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (dstsd) { - if (dstsd->special_state.no_weapon_damage ) - break; - pc_heal(dstsd,0,-100); - } - if(rand()%100 < (skilllv*5)*sc_def_vit/100) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - - case NPC_SUICIDE: /* 自決 */ - if(src && bl){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (md) - mob_damage(NULL,md,md->hp,0); - else if (sd) - pc_damage(NULL,sd,sd->status.hp); - } - break; - - case NPC_SUMMONSLAVE: /* 手下召喚 */ - case NPC_SUMMONMONSTER: /* MOB召喚 */ - if(md) - mob_summonslave(md,mob_db[md->class_].skill[md->skillidx].val,skilllv,(skillid==NPC_SUMMONSLAVE)?1:0); - break; - - case NPC_RECALL: //取り巻き呼び戻し - if(md) { - int mobcount; - md->recallcount = 0;//初期化 - md->recall_flag = 0; - mobcount = mob_countslave(md); - if(mobcount > 0) { - md->recall_flag = 1; //mob.cの[取り巻きモンスターの処理]で利用 - md->recallmob_count = mobcount; - } - } - break; - - case NPC_RUNAWAY: //後退 - if(md) { - int check; - int dist = skilllv;//後退する距離 - check = md->dir; //自分がどの方向に向いてるかチェック - md->attacked_id = 0; - md->target_id = 0; - md->state.targettype = NONE_ATTACKABLE; - md->state.skillstate = MSS_IDLE; - switch (check) { - case 0: //自分の向いてる方向と逆に移動する - mob_walktoxy(md,md->bl.x,md->bl.y-dist,0);//そして、移動する - break; - case 1: - mob_walktoxy(md,md->bl.x-dist,md->bl.y-dist,0); - break; - case 2: - mob_walktoxy(md,md->bl.x+dist,md->bl.y,0); - break; - case 3: - mob_walktoxy(md,md->bl.x+dist,md->bl.y+dist,0); - break; - case 4: - mob_walktoxy(md,md->bl.x,md->bl.y+dist,0); - break; - case 5: - mob_walktoxy(md,md->bl.x-dist,md->bl.y+dist,0); - break; - case 6: - mob_walktoxy(md,md->bl.x-dist,md->bl.y,0); - break; - case 7: - mob_walktoxy(md,md->bl.x-dist,md->bl.y-dist,0); - break; - } - } - break; - - case NPC_TRANSFORMATION: - case NPC_METAMORPHOSIS: - if(md) - mob_class_change(md,mob_db[md->class_].skill[md->skillidx].val); - break; - - case NPC_EMOTION: /* エモ?ション */ - if(md) - clif_emotion(&md->bl,mob_db[md->class_].skill[md->skillidx].val[0]); - break; - - case NPC_DEFENDER: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - break; - - // Equipment breaking monster skills [Celest] - case NPC_BREAKWEAPON: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && battle_config.equipment_breaking) - pc_breakweapon(dstsd); - break; - - case NPC_BREAKARMOR: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && battle_config.equipment_breaking) - pc_breakarmor(dstsd); - break; - - case NPC_BREAKHELM: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && battle_config.equipment_breaking) - pc_breakhelm(dstsd); - break; - - case NPC_BREAKSHIELD: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstsd && battle_config.equipment_breaking) - pc_breakshield(dstsd); - break; - - case NPC_EXPLOSIONSPIRITS: //NPC爆裂波動 - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SC_EXPLOSIONSPIRITS,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - break; - - case WE_MALE: /* 君だけは護るよ */ - if(sd && dstsd){ - int hp_rate=(skilllv <= 0)? 0:skill_db[skillid].hp_rate[skilllv-1]; - int gain_hp=sd->status.max_hp*abs(hp_rate)/100;// 15% - clif_skill_nodamage(src,bl,skillid,gain_hp,1); - battle_heal(NULL,bl,gain_hp,0,0); - } - break; - case WE_FEMALE: /* あなたの?に?牲になります */ - if(sd && dstsd){ - int sp_rate=(skilllv <= 0)? 0:skill_db[skillid].sp_rate[skilllv-1]; - int gain_sp=sd->status.max_sp*abs(sp_rate)/100;// 15% - clif_skill_nodamage(src,bl,skillid,gain_sp,1); - battle_heal(NULL,bl,0,gain_sp,0); - } - break; - - case WE_CALLPARTNER: /* あなたに?いたい */ - if(sd && dstsd){ - if((dstsd = pc_get_partner(sd)) == NULL){ - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - if(map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto || map[dstsd->bl.m].flag.nowarp){ - clif_skill_teleportmessage(sd,1); - map_freeblock_unlock(); - return 0; - } - skill_unitsetting(src,skillid,skilllv,sd->bl.x,sd->bl.y,0); - } - break; - -// parent-baby skills - case WE_BABY: - if(sd && dstsd){ - struct map_session_data *f_sd = pc_get_father(sd); - struct map_session_data *m_sd = pc_get_mother(sd); - // if neither was found - if(!f_sd && !m_sd){ - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if (f_sd) status_change_start(&f_sd->bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - if (m_sd) status_change_start(&m_sd->bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - } - break; - - case WE_CALLPARENT: - if(sd && dstsd){ - struct map_session_data *f_sd = pc_get_father(sd); - struct map_session_data *m_sd = pc_get_mother(sd); - // if neither was found - if(!f_sd && !m_sd){ - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - if(map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto || map[dstsd->bl.m].flag.nowarp){ - clif_skill_teleportmessage(sd,1); - map_freeblock_unlock(); - return 0; - } - if (f_sd) pc_setpos(f_sd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,3); - if (m_sd) pc_setpos(f_sd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,3); - } - break; - - case WE_CALLBABY: - if(sd && dstsd){ - if((dstsd = pc_get_child(sd)) == NULL){ - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - if(map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto || map[dstsd->bl.m].flag.nowarp){ - clif_skill_teleportmessage(sd,1); - map_freeblock_unlock(); - return 0; - } - pc_setpos(dstsd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,3); - } - break; - - case PF_HPCONVERSION: /* ライフ置き換え */ - clif_skill_nodamage(src, bl, skillid, skilllv, 1); - if (sd) { - int hp, sp; - hp = sd->status.max_hp / 10; //基本はHPの10% - sp = hp * 10 * skilllv / 100; - if (sd->status.sp + sp > sd->status.max_sp) - sp = sd->status.max_sp - sd->status.sp; - // we need to check with the sp that was taken away when casting too - if (sd->status.sp + skill_get_sp(skillid, skilllv) >= sd->status.max_sp) - hp = sp = 0; - pc_heal(sd, -hp, sp); - clif_heal(sd->fd, SP_SP, sp); - clif_updatestatus(sd, SP_SP); - } - break; - case HT_REMOVETRAP: /* リム?ブトラップ */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - { - struct skill_unit *su=NULL; - struct item item_tmp; - int flag; - if((bl->type==BL_SKILL) && - (su=(struct skill_unit *)bl) && - (su->group->src_id == src->id || map[bl->m].flag.pvp || map[bl->m].flag.gvg) && - (su->group->unit_id >= 0x8f && su->group->unit_id <= 0x99) && - (su->group->unit_id != 0x92)){ //?を取り返す - if(sd){ - if(battle_config.skill_removetrap_type == 1){ - for(i=0;i<10;i++) { - if(skill_db[su->group->skill_id].itemid[i] > 0){ - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = skill_db[su->group->skill_id].itemid[i]; - item_tmp.identify = 1; - if(item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,skill_db[su->group->skill_id].amount[i]))){ - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,skill_db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - } - }else{ - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = 1065; - item_tmp.identify = 1; - if(item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,1))){ - clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - - } - if(su->group->unit_id == 0x91 && su->group->val2){ - struct block_list *target=map_id2bl(su->group->val2); - if(target && (target->type == BL_PC || target->type == BL_MOB)) - status_change_end(target,SC_ANKLE,-1); - } - skill_delunit(su); - } - } - break; - case HT_SPRINGTRAP: /* スプリングトラップ */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - { - struct skill_unit *su=NULL; - if((bl->type==BL_SKILL) && (su=(struct skill_unit *)bl) && (su->group) ){ - switch(su->group->unit_id){ - case 0x91: // ankle snare - if (su->group->val2 != 0) - // if it is already trapping something don't spring it, - // remove trap should be used instead - break; - // otherwise fallthrough to below - case 0x8f: /* ブラストマイン */ - case 0x90: /* スキッドトラップ */ - case 0x93: /* ランドマイン */ - case 0x94: /* ショックウェ?ブトラップ */ - case 0x95: /* サンドマン */ - case 0x96: /* フラッシャ? */ - case 0x97: /* フリ?ジングトラップ */ - case 0x98: /* クレイモア?トラップ */ - case 0x99: /* ト?キ?ボックス */ - su->group->unit_id = 0x8c; - clif_changelook(bl,LOOK_BASE,su->group->unit_id); - su->group->limit=DIFF_TICK(tick+1500,su->group->tick); - su->limit=DIFF_TICK(tick+1500,su->group->tick); - } - } - } - break; - case BD_ENCORE: /* アンコ?ル */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(sd) - skill_use_id(sd,src->id,sd->skillid_dance,sd->skilllv_dance); - break; - - case AS_SPLASHER: /* ベナムスプラッシャ? */ - if((double)status_get_max_hp(bl)*2/3 < status_get_hp(bl)) { //HPが2/3以上?っていたら失敗 - map_freeblock_unlock(); - return 1; - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,src->id,skill_get_time(skillid,skilllv),1000,0 ); - break; - - case PF_MINDBREAKER: /* プロボック */ - { - struct status_change *sc_data = status_get_sc_data(bl); - - /* MVPmobと不死には?かない */ - if((dstmd && status_get_mode(bl)&0x20) || battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) //不死には?かない - { - map_freeblock_unlock(); - return 1; - } - - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - - if(dstmd && dstmd->skilltimer!=-1 && dstmd->state.skillcastcancel) // 詠唱妨害 - skill_castcancel(bl,0); - if(dstsd && dstsd->skilltimer!=-1 && (!dstsd->special_state.no_castcancel || map[bl->m].flag.gvg) - && dstsd->state.skillcastcancel && !dstsd->special_state.no_castcancel2) - skill_castcancel(bl,0); - - if(sc_data){ - if(sc_data[SC_FREEZE].timer!=-1) - status_change_end(bl,SC_FREEZE,-1); - if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) - status_change_end(bl,SC_STONE,-1); - if(sc_data[SC_SLEEP].timer!=-1) - status_change_end(bl,SC_SLEEP,-1); - } - - if(dstmd) - mob_target(dstmd,src,skill_get_range(skillid,skilllv)); - } - break; - - case PF_SOULCHANGE: - { - int sp1 = 0, sp2 = 0; - if (sd) { - if (dstsd) { - sp1 = sd->status.sp > dstsd->status.max_sp ? dstsd->status.max_sp : sd->status.sp; - sp2 = dstsd->status.sp > sd->status.max_sp ? sd->status.max_sp : dstsd->status.sp; - sd->status.sp = sp2; - dstsd->status.sp = sp1; - clif_heal(sd->fd,SP_SP,sp2); - clif_updatestatus(sd,SP_SP); - clif_heal(dstsd->fd,SP_SP,sp1); - clif_updatestatus(dstsd,SP_SP); - } else if (dstmd) { - if (dstmd->state.soul_change_flag) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - sp2 = sd->status.max_sp * 3 /100; - if (sd->status.sp + sp2 > sd->status.max_sp) - sp2 = sd->status.max_sp - sd->status.sp; - sd->status.sp += sp2; - clif_heal(sd->fd,SP_SP,sp2); - clif_updatestatus(sd,SP_SP); - dstmd->state.soul_change_flag = 1; - } - } - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } - break; - - case PF_SPIDERWEB: /* スパイダ?ウェッブ */ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_unitsetting(src,skillid,skilllv,bl->x,bl->y,0); - break; - - // Weapon Refining [Celest] - case WS_WEAPONREFINE: - if(sd) - clif_item_refine_list(sd); - break; - - // Slim Pitcher - case CR_SLIMPITCHER: - { - if (sd && flag&1) { - struct block_list tbl; - int hp = sd->potion_hp * (100 + pc_checkskill(sd,CR_SLIMPITCHER)*10 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100; - hp = hp * (100 + (status_get_vit(bl)<<1))/100; - if (dstsd) { - hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10)/100; - } - tbl.id = 0; - tbl.m = src->m; - tbl.x = src->x; - tbl.y = src->y; - clif_skill_nodamage(&tbl,bl,AL_HEAL,hp,1); - battle_heal(NULL,bl,hp,0,0); - } - } - break; - // Full Chemical Protection - case CR_FULLPROTECTION: - { - int i, skilltime; - struct status_change *tsc_data = status_get_sc_data(bl); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skilltime = skill_get_time(skillid,skilllv); - for (i=0; i<4; i++) { - if(tsc_data && tsc_data[SC_STRIPWEAPON + i].timer != -1) - status_change_end(bl, SC_STRIPWEAPON + i, -1 ); - status_change_start(bl,SC_CP_WEAPON + i,skilllv,0,0,0,skilltime,0 ); - } - } - break; - - case RG_CLEANER: //AppleGirl - clif_skill_nodamage(src,bl,skillid,skilllv,1); - { - struct skill_unit *su=NULL; - if((bl->type==BL_SKILL) && - (su=(struct skill_unit *)bl) && - (su->group->src_id == src->id || map[bl->m].flag.pvp || map[bl->m].flag.gvg) && - (su->group->unit_id == 0xb0)){ //?を取り返す - if(sd) - skill_delunit(su); - } - } - break; - case ST_PRESERVE: - if (sd){ - if (sd->sc_count && sd->sc_data[SC_PRESERVE].timer != -1) - status_change_end(src, SC_PRESERVE, -1 ); - else - status_change_start(src,SC_PRESERVE,skilllv,0,0,0,skill_get_time(skillid, skilllv),0 ); - clif_skill_nodamage(src,src,skillid,skilllv,1); - } - break; - - // New guild skills [Celest] - case GD_BATTLEORDER: - { - struct guild *g = NULL; - // Only usable during WoE - if (!agit_flag) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - if(flag&1) { - if (dstsd && dstsd->status.guild_id == sd->status.guild_id) { - status_change_start(&dstsd->bl,SC_BATTLEORDERS,skilllv,0,0,0,0,0 ); - } - } - else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) && - strcmp(sd->status.name,g->master)==0) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - map_foreachinarea(skill_area_sub, - src->m,src->x-15,src->y-15,src->x+15,src->y+15,0, - src,skillid,skilllv,tick, flag|BCT_ALL|1, - skill_castend_nodamage_id); - pc_blockskill_start (sd, skillid, 300000); - } - } - break; - case GD_REGENERATION: - { - struct guild *g = NULL; - // Only usable during WoE - if (!agit_flag) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - if(flag&1) { - if (dstsd && dstsd->status.guild_id == sd->status.guild_id) { - status_change_start(&dstsd->bl,SC_REGENERATION,skilllv,0,0,0,0,0 ); - } - } - else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) && - strcmp(sd->status.name,g->master)==0) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - map_foreachinarea(skill_area_sub, - src->m,src->x-15,src->y-15,src->x+15,src->y+15,0, - src,skillid,skilllv,tick, flag|BCT_ALL|1, - skill_castend_nodamage_id); - pc_blockskill_start (sd, skillid, 300000); - } - } - break; - case GD_RESTORE: - { - struct guild *g = NULL; - // Only usable during WoE - if (!agit_flag) { - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - if(flag&1) { - if (dstsd && dstsd->status.guild_id == sd->status.guild_id) { - int hp, sp; - hp = dstsd->status.max_hp*9/10; - sp = dstsd->status.max_sp*9/10; - sp = dstsd->status.sp + sp <= dstsd->status.max_sp ? sp : dstsd->status.max_sp - dstsd->status.sp; - clif_skill_nodamage(src,bl,AL_HEAL,hp,1); - battle_heal(NULL,bl,hp,sp,0); - } - } - else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) && - strcmp(sd->status.name,g->master)==0) { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - map_foreachinarea(skill_area_sub, - src->m,src->x-15,src->y-15,src->x+15,src->y+15,0, - src,skillid,skilllv,tick, flag|BCT_ALL|1, - skill_castend_nodamage_id); - pc_blockskill_start (sd, skillid, 300000); - } - } - break; - case GD_EMERGENCYCALL: - { - int dx[9]={-1, 1, 0, 0,-1, 1,-1, 1, 0}; - int dy[9]={ 0, 0, 1,-1, 1,-1,-1, 1, 0}; - int j = 0; - struct guild *g = NULL; - // Only usable during WoE - if (!agit_flag || - (sd && map[sd->bl.m].flag.nowarpto && // if not allowed to warp to the map - guild_mapname2gc(sd->mapname) == NULL)) { // and it's not a castle... - clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - // i don't know if it actually summons in a circle, but oh well. ;P - if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) && - strcmp(sd->status.name,g->master)==0) { - for(i = 0; i < g->max_member; i++, j++) { - if (j>8) j=0; - if ((dstsd = g->member[i].sd) != NULL && sd != dstsd) { - if (map[dstsd->bl.m].flag.nowarp && - guild_mapname2gc(sd->mapname) == NULL) - continue; - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(map_getcell(sd->bl.m,sd->bl.x+dx[j],sd->bl.y+dy[j],CELL_CHKNOPASS)) - dx[j] = dy[j] = 0; - pc_setpos(dstsd, sd->mapname, sd->bl.x+dx[j], sd->bl.y+dy[j], 2); - } - } - pc_blockskill_start (sd, skillid, 300000); - } - } - break; - - default: - printf("Unknown skill used:%d\n",skillid); - map_freeblock_unlock(); - return 1; - } - - map_freeblock_unlock(); - return 0; -} - -/*========================================== - * スキル使用(詠唱完了、ID指定) - *------------------------------------------ - */ -int skill_castend_id( int tid, unsigned int tick, int id,int data ) -{ - struct map_session_data* sd = map_id2sd(id)/*,*target_sd=NULL*/; - struct block_list *bl; - int range,inf2; - - nullpo_retr(0, sd); - - if( sd->bl.prev == NULL ) //prevが無いのはありなの? - return 0; - - if(sd->skillid != SA_CASTCANCEL && sd->skilltimer != tid ) /* タイマIDの確認 */ - return 0; - if(sd->skillid != SA_CASTCANCEL && sd->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) > 0) { - sd->speed = sd->prev_speed; - clif_updatestatus(sd,SP_SPEED); - } - if(sd->skillid != SA_CASTCANCEL) - sd->skilltimer=-1; - - if((bl=map_id2bl(sd->skilltarget))==NULL || bl->prev==NULL) { - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - if(sd->bl.m != bl->m || pc_isdead(sd)) { //マップが違うか自分が死んでいる - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - - if(sd->skillid == PR_LEXAETERNA) { - struct status_change *sc_data = status_get_sc_data(bl); - if(sc_data && (sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - else if(sd->skillid == RG_BACKSTAP) { - int dir = map_calc_dir(&sd->bl,bl->x,bl->y),t_dir = status_get_dir(bl); - int dist = distance(sd->bl.x,sd->bl.y,bl->x,bl->y); - if(bl->type != BL_SKILL && (dist == 0 || map_check_dir(dir,t_dir))) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - - inf2 = skill_get_inf2(sd->skillid); - if( ( (skill_get_inf(sd->skillid)&1) || inf2&4 ) && // 彼我敵??係チェック - battle_check_target(&sd->bl,bl, BCT_ENEMY)<=0 ) { - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - if(inf2 & 0xC00 && sd->bl.id != bl->id) { - int fail_flag = 1; - if(inf2 & 0x400 && battle_check_target(&sd->bl,bl, BCT_PARTY) > 0) - fail_flag = 0; - if(inf2 & 0x800 && sd->status.guild_id > 0 && sd->status.guild_id == status_get_guild_id(bl)) - fail_flag = 0; - if(fail_flag) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - - range = skill_get_range(sd->skillid,sd->skilllv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - range += battle_config.pc_skill_add_range; - if((sd->skillid == MO_EXTREMITYFIST && sd->sc_data[SC_COMBO].timer != -1 && sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH) || - (sd->skillid == CH_TIGERFIST && sd->sc_data[SC_COMBO].timer != -1 && sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH) || - (sd->skillid == CH_CHAINCRUSH && sd->sc_data[SC_COMBO].timer != -1 && sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH) || - (sd->skillid == CH_CHAINCRUSH && sd->sc_data[SC_COMBO].timer != -1 && sd->sc_data[SC_COMBO].val1 == CH_TIGERFIST)) - range += skill_get_blewcount(MO_COMBOFINISH,sd->sc_data[SC_COMBO].val2); - if(battle_config.skill_out_range_consume) { // changed to allow casting when target walks out of range [Valaris] - if(range < distance(sd->bl.x,sd->bl.y,bl->x,bl->y)) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - if(!skill_check_condition(sd,1)) { /* 使用?件チェック */ - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - sd->skillitem = sd->skillitemlv = -1; - if(battle_config.skill_out_range_consume) { - if(range < distance(sd->bl.x,sd->bl.y,bl->x,bl->y)) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - return 0; - } - } - - if(battle_config.pc_skill_log) - printf("PC %d skill castend skill=%d\n",sd->bl.id,sd->skillid); - pc_stop_walking(sd,0); - - switch( skill_get_nk(sd->skillid) ) - { - /* 攻?系/吹き飛ばし系 */ - case 0: case 2: - skill_castend_damage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0); - break; - case 1:/* 支援系 */ - if( (sd->skillid==AL_HEAL || (sd->skillid==ALL_RESURRECTION && bl->type != BL_PC) || sd->skillid==PR_ASPERSIO) && battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) - skill_castend_damage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0); - else - skill_castend_nodamage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0); - break; - } - - return 0; -} - -/*========================================== - * スキル使用(詠唱完了、場所指定の?際の?理) - *------------------------------------------ - */ -int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skilllv,unsigned int tick,int flag) -{ - struct map_session_data *sd=NULL; - int i,tmpx = 0,tmpy = 0, x1 = 0, y1 = 0; - - //if(skilllv <= 0) return 0; - if(skillid > 0 && skilllv <= 0) return 0; // celest - - nullpo_retr(0, src); - - if(src->type==BL_PC){ - nullpo_retr(0, sd=(struct map_session_data *)src); - } - if( skillid != WZ_METEOR && - skillid != AM_CANNIBALIZE && - skillid != AM_SPHEREMINE) - clif_skill_poseffect(src,skillid,skilllv,x,y,tick); - - if (sd && skillnotok(skillid, sd)) // [MouseJstr] - return 0; - - switch(skillid) - { - case PR_BENEDICTIO: /* 聖?降福 */ - skill_area_temp[1]=src->id; - map_foreachinarea(skill_area_sub, - src->m,x-1,y-1,x+1,y+1,0, - src,skillid,skilllv,tick, flag|BCT_NOENEMY|1, - skill_castend_nodamage_id); - map_foreachinarea(skill_area_sub, - src->m,x-1,y-1,x+1,y+1,0, - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); - break; - - case BS_HAMMERFALL: /* ハンマ?フォ?ル */ - { - int r = 2; - if (skilllv > 5) { - r = 14; - skilllv = 5; // スタン率上がりすぎるため計算はLv5で固定 - } - skill_area_temp[1] = src->id; - skill_area_temp[2] = x; - skill_area_temp[3] = y; - map_foreachinarea (skill_area_sub, - src->m, x-r, y-r, x+r, y+r, 0, - src, skillid, skilllv, tick, flag|BCT_ENEMY|2, - skill_castend_nodamage_id); - } - break; - - case HT_DETECTING: /* ディテクティング */ - { - int range=skilllv*2+1; - if(src->x!=x) - x+=(src->x-x>0)?-range:range; - if(src->y!=y) - y+=(src->y-y>0)?-range:range; - map_foreachinarea( status_change_timer_sub, - src->m, x-range, y-range, x+range,y+range,0, - src,SC_SIGHT,tick); - } - break; - - case MG_SAFETYWALL: /* セイフティウォ?ル */ - case MG_FIREWALL: /* ファイヤ?ウォ?ル */ - case MG_THUNDERSTORM: /* サンダ?スト?ム */ - case AL_PNEUMA: /* ニュ?マ */ - case WZ_ICEWALL: /* アイスウォ?ル */ - case WZ_FIREPILLAR: /* ファイアピラ? */ - case WZ_QUAGMIRE: /* クァグマイア */ - case WZ_VERMILION: /* ロ?ドオブヴァ?ミリオン */ - //case WZ_FROSTNOVA: /* フロストノヴァ */ - case WZ_STORMGUST: /* スト?ムガスト */ - case WZ_HEAVENDRIVE: /* ヘヴンズドライブ */ - case PR_SANCTUARY: /* サンクチュアリ */ - case PR_MAGNUS: /* マグヌスエクソシズム */ - case CR_GRANDCROSS: /* グランドクロス */ - case NPC_DARKGRANDCROSS: /*闇グランドクロス*/ - case HT_SKIDTRAP: /* スキッドトラップ */ - case HT_LANDMINE: /* ランドマイン */ - case HT_ANKLESNARE: /* アンクルスネア */ - case HT_SHOCKWAVE: /* ショックウェ?ブトラップ */ - case HT_SANDMAN: /* サンドマン */ - case HT_FLASHER: /* フラッシャ? */ - case HT_FREEZINGTRAP: /* フリ?ジングトラップ */ - case HT_BLASTMINE: /* ブラストマイン */ - case HT_CLAYMORETRAP: /* クレイモア?トラップ */ - case AS_VENOMDUST: /* ベノムダスト */ - case AM_DEMONSTRATION: /* デモンストレ?ション */ - case PF_FOGWALL: /* フォグウォ?ル */ - case HT_TALKIEBOX: /* ト?キ?ボックス */ - skill_unitsetting(src,skillid,skilllv,x,y,0); - break; - - case RG_GRAFFITI: /* Graffiti [Valaris] */ - skill_clear_unitgroup(src); - skill_unitsetting(src,skillid,skilllv,x,y,0); - break; - - case SA_VOLCANO: /* ボルケ?ノ */ - case SA_DELUGE: /* デリュ?ジ */ - case SA_VIOLENTGALE: /* バイオレントゲイル */ - case SA_LANDPROTECTOR: /* ランドプロテクタ? */ - skill_clear_element_field(src);//?に自分が?動している?性場をクリア - skill_unitsetting(src,skillid,skilllv,x,y,0); - break; - - case WZ_METEOR: //メテオスト?ム - { - int flag=0; - for(i=0;i<2+(skilllv>>1);i++) { - int j=0; - do { - tmpx = x + (rand()%7 - 3); - tmpy = y + (rand()%7 - 3); - if(tmpx < 0) - tmpx = 0; - else if(tmpx >= map[src->m].xs) - tmpx = map[src->m].xs - 1; - if(tmpy < 0) - tmpy = 0; - else if(tmpy >= map[src->m].ys) - tmpy = map[src->m].ys - 1; - j++; - } while((map_getcell(src->m,tmpx,tmpy,CELL_CHKNOPASS)) && j<100); - if(j >= 100) - continue; - if(flag==0){ - clif_skill_poseffect(src,skillid,skilllv,tmpx,tmpy,tick); - flag=1; - } - if(i > 0) - skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skillid,skilllv,(x1<<16)|y1,flag); - x1 = tmpx; - y1 = tmpy; - } - skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skillid,skilllv,-1,flag); - } - break; - - case AL_WARP: /* ワ?プポ?タル */ - if(sd) { - if(map[sd->bl.m].flag.noteleport) /* テレポ禁止 */ - break; - clif_skill_warppoint(sd,sd->skillid,sd->status.save_point.map, - (sd->skilllv>1)?sd->status.memo_point[0].map:"", - (sd->skilllv>2)?sd->status.memo_point[1].map:"", - (sd->skilllv>3)?sd->status.memo_point[2].map:""); - } - break; - case MO_BODYRELOCATION: - if(sd){ - pc_movepos(sd,x,y); - }else if( src->type==BL_MOB ) - mob_warp((struct mob_data *)src,-1,x,y,0); - if (sd) - pc_blockskill_start (sd, MO_EXTREMITYFIST, 2000); - break; - case AM_CANNIBALIZE: // バイオプラント - if(sd) { - int id; - int summons[5] = { 1020, 1068, 1118, 1500, 1368 }; - struct mob_data *md; - - // Correct info, don't change any of this! [celest] - id = mob_once_spawn (sd, "this", x, y, "--ja--", summons[skilllv-1] ,1,""); - - if( (md=(struct mob_data *)map_id2bl(id)) !=NULL ){ - md->master_id = sd->bl.id; - // different levels of HP according to skill level - md->hp = 1500 + skilllv * 200 + sd->status.base_level * 10; - md->state.special_mob_ai = 1; - //非移動でアクティブで反撃する[0x0:非移動 0x1:移動 0x4:ACT 0x8:非ACT 0x40:反撃無 0x80:反撃有] - md->mode = 0x0 + 0x4 + 0x80; - md->deletetimer = add_timer (gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, id, 0); - } - // To-do: 召還されるモンスターには召還したプレーヤーの名前が付きます - // (attach name of player?) - clif_skill_poseffect(src,skillid,skilllv,x,y,tick); - } - break; - case AM_SPHEREMINE: // スフィア?マイン - if(sd){ - int id; - struct mob_data *md; - - id = mob_once_spawn(sd, "this", x, y, "--ja--", 1142, 1, ""); - if( (md=(struct mob_data *)map_id2bl(id)) !=NULL ){ - md->master_id = sd->bl.id; - md->hp = 2000 + skilllv * 400; - md->state.special_mob_ai = 2; - md->deletetimer = add_timer (gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, id, 0); - } - clif_skill_poseffect(src,skillid,skilllv,x,y,tick); - } - break; - - // Slim Pitcher [Celest] - case CR_SLIMPITCHER: - { - if (sd) { - int i = skilllv%11 - 1; - int j = pc_search_inventory(sd,skill_db[skillid].itemid[i]); - if(j < 0 || skill_db[skillid].itemid[i] <= 0 || sd->inventory_data[j] == NULL || - sd->status.inventory[j].amount < skill_db[skillid].amount[i]) { - clif_skill_fail(sd,skillid,0,0); - return 1; - } - sd->state.potionpitcher_flag = 1; - sd->potion_hp = 0; - run_script(sd->inventory_data[j]->use_script,0,sd->bl.id,0); - pc_delitem(sd,j,skill_db[skillid].amount[i],0); - sd->state.potionpitcher_flag = 0; - clif_skill_poseffect(src,skillid,skilllv,x,y,tick); - if(sd->potion_hp > 0) { - map_foreachinarea(skill_area_sub, - src->m,x-3,y-3,x+3,y+3,0, - src,skillid,skilllv,tick,flag|BCT_PARTY|1, - skill_castend_nodamage_id); - } - } - } - break; - } - - return 0; -} - -/*========================================== - * スキル使用(詠唱完了、map指定) - *------------------------------------------ - */ -int skill_castend_map( struct map_session_data *sd,int skill_num, const char *map) -{ - int x=0,y=0; - - nullpo_retr(0, sd); - if( sd->bl.prev == NULL || pc_isdead(sd) ) - return 0; - - if(skillnotok(skill_num, sd)) - return 0; - - if( sd->opt1>0 || sd->status.option&2 ) - return 0; - //スキルが使えない?態異常中 - if(sd->sc_count){ - if( sd->sc_data[SC_DIVINA].timer!=-1 || - sd->sc_data[SC_ROKISWEIL].timer!=-1 || - sd->sc_data[SC_AUTOCOUNTER].timer != -1 || - sd->sc_data[SC_STEELBODY].timer != -1 || - sd->sc_data[SC_DANCING].timer!=-1 || - sd->sc_data[SC_BERSERK].timer != -1 || - sd->sc_data[SC_MARIONETTE].timer != -1) - return 0; - } - - if( skill_num != sd->skillid) /* 不正パケットらしい */ - return 0; - - pc_stopattack(sd); - - if(battle_config.pc_skill_log) - printf("PC %d skill castend skill =%d map=%s\n",sd->bl.id,skill_num,map); - pc_stop_walking(sd,0); - - if(strcmp(map,"cancel")==0) - return 0; - - switch(skill_num){ - case AL_TELEPORT: /* テレポ?ト */ - if(strcmp(map,"Random")==0) - pc_randomwarp(sd,3); - else - pc_setpos(sd,sd->status.save_point.map, - sd->status.save_point.x,sd->status.save_point.y,3); - break; - - case AL_WARP: /* ワ?プポ?タル */ - { - const struct point *p[4]; - struct skill_unit_group *group; - int i; - int maxcount=0; - p[0] = &sd->status.save_point; - p[1] = &sd->status.memo_point[0]; - p[2] = &sd->status.memo_point[1]; - p[3] = &sd->status.memo_point[2]; - - if((maxcount = skill_get_maxcount(sd->skillid)) > 0) { - int c; - for(i=c=0;i<MAX_SKILLUNITGROUP;i++) { - if(sd->skillunit[i].alive_count > 0 && sd->skillunit[i].skill_id == sd->skillid) - c++; - } - if(c >= maxcount) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = gettick(); - sd->canmove_tick = gettick(); - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - - if(sd->skilllv <= 0) return 0; - for(i=0;i<sd->skilllv;i++){ - if(strcmp(map,p[i]->map)==0){ - x=p[i]->x; - y=p[i]->y; - break; - } - } - if(x==0 || y==0) /* 不正パケット? */ - return 0; - - if(!skill_check_condition(sd,3)) - return 0; - if((group=skill_unitsetting(&sd->bl,sd->skillid,sd->skilllv,sd->skillx,sd->skilly,0))==NULL) - return 0; - group->valstr=(char *)aCallocA(24,sizeof(char)); - memcpy(group->valstr,map,24); - group->val2=(x<<16)|y; - } - break; - } - - return 0; -} - -/*========================================== - * スキルユニット設定?理 - *------------------------------------------ - */ -struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,int flag) -{ - struct skill_unit_group *group; - int i,limit,val1=0,val2=0,val3=0; - int count=0; - int target,interval,range,unit_flag; - struct skill_unit_layout *layout; - struct status_change *sc_data; - int active_flag=1; - - nullpo_retr(0, src); - - limit = skill_get_time(skillid,skilllv); - range = skill_get_unit_range(skillid); - interval = skill_get_unit_interval(skillid); - target = skill_get_unit_target(skillid); - unit_flag = skill_get_unit_flag(skillid); - layout = skill_get_unit_layout(skillid,skilllv,src,x,y); - - if (unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy) - target = BCT_NOENEMY; - - sc_data = status_get_sc_data(src); // for firewall and fogwall - celest - - switch(skillid){ /* 設定 */ - - case MG_SAFETYWALL: /* セイフティウォ?ル */ - val2=skilllv+1; - break; - case MG_FIREWALL: /* ファイヤ?ウォ?ル */ - if(sc_data && sc_data[SC_VIOLENTGALE].timer!=-1) - limit = limit*3/2; - val2=4+skilllv; - break; - - case AL_WARP: /* ワ?プポ?タル */ - val1=skilllv+6; - if(flag==0) - limit=2000; - active_flag=0; - break; - - case PR_SANCTUARY: /* サンクチュアリ */ - val1=(skilllv+3)*2; - val2=(skilllv>6)?777:skilllv*100; - interval += 500; - break; - - case WZ_FIREPILLAR: /* ファイア?ピラ? */ - if(flag!=0) - limit=1000; - val1=skilllv+2; - if(skilllv >= 6) - range=2; - break; - case WZ_METEOR: - if (skilllv > 10) //広範囲メテオ - range = 10; - break; - case WZ_VERMILION: - if (skilllv > 10) //広範囲LOV - range = 25; - break; - - case HT_SANDMAN: /* サンドマン */ - case HT_CLAYMORETRAP: /* クレイモア?トラップ */ - case HT_SKIDTRAP: /* スキッドトラップ */ - case HT_LANDMINE: /* ランドマイン */ - case HT_ANKLESNARE: /* アンクルスネア */ - case HT_FLASHER: /* フラッシャ? */ - case HT_FREEZINGTRAP: /* フリ?ジングトラップ */ - case HT_BLASTMINE: /* ブラストマイン */ - // longer trap times in WOE [celest] - if (map[src->m].flag.gvg) limit *= 4; - break; - case HT_SHOCKWAVE: /* ショックウェ?ブトラップ */ - val1=skilllv*15+10; - break; - - case SA_LANDPROTECTOR: /* グランドクロス */ - { - int aoe_diameter; // -- aoe_diameter (moonsoul) added for sage Area Of Effect skills - val1=skilllv*15+10; - aoe_diameter=skilllv+skilllv%2+5; - count=aoe_diameter*aoe_diameter; // -- this will not function if changed to ^2 (moonsoul) - } - break; - - case BA_WHISTLE: /* 口笛 */ - if(src->type == BL_PC) - val1 = (pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON)+1)>>1; - val2 = ((status_get_agi(src)/10)&0xffff)<<16; - val2 |= (status_get_luk(src)/10)&0xffff; - break; - case DC_HUMMING: /* ハミング */ - if(src->type == BL_PC) - val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1; - val2 = status_get_dex(src)/10; - break; - case DC_DONTFORGETME: /* 私を忘れないで… */ - if(src->type == BL_PC) - val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1; - val2 = ((status_get_dex(src)/20)&0xffff)<<16; - val2 |= (status_get_agi(src)/10)&0xffff; - break; - case BA_POEMBRAGI: /* ブラギの詩 */ - if(src->type == BL_PC) - val1 = pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON); - val2 = ((status_get_dex(src)/10)&0xffff)<<16; - val2 |= (status_get_int(src)/5)&0xffff; - break; - case BA_APPLEIDUN: /* イドゥンの林檎 */ - if(src->type == BL_PC) - val1 = pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON)&0xffff; - val2 |= (status_get_vit(src))&0xffff; - val3 = 0;//回復用タイムカウンタ(6秒?に1?加) - break; - case DC_SERVICEFORYOU: /* サ?ビスフォ?ユ? */ - if(src->type == BL_PC) - val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1; - val2 = status_get_int(src)/10; - break; - case BA_ASSASSINCROSS: /* 夕陽のアサシンクロス */ - if(src->type == BL_PC) - val1 = (pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON)+1)>>1; - val2 = status_get_agi(src)/20; - break; - case DC_FORTUNEKISS: /* 幸運のキス */ - if(src->type == BL_PC) - val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1; - val2 = status_get_luk(src)/10; - break; - - case PF_FOGWALL: /* フォグウォ?ル */ - if(sc_data && sc_data[SC_DELUGE].timer!=-1) limit *= 2; - break; - - case RG_GRAFFITI: /* Graffiti */ - count=1; // Leave this at 1 [Valaris] - break; - } - - nullpo_retr(NULL, group=skill_initunitgroup(src,(count > 0 ? count : layout->count), - skillid,skilllv,skill_get_unit_id(skillid,flag&1))); - group->limit=limit; - group->val1=val1; - group->val2=val2; - group->val3=val3; - group->target_flag=target; - group->interval=interval; - if(skillid==HT_TALKIEBOX || - skillid==RG_GRAFFITI){ - group->valstr=(char *) aCallocA(80, 1); - if(group->valstr==NULL){ - printf("skill_castend_map: out of memory !\n"); - exit(1); - } - memcpy(group->valstr,talkie_mes,80); - } - for(i=0;i<layout->count;i++){ - struct skill_unit *unit; - int ux,uy,val1=skilllv,val2=0,limit=group->limit,alive=1; - ux = x + layout->dx[i]; - uy = y + layout->dy[i]; - switch (skillid) { - case MG_FIREWALL: /* ファイヤ?ウォ?ル */ - val2=group->val2; - break; - case WZ_ICEWALL: /* アイスウォ?ル */ - if(skilllv <= 1) - val1 = 500; - else - val1 = 200 + 200*skilllv; - break; - case RG_GRAFFITI: /* Graffiti [Valaris] */ - ux+=(i%5-2); - uy+=(i/5-2); - break; - } - //直上スキルの場合設置座標上にランドプロテクタ?がないかチェック - if(range<=0) - map_foreachinarea(skill_landprotector,src->m,ux,uy,ux,uy,BL_SKILL,skillid,&alive); - - if(skillid==WZ_ICEWALL && alive){ - val2=map_getcell(src->m,ux,uy,CELL_GETTYPE); - if(val2==5 || val2==1) - alive=0; - else { - map_setcell(src->m,ux,uy,5); - clif_changemapcell(src->m,ux,uy,5,0); - } - } - - if(alive){ - nullpo_retr(NULL, unit=skill_initunit(group,i,ux,uy)); - unit->val1=val1; - unit->val2=val2; - unit->limit=limit; - unit->range=range; - - if (range==0 && active_flag) - map_foreachinarea(skill_unit_effect,unit->bl.m - ,unit->bl.x,unit->bl.y,unit->bl.x,unit->bl.y - ,0,&unit->bl,gettick(),1); - } - } - - return group; -} - -/*========================================== - * スキルユニットの?動イベント - *------------------------------------------ - */ -int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int tick) -{ - struct skill_unit_group *sg; - struct block_list *ss; - struct skill_unit *unit2; - struct status_change *sc_data; - int type; - - nullpo_retr(0, src); - nullpo_retr(0, bl); - - if(bl->prev==NULL || !src->alive || - (bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))) - return 0; - - nullpo_retr(0, sg=src->group); - nullpo_retr(0, ss=map_id2bl(sg->src_id)); - - sc_data = status_get_sc_data(bl); - type = SkillStatusChangeTable[sg->skill_id]; - - if (battle_check_target(&src->bl,bl,sg->target_flag)<=0) - return 0; - - // 対象がLP上に居る場合は無効 - if (map_find_skill_unit_oncell(bl,bl->x,bl->y,SA_LANDPROTECTOR,NULL)) - return 0; - - switch (sg->unit_id) { - case 0x85: /* ニューマ */ - case 0x7e: /* セイフティウォール */ - if (sc_data && sc_data[type].timer == -1) - status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0); - break; - - case 0x80: /* ワープポータル(発動後) */ - if(bl->type==BL_PC){ - struct map_session_data *sd = (struct map_session_data *)bl; - if(sd && src->bl.m == bl->m && src->bl.x == bl->x && src->bl.y == bl->y && - src->bl.x == sd->to_x && src->bl.y == sd->to_y) { - if( battle_config.chat_warpportal || !sd->chatID ){ - pc_setpos(sd,sg->valstr,sg->val2>>16,sg->val2&0xffff,3); - if(sg->src_id == bl->id || (strcmp(map[src->bl.m].name,sg->valstr) == 0 && - src->bl.x == (sg->val2>>16) && src->bl.y == (sg->val2&0xffff) )) - skill_delunitgroup(sg); - if (--sg->val1<=0) - skill_delunitgroup(sg); - } - } - } else if(bl->type==BL_MOB && battle_config.mob_warpportal){ - int m = map_mapname2mapid(sg->valstr); - mob_warp((struct mob_data *)bl,m,sg->val2>>16,sg->val2&0xffff,3); - } - break; - - case 0x8e: /* クァグマイア */ - if(bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ) - break; - if(sc_data && sc_data[type].timer==-1) - status_change_start(bl,type,sg->skill_lv,(int)src,0,0, - skill_get_time2(sg->skill_id,sg->skill_lv),0); - break; - - case 0x9a: /* ボルケ?ノ */ - case 0x9b: /* デリュ?ジ */ - case 0x9c: /* バイオレントゲイル */ - if (sc_data && sc_data[type].timer!=-1) { - unit2 = (struct skill_unit *)sc_data[type].val4; - if (unit2 && unit2->group && - (unit2==src || DIFF_TICK(sg->tick,unit2->group->tick)<=0)) - break; - } - status_change_start(bl,type,sg->skill_lv,(int)src,0,0, - skill_get_time2(sg->skill_id,sg->skill_lv),0); - break; - - case 0x9e: /* 子守唄 */ - case 0x9f: /* ニヨルドの宴 */ - case 0xa0: /* 永遠の混沌 */ - case 0xa1: /* ?太鼓の響き */ - case 0xa2: /* ニ?ベルングの指輪 */ - case 0xa3: /* ロキの叫び */ - case 0xa4: /* 深淵の中に */ - case 0xa5: /* 不死身のジ?クフリ?ド */ - case 0xa6: /* 不協和音 */ - case 0xa7: /* 口笛 */ - case 0xa8: /* 夕陽のアサシンクロス */ - case 0xa9: /* ブラギの詩 */ - case 0xaa: /* イドゥンの林檎 */ - case 0xab: /* 自分勝手なダンス */ - case 0xac: /* ハミング */ - case 0xad: /* 私を忘れないで… */ - case 0xae: /* 幸運のキス */ - case 0xaf: /* サ?ビスフォ?ユ? */ - if (sg->src_id==bl->id) - break; - if (sc_data && sc_data[type].timer!=-1) { - unit2 = (struct skill_unit *)sc_data[type].val4; - if (unit2 && unit2->group && - (unit2 == src || DIFF_TICK(sg->tick,unit2->group->tick)<=0)) - break; - } - status_change_start(bl,type,sg->skill_lv,sg->val1,sg->val2, - (int)src,skill_get_time2(sg->skill_id,sg->skill_lv),0); - break; - - case 0xb4: // Basilica - if (battle_check_target(&src->bl,bl,BCT_NOENEMY)>0) { - if (sc_data && sc_data[type].timer!=-1) { - struct skill_unit_group *sg2 = (struct skill_unit_group *)sc_data[type].val4; - if (sg2 && (sg2 == src->group || DIFF_TICK(sg->tick,sg2->tick)<=0)) - break; - } else - status_change_start(bl,type,sg->skill_lv,(int)src,0,0, - skill_get_time2(sg->skill_id,sg->skill_lv),0); - } else if (!status_get_mode(bl)&0x20) - skill_blown(&src->bl,bl,1); - break; - - case 0xb6: /* フォグウォ?ル */ - if (sc_data && sc_data[type].timer!=-1) { - struct skill_unit_group *sg2 = (struct skill_unit_group *)sc_data[type].val4; - if (sg2 && (sg2 == src->group || DIFF_TICK(sg->tick,sg2->tick)<=0)) - break; - } - status_change_start (bl, type, sg->skill_lv, sg->val1, sg->val2, (int)sg, - skill_get_time2(sg->skill_id, sg->skill_lv), 0); - if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0) - skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, tick); - break; - - case 0xb2: /* あなたを_?いたいです */ - case 0xb3: /* ゴスペル */ - //とりあえず何もしない - break; - /* default: - if(battle_config.error_log) - printf("skill_unit_onplace: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id); - break;*/ - } - - return 0; -} - -/*========================================== - * スキルユニットの発動イベント(タイマー発動) - *------------------------------------------ - */ -int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsigned int tick) -{ - struct skill_unit_group *sg; - struct block_list *ss; - int splash_count=0; - struct status_change *sc_data; - struct skill_unit_group_tickset *ts; - int type; - int diff=0; - - nullpo_retr(0, src); - nullpo_retr(0, bl); - - if (bl->type!=BL_PC && bl->type!=BL_MOB) - return 0; - - if (bl->prev==NULL || !src->alive || - (bl->type==BL_PC && pc_isdead((struct map_session_data *)bl))) - return 0; - - nullpo_retr(0, sg=src->group); - nullpo_retr(0, ss=map_id2bl(sg->src_id)); - sc_data = status_get_sc_data(bl); - type = SkillStatusChangeTable[sg->skill_id]; - - // 対象がLP上に居る場合は無効 - if (map_find_skill_unit_oncell(bl,bl->x,bl->y,SA_LANDPROTECTOR,NULL)) - return 0; - - // 前に影響を受けてからintervalの間は影響を受けない - nullpo_retr(0,ts = skill_unitgrouptickset_search(bl,sg,tick)); - diff = DIFF_TICK(tick,ts->tick); - if (sg->skill_id == PR_SANCTUARY) - diff += 500; // 新規に回復したユニットだけカウントするための仕掛け - if (diff < 0) - return 0; - ts->tick = tick+sg->interval; - // GXは重なっていたら3HITしない - if (sg->skill_id==CR_GRANDCROSS && !battle_config.gx_allhit) - ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y)-1); - - switch (sg->unit_id) { - case 0x83: /* サンクチュアリ */ - { - int race = status_get_race(bl); - - if (battle_check_undead(race, status_get_elem_type(bl)) || race==6) { - if (skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0)) { - // reduce healing count if this was meant for damaging [hekate] - sg->val1 -= 2; - //sg->val1--; // チャットキャンセルに対応 - } - } else { - int heal = sg->val2; - if (status_get_hp(bl) >= status_get_max_hp(bl)) - break; - if (bl->type == BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage) - heal = 0; /* 黄金蟲カード(ヒール量0) */ - clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1); - battle_heal(NULL, bl, heal, 0, 0); - if (diff >= 500) - sg->val1--; // 新規に入ったユニットだけカウント - } - if (sg->val1 <= 0) - skill_delunitgroup(sg); - break; - } - - case 0x84: /* マグヌスエクソシズム */ - { - int race = status_get_race(bl); - if (!battle_check_undead(race,status_get_elem_type(bl)) && race!=6) - return 0; - skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - src->val2++; - break; - } - - case 0x7f: /* ファイヤーウォール */ - skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - if (--src->val2<=0) - skill_delunit(src); - break; - case 0x86: /* ロードオブヴァーミリオン(TS,MS,FN,SG,HD,GX,闇GX) */ - skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - break; - case 0x87: /* ファイアーピラー(発動前) */ - skill_delunit(src); - skill_unitsetting(ss,sg->skill_id,sg->skill_lv,src->bl.x,src->bl.y,1); - break; - - case 0x88: /* ファイアーピラー(発動後) */ - map_foreachinarea(skill_attack_area,bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, - BF_MAGIC,ss,&src->bl,sg->skill_id,sg->skill_lv,tick,0,BCT_ENEMY); // area damage [Celest] - //skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - break; - - case 0x90: /* スキッドトラップ */ - { - int i,c = skill_get_blewcount(sg->skill_id,sg->skill_lv); - if(map[bl->m].flag.gvg) c = 0; - for(i=0;i<c;i++) - skill_blown(&src->bl,bl,1|0x30000); - sg->unit_id = 0x8c; - clif_changelook(&src->bl,LOOK_BASE,sg->unit_id); - sg->limit=DIFF_TICK(tick,sg->tick)+1500; - } - break; - - case 0x93: /* ランドマイン */ - skill_attack(BF_MISC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - sg->unit_id = 0x8c; - clif_changelook(&src->bl,LOOK_BASE,0x88); - sg->limit=DIFF_TICK(tick,sg->tick)+1500; - break; - - case 0x8f: /* ブラストマイン */ - case 0x94: /* ショックウェ?ブトラップ */ - case 0x95: /* サンドマン */ - case 0x96: /* フラッシャ? */ - case 0x97: /* フリ?ジングトラップ */ - case 0x98: /* クレイモア?トラップ */ - map_foreachinarea(skill_count_target,src->bl.m - ,src->bl.x-src->range,src->bl.y-src->range - ,src->bl.x+src->range,src->bl.y+src->range - ,0,&src->bl,&splash_count); - map_foreachinarea(skill_trap_splash,src->bl.m - ,src->bl.x-src->range,src->bl.y-src->range - ,src->bl.x+src->range,src->bl.y+src->range - ,0,&src->bl,tick,splash_count); - sg->unit_id = 0x8c; - clif_changelook(&src->bl,LOOK_BASE,sg->unit_id); - sg->limit=DIFF_TICK(tick,sg->tick)+1500; - break; - - case 0x91: /* アンクルスネア */ - if(sg->val2==0 && sc_data && sc_data[SC_ANKLE].timer==-1){ - int moveblock = ( bl->x/BLOCK_SIZE != src->bl.x/BLOCK_SIZE || bl->y/BLOCK_SIZE != src->bl.y/BLOCK_SIZE); - int sec = skill_get_time2(sg->skill_id,sg->skill_lv) - status_get_agi(bl)*100; - if(status_get_mode(bl)&0x20) - sec = sec/5; - if (sec < 3000) // minimum time of 3 seconds [celest] - sec = 3000; - battle_stopwalking(bl,1); - status_change_start(bl,SC_ANKLE,sg->skill_lv,0,0,0,sec,0); - - skill_unit_move(bl,tick,0); - if(moveblock) map_delblock(bl); - bl->x = src->bl.x; - bl->y = src->bl.y; - if(moveblock) map_addblock(bl); - skill_unit_move(bl,tick,1); - if(bl->type == BL_MOB) - clif_fixmobpos((struct mob_data *)bl); - else if(bl->type == BL_PET) - clif_fixpetpos((struct pet_data *)bl); - else - clif_fixpos(bl); - clif_01ac(&src->bl); - sg->limit=DIFF_TICK(tick,sg->tick) + sec; - sg->val2=bl->id; - sg->interval = -1; - src->range = 0; - } - break; - - case 0x92: /* ベノムダスト */ - if(sc_data && sc_data[type].timer==-1 ) - status_change_start(bl,type,sg->skill_lv,(int)src,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0); - break; - - case 0xb1: /* デモンストレ?ション */ - skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - if(bl->type == BL_PC && rand()%100 < sg->skill_lv && battle_config.equipment_breaking) - pc_breakweapon((struct map_session_data *)bl); - break; - - case 0x99: /* トーキーボックス */ - if(sg->src_id == bl->id) //自分が踏んでも発動しない - break; - if(sg->val2==0){ - clif_talkiebox(&src->bl,sg->valstr); - sg->unit_id = 0x8c; - clif_changelook(&src->bl,LOOK_BASE,sg->unit_id); - sg->limit=DIFF_TICK(tick,sg->tick)+5000; - sg->val2=-1; //踏んだ - } - break; - - // Basilica - case 0xb4: /* バジリカ */ - if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0 && - !(status_get_mode(bl)&0x20)) - skill_blown(&src->bl,bl,1); - if (sg->src_id==bl->id) - break; - if (battle_check_target(&src->bl,bl,BCT_NOENEMY)>0 && sc_data && sc_data[type].timer == -1) - status_change_start(bl,type,sg->skill_lv,(int)src,0,0, - skill_get_time2(sg->skill_id,sg->skill_lv),0); - break; - - case 0xb7: /* スパイダ?ウェッブ */ - if(sg->val2==0){ - int moveblock = ( bl->x/BLOCK_SIZE != src->bl.x/BLOCK_SIZE || bl->y/BLOCK_SIZE != src->bl.y/BLOCK_SIZE); - skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,tick); - skill_unit_move(bl,tick,0); - if(moveblock) map_delblock(bl); - bl->x = src->bl.x; - bl->y = src->bl.y; - if(moveblock) map_addblock(bl); - skill_unit_move(bl,tick,1); - if(bl->type == BL_MOB) - clif_fixmobpos((struct mob_data *)bl); - else if(bl->type == BL_PET) - clif_fixpetpos((struct pet_data *)bl); - else - clif_fixpos(bl); - sg->limit = DIFF_TICK(tick,sg->tick)+skill_get_time2(sg->skill_id,sg->skill_lv); - sg->val2=bl->id; - sg->interval = -1; - src->range = 0; - } - break; - -/* default: - if(battle_config.error_log) - printf("skill_unit_onplace: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id); - break;*/ - } - - if(bl->type==BL_MOB && ss!=bl) /* スキル使用?件のMOBスキル */ - { - if(battle_config.mob_changetarget_byskill == 1) - { - int target=((struct mob_data *)bl)->target_id; - if(ss->type == BL_PC) - ((struct mob_data *)bl)->target_id=ss->id; - mobskill_use((struct mob_data *)bl,tick,MSC_SKILLUSED|(sg->skill_id<<16)); - ((struct mob_data *)bl)->target_id=target; - } - else - mobskill_use((struct mob_data *)bl,tick,MSC_SKILLUSED|(sg->skill_id<<16)); - } - - return 0; -} -/*========================================== - * スキルユニットから離?する(もしくはしている)場合 - *------------------------------------------ - */ -int skill_unit_onout(struct skill_unit *src,struct block_list *bl,unsigned int tick) -{ - struct skill_unit_group *sg; - struct status_change *sc_data; - int type; - - nullpo_retr(0, src); - nullpo_retr(0, bl); - nullpo_retr(0, sg=src->group); - sc_data = status_get_sc_data(bl); - type = SkillStatusChangeTable[sg->skill_id]; - - if (bl->prev==NULL || !src->alive || - (bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))) - return 0; - - switch(sg->unit_id){ - case 0x7e: /* セイフティウォール */ - case 0x85: /* ニューマ */ - case 0x8e: /* クァグマイア */ - case 0x9a: /* ボルケーノ */ - case 0x9b: /* デリュージ */ - case 0x9c: /* バイオレントゲイル */ - if (type==SC_QUAGMIRE && bl->type==BL_MOB) - break; - if (sc_data && sc_data[type].timer!=-1 && sc_data[type].val2==(int)src) { - status_change_end(bl,type,-1); - } - break; - case 0x91: /* アンクルスネア */ - { - struct block_list *target = map_id2bl(sg->val2); - if(target && target == bl){ - status_change_end(bl,SC_ANKLE,-1); - sg->limit=DIFF_TICK(tick,sg->tick)+1000; - } - break; - } - case 0x9e: /* 子守唄 */ - case 0x9f: /* ニヨルドの宴 */ - case 0xa0: /* 永遠の混沌 */ - case 0xa1: /* 戦太鼓の響き */ - case 0xa2: /* ニーベルングの指輪 */ - case 0xa3: /* ロキの叫び */ - case 0xa4: /* 深淵の中に */ - case 0xa5: /* 不死身のジークフリード */ - case 0xad: /* 私を忘れないで… */ - if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)src) { - status_change_end(bl,type,-1); - } - break; - - case 0xa6: /* 不協和音 */ - case 0xa7: /* 口笛 */ - case 0xa8: /* 夕陽のアサシンクロス */ - case 0xa9: /* ブラギの詩 */ - case 0xaa: /* イドゥンの林檎 */ - case 0xab: /* 自分勝手なダンス */ - case 0xac: /* ハミング */ - case 0xae: /* 幸運のキス */ - case 0xaf: /* サ?ビスフォ?ユ? */ - if (sg->src_id==bl->id) { - status_change_end(bl,type,-1); - break; - } - if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)src) { - sc_data[type].timer = add_timer(20000+tick, status_change_timer, bl->id, type); - } - break; - - case 0xb4: // Basilica - if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)sg) { - status_change_end(bl,type,-1); - } - break; - - case 0xb6: - { - if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)sg) { - status_change_end(bl,SC_FOGWALL,-1); - if (sc_data && sc_data[SC_BLIND].timer!=-1) - sc_data[SC_BLIND].timer = add_timer( - gettick() + 30000, status_change_timer, bl->id, 0); - } - break; - } - - case 0xb7: /* スパイダ?ウェッブ */ - { - struct block_list *target = map_id2bl(sg->val2); - if (target && target==bl) - status_change_end(bl,SC_SPIDERWEB,-1); - sg->limit = DIFF_TICK(tick,sg->tick)+1000; - break; - } - -/* default: - if(battle_config.error_log) - printf("skill_unit_onout: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id); - break;*/ - } - - return 0; -} - -/*========================================== - * スキルユニット効果発動/離脱処理(foreachinarea) - * bl: ユニット(BL_PC/BL_MOB) - *------------------------------------------ - */ -int skill_unit_effect(struct block_list *bl,va_list ap) -{ - struct skill_unit *unit; - struct skill_unit_group *group; - int flag; - unsigned int tick; - static int called = 0; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, unit=va_arg(ap,struct skill_unit*)); - tick = va_arg(ap,unsigned int); - flag = va_arg(ap,unsigned int); - - if (bl->type!=BL_PC && bl->type!=BL_MOB) - return 0; - - if (!unit->alive || bl->prev==NULL) - return 0; - - nullpo_retr(0, group=unit->group); - - if (flag) - skill_unit_onplace(unit,bl,tick); - else { - skill_unit_onout(unit,bl,tick); - unit = map_find_skill_unit_oncell(bl,bl->x,bl->y,group->skill_id,unit); - if (unit && called == 0) { - called = 1; - skill_unit_onplace(unit,bl,tick); - called = 0; - } - } - - return 0; -} - -/*========================================== - * スキルユニットの限界イベント - *------------------------------------------ - */ -int skill_unit_onlimit(struct skill_unit *src,unsigned int tick) -{ - struct skill_unit_group *sg; - nullpo_retr(0, src); - nullpo_retr(0, sg=src->group); - - switch(sg->unit_id){ - case 0x81: /* ワ?プポ?タル(?動前) */ - { - struct skill_unit_group *group= - skill_unitsetting(map_id2bl(sg->src_id),sg->skill_id,sg->skill_lv, - src->bl.x,src->bl.y,1); - if(group == NULL) - return 0; - group->valstr=(char *) aCallocA(24, 1); - if(group->valstr==NULL){ - printf("skill_unit_onlimit: out of memory !\n"); - exit(1); - } - memcpy(group->valstr,sg->valstr,24); - group->val2=sg->val2; - } - break; - - case 0x8d: /* アイスウォ?ル */ - map_setcell(src->bl.m,src->bl.x,src->bl.y,src->val2); - clif_changemapcell(src->bl.m,src->bl.x,src->bl.y,src->val2,1); - break; - case 0xb2: /* あなたに?いたい */ - { - struct map_session_data *sd = NULL; - struct map_session_data *p_sd = NULL; - if((sd = map_id2sd(sg->src_id)) == NULL) - return 0; - if((p_sd = pc_get_partner(sd)) == NULL) - return 0; - - pc_setpos(p_sd,map[src->bl.m].name,src->bl.x,src->bl.y,3); - } - break; - } - return 0; -} -/*========================================== - * スキルユニットのダメ?ジイベント - *------------------------------------------ - */ -int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl, - int damage,unsigned int tick) -{ - struct skill_unit_group *sg; - - nullpo_retr(0, src); - nullpo_retr(0, sg=src->group); - - switch(sg->unit_id){ - case 0x8d: /* アイスウォ?ル */ - src->val1-=damage; - break; - case 0x8f: /* ブラストマイン */ - case 0x98: /* クレイモア?トラップ */ - skill_blown(bl,&src->bl,2); //吹き飛ばしてみる - break; - default: - damage = 0; - break; - } - return damage; -} - - -/*---------------------------------------------------------------------------- */ - -/*========================================== - * スキル使用(詠唱完了、場所指定) - *------------------------------------------ - */ -int skill_castend_pos( int tid, unsigned int tick, int id,int data ) -{ - struct map_session_data* sd=map_id2sd(id)/*,*target_sd=NULL*/; - int range,maxcount; - - nullpo_retr(0, sd); - - if( sd->bl.prev == NULL ) - return 0; - if( sd->skilltimer != tid ) /* タイマIDの確認 */ - return 0; - if(sd->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) > 0) { - sd->speed = sd->prev_speed; - clif_updatestatus(sd,SP_SPEED); - } - sd->skilltimer=-1; - if(pc_isdead(sd)) { - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - - /*case MG_SAFETYWALL: - case WZ_FIREPILLAR: - case HT_SKIDTRAP: - case HT_LANDMINE: - case HT_ANKLESNARE: - case HT_SHOCKWAVE: - case HT_SANDMAN: - case HT_FLASHER: - case HT_FREEZINGTRAP: - case HT_BLASTMINE: - case HT_CLAYMORETRAP: - case HT_TALKIEBOX: - case AL_WARP: - case PF_SPIDERWEB: - case RG_GRAFFITI: - range = 0; - break; - case AL_PNEUMA: - range = 1; - break;*/ - if (!battle_config.pc_skill_reiteration && - skill_get_unit_flag(sd->skillid)&UF_NOREITERATION && - skill_check_unit_range(sd->bl.m,sd->skillx,sd->skilly,sd->skillid,sd->skilllv)) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - /*case WZ_FIREPILLAR: - case HT_SKIDTRAP: - case HT_LANDMINE: - case HT_ANKLESNARE: - case HT_SHOCKWAVE: - case HT_SANDMAN: - case HT_FLASHER: - case HT_FREEZINGTRAP: - case HT_BLASTMINE: - case HT_CLAYMORETRAP: - case HT_TALKIEBOX: - case PF_SPIDERWEB: - case WZ_ICEWALL: - range = 2; - break; - case AL_WARP: - range = 0; - break;*/ - if (battle_config.pc_skill_nofootset && - skill_get_unit_flag(sd->skillid)&UF_NOFOOTSET && - skill_check_unit_range2(&sd->bl,sd->bl.m,sd->skillx,sd->skilly,sd->skillid,sd->skilllv)) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - if(battle_config.pc_land_skill_limit) { - maxcount = skill_get_maxcount(sd->skillid); - if(maxcount > 0) { - int i,c; - for(i=c=0;i<MAX_SKILLUNITGROUP;i++) { - if(sd->skillunit[i].alive_count > 0 && sd->skillunit[i].skill_id == sd->skillid) - c++; - } - if(c >= maxcount) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - } - - if(sd->skilllv <= 0) return 0; - range = skill_get_range(sd->skillid,sd->skilllv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - range += battle_config.pc_skill_add_range; - if(battle_config.skill_out_range_consume) { // changed to allow casting when target walks out of range [Valaris] - if(range < distance(sd->bl.x,sd->bl.y,sd->skillx,sd->skilly)) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - } - if(!skill_check_condition(sd,1)) { /* 使用?件チェック */ - sd->canact_tick = tick; - sd->canmove_tick = tick; - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - sd->skillitem = sd->skillitemlv = -1; - if(battle_config.skill_out_range_consume) { - if(range < distance(sd->bl.x,sd->bl.y,sd->skillx,sd->skilly)) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->canact_tick = tick; - sd->canmove_tick = tick; - return 0; - } - } - - if(battle_config.pc_skill_log) - printf("PC %d skill castend skill=%d\n",sd->bl.id,sd->skillid); - pc_stop_walking(sd,0); - - skill_castend_pos2(&sd->bl,sd->skillx,sd->skilly,sd->skillid,sd->skilllv,tick,0); - - return 0; -} - -/*========================================== - * 範??キャラ存在確認判定?理(foreachinarea) - *------------------------------------------ - */ - -static int skill_check_condition_char_sub(struct block_list *bl,va_list ap) -{ - int *c; - struct block_list *src; - struct map_session_data *sd; - struct map_session_data *ssd; - struct pc_base_job s_class; - struct pc_base_job ss_class; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd=(struct map_session_data*)bl); - nullpo_retr(0, src=va_arg(ap,struct block_list *)); - nullpo_retr(0, c=va_arg(ap,int *)); - nullpo_retr(0, ssd=(struct map_session_data*)src); - - s_class = pc_calc_base_job(sd->status.class_); - //チェックしない設定ならcにありえない大きな?字を返して終了 - if(!battle_config.player_skill_partner_check){ //本?はforeachの前にやりたいけど設定適用箇所をまとめるためにここへ - (*c)=99; - return 0; - } - - ss_class = pc_calc_base_job(ssd->status.class_); - - switch(ssd->skillid){ - case PR_BENEDICTIO: /* 聖?降福 */ - if(sd != ssd && (s_class.job == 4 || s_class.job == 8 || s_class.job == 15) && - (sd->bl.x == ssd->bl.x - 1 || sd->bl.x == ssd->bl.x + 1) && sd->status.sp >= 10) - (*c)++; - break; - case BD_LULLABY: /* 子守歌 */ - case BD_RICHMANKIM: /* ニヨルドの宴 */ - case BD_ETERNALCHAOS: /* 永遠の混沌 */ - case BD_DRUMBATTLEFIELD: /* ?太鼓の響き */ - case BD_RINGNIBELUNGEN: /* ニ?ベルングの指輪 */ - case BD_ROKISWEIL: /* ロキの叫び */ - case BD_INTOABYSS: /* 深淵の中に */ - case BD_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - case BD_RAGNAROK: /* 神?の?昏 */ - case CG_MOONLIT: /* 月明りの泉に落ちる花びら */ - if(sd != ssd && - ((ss_class.job==19 && s_class.job==20) || - (ss_class.job==20 && s_class.job==19)) && - pc_checkskill(sd,ssd->skillid) > 0 && - (*c)==0 && - sd->status.party_id == ssd->status.party_id && - !pc_issit(sd) && - sd->sc_data[SC_DANCING].timer==-1 - ) - (*c)=pc_checkskill(sd,ssd->skillid); - break; - } - return 0; -} -/*========================================== - * 範??キャラ存在確認判定後スキル使用?理(foreachinarea) - *------------------------------------------ - */ - -static int skill_check_condition_use_sub(struct block_list *bl,va_list ap) -{ - int *c; - struct block_list *src; - struct map_session_data *sd; - struct map_session_data *ssd; - struct pc_base_job s_class; - struct pc_base_job ss_class; - int skillid,skilllv; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, sd=(struct map_session_data*)bl); - nullpo_retr(0, src=va_arg(ap,struct block_list *)); - nullpo_retr(0, c=va_arg(ap,int *)); - nullpo_retr(0, ssd=(struct map_session_data*)src); - - s_class = pc_calc_base_job(sd->status.class_); - - //チェックしない設定ならcにありえない大きな?字を返して終了 - if(!battle_config.player_skill_partner_check){ //本?はforeachの前にやりたいけど設定適用箇所をまとめるためにここへ - (*c)=99; - return 0; - } - - ss_class = pc_calc_base_job(ssd->status.class_); - skillid=ssd->skillid; - skilllv=ssd->skilllv; - //if(skilllv <= 0) return 0; - if(skillid > 0 && skilllv <= 0) return 0; // celest - switch(skillid){ - case PR_BENEDICTIO: /* 聖?降福 */ - if(sd != ssd && (s_class.job == 4 || s_class.job == 8 || s_class.job == 15) && - (sd->bl.x == ssd->bl.x - 1 || sd->bl.x == ssd->bl.x + 1) && sd->status.sp >= 10){ - sd->status.sp -= 10; - status_calc_pc(sd,0); - (*c)++; - } - break; - case BD_LULLABY: /* 子守歌 */ - case BD_RICHMANKIM: /* ニヨルドの宴 */ - case BD_ETERNALCHAOS: /* 永遠の混沌 */ - case BD_DRUMBATTLEFIELD: /* ?太鼓の響き */ - case BD_RINGNIBELUNGEN: /* ニ?ベルングの指輪 */ - case BD_ROKISWEIL: /* ロキの叫び */ - case BD_INTOABYSS: /* 深淵の中に */ - case BD_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - case BD_RAGNAROK: /* 神?の?昏 */ - case CG_MOONLIT: /* 月明りの泉に落ちる花びら */ - if(sd != ssd && //本人以外で - ((ss_class.job==19 && s_class.job==20) || //自分がバ?ドならダンサ?で - (ss_class.job==20 && s_class.job==19)) && //自分がダンサ?ならバ?ドで - pc_checkskill(sd,skillid) > 0 && //スキルを持っていて - (*c)==0 && //最初の一人で - sd->status.party_id == ssd->status.party_id && //パ?ティ?が同じで - !pc_issit(sd) && //座ってない - sd->sc_data[SC_DANCING].timer==-1 //ダンス中じゃない - ){ - ssd->sc_data[SC_DANCING].val4=bl->id; - clif_skill_nodamage(bl,src,skillid,skilllv,1); - status_change_start(bl,SC_DANCING,skillid,ssd->sc_data[SC_DANCING].val2,0,src->id,skill_get_time(skillid,skilllv)+1000,0); - sd->skillid_dance=sd->skillid=skillid; - sd->skilllv_dance=sd->skilllv=skilllv; - (*c)++; - } - break; - } - return 0; -} -/*========================================== - * 範??バイオプラント、スフィアマイン用Mob存在確認判定?理(foreachinarea) - *------------------------------------------ - */ - -static int skill_check_condition_mob_master_sub(struct block_list *bl,va_list ap) -{ - int *c,src_id=0,mob_class=0; - struct mob_data *md; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, md=(struct mob_data*)bl); - nullpo_retr(0, src_id=va_arg(ap,int)); - nullpo_retr(0, mob_class=va_arg(ap,int)); - nullpo_retr(0, c=va_arg(ap,int *)); - - if(md->class_==mob_class && md->master_id==src_id) - (*c)++; - return 0; -} - -/*========================================== - * スキル使用?件(?で使用失敗) - *------------------------------------------ - */ -int skill_check_condition(struct map_session_data *sd,int type) -{ - int i,hp,sp,hp_rate,sp_rate,zeny,weapon,state,spiritball,skill,lv,mhp; - int index[10],itemid[10],amount[10]; - int arrow_flag = 0; - - nullpo_retr(0, sd); - - if( battle_config.gm_skilluncond>0 && pc_isGM(sd)>= battle_config.gm_skilluncond ) { - sd->skillitem = sd->skillitemlv = -1; - return 1; - } - - if( sd->opt1>0) { - clif_skill_fail(sd,sd->skillid,0,0); - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - if(pc_is90overweight(sd)) { - clif_skill_fail(sd,sd->skillid,9,0); - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - - if(sd->skillid == AC_MAKINGARROW && sd->state.make_arrow_flag == 1) { - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - if((sd->skillid == AM_PHARMACY || sd->skillid == ASC_CDP) - && sd->state.produce_flag == 1) { - sd->skillitem = sd->skillitemlv = -1; - return 0; - } - - if(sd->skillitem == sd->skillid) { /* アイテムの場合無?件成功 */ - if(type&1) - sd->skillitem = sd->skillitemlv = -1; - return 1; - } - if( sd->opt1>0 ){ - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - if(sd->sc_count){ - if( sd->sc_data[SC_DIVINA].timer!=-1 || - sd->sc_data[SC_ROKISWEIL].timer!=-1 || - (sd->sc_data[SC_AUTOCOUNTER].timer != -1 && sd->skillid != KN_AUTOCOUNTER) || - sd->sc_data[SC_STEELBODY].timer != -1 || - sd->sc_data[SC_BERSERK].timer != -1 || - (sd->sc_data[SC_MARIONETTE].timer != -1 && sd->skillid != CG_MARIONETTE)){ - clif_skill_fail(sd,sd->skillid,0,0); - return 0; /* ?態異常や沈?など */ - } - } - skill = sd->skillid; - lv = sd->skilllv; - if(lv <= 0) return 0; - // for the guild skills [celest] - if (skill >= 10000 && skill < 10015) skill-= 9500; - hp=skill_get_hp(skill, lv); /* 消費HP */ - sp=skill_get_sp(skill, lv); /* 消費SP */ - if((sd->skillid_old == BD_ENCORE) && skill==sd->skillid_dance) - sp=sp/2; //アンコ?ル時はSP消費が半分 - hp_rate = (lv <= 0)? 0:skill_db[skill].hp_rate[lv-1]; - sp_rate = (lv <= 0)? 0:skill_db[skill].sp_rate[lv-1]; - zeny = skill_get_zeny(skill,lv); - weapon = skill_db[skill].weapon; - state = skill_db[skill].state; - spiritball = (lv <= 0)? 0:skill_db[skill].spiritball[lv-1]; - mhp=skill_get_mhp(skill, lv); /* 消費HP */ - for(i=0;i<10;i++) { - itemid[i] = skill_db[skill].itemid[i]; - amount[i] = skill_db[skill].amount[i]; - } - if(mhp > 0) - hp += (sd->status.max_hp * mhp)/100; - if(hp_rate > 0) - hp += (sd->status.hp * hp_rate)/100; - else - hp += (sd->status.max_hp * abs(hp_rate))/100; - if(sp_rate > 0) - sp += (sd->status.sp * sp_rate)/100; - else - sp += (sd->status.max_sp * abs(sp_rate))/100; - if(sd->dsprate!=100) - sp=sp*sd->dsprate/100; /* 消費SP修正 */ - - switch(skill) { - case SA_CASTCANCEL: - if(sd->skilltimer == -1) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case BS_MAXIMIZE: /* マキシマイズパワ? */ - case NV_TRICKDEAD: /* 死んだふり */ - case TF_HIDING: /* ハイディング */ - case AS_CLOAKING: /* クロ?キング */ - case CR_AUTOGUARD: /* オ?トガ?ド */ - case CR_DEFENDER: /* ディフェンダ? */ - case ST_CHASEWALK: - if(sd->sc_data[SkillStatusChangeTable[skill]].timer!=-1) - return 1; /* 解除する場合はSP消費しない */ - break; - case AL_TELEPORT: - case AL_WARP: - if(map[sd->bl.m].flag.noteleport) { - clif_skill_teleportmessage(sd,0); - return 0; - } - break; - case MO_CALLSPIRITS: /* ?功 */ - if(sd->spiritball >= lv) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case CH_SOULCOLLECT: /* 狂?功 */ - if(sd->spiritball >= 5) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case MO_FINGEROFFENSIVE: //指? - if (sd->spiritball > 0 && sd->spiritball < spiritball) { - spiritball = sd->spiritball; - sd->spiritball_old = sd->spiritball; - } - else sd->spiritball_old = lv; - break; - case MO_BODYRELOCATION: - if (sd->sc_count && sd->sc_data[SC_EXPLOSIONSPIRITS].timer!=-1) - spiritball = 0; - break; - case MO_CHAINCOMBO: //連打掌 - if(sd->sc_data[SC_BLADESTOP].timer==-1){ - if(sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_TRIPLEATTACK) - return 0; - } - break; - case MO_COMBOFINISH: //猛龍拳 - if(sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_CHAINCOMBO) - return 0; - break; - case CH_TIGERFIST: //伏虎拳 - if((sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) && !sd->state.skill_flag) - return 0; - break; - case CH_CHAINCRUSH: //連柱崩? - if(sd->sc_data[SC_COMBO].timer == -1) - return 0; - if(sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH && sd->sc_data[SC_COMBO].val1 != CH_TIGERFIST) - return 0; - break; - case MO_EXTREMITYFIST: // 阿修羅覇鳳拳 - if((sd->sc_data[SC_COMBO].timer != -1 && (sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH || sd->sc_data[SC_COMBO].val1 == CH_CHAINCRUSH)) || sd->sc_data[SC_BLADESTOP].timer!=-1) - spiritball--; - break; - case BD_ADAPTATION: /* アドリブ */ - { - struct skill_unit_group *group=NULL; - if(sd->sc_data[SC_DANCING].timer==-1 || ((group=(struct skill_unit_group*)sd->sc_data[SC_DANCING].val2) && (skill_get_time(sd->sc_data[SC_DANCING].val1,group->skill_lv) - sd->sc_data[SC_DANCING].val3*1000) <= skill_get_time2(skill,lv))){ //ダンス中で使用後5秒以上のみ? - clif_skill_fail(sd,skill,0,0); - return 0; - } - } - break; - case PR_BENEDICTIO: /* 聖?降福 */ - { - int range=1; - int c=0; - if(!(type&1)){ - map_foreachinarea(skill_check_condition_char_sub,sd->bl.m, - sd->bl.x-range,sd->bl.y-range, - sd->bl.x+range,sd->bl.y+range,BL_PC,&sd->bl,&c); - if(c<2){ - clif_skill_fail(sd,skill,0,0); - return 0; - } - }else{ - map_foreachinarea(skill_check_condition_use_sub,sd->bl.m, - sd->bl.x-range,sd->bl.y-range, - sd->bl.x+range,sd->bl.y+range,BL_PC,&sd->bl,&c); - } - } - break; - case WE_CALLPARTNER: /* あなたに逢いたい */ - if(!sd->status.partner_id){ - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case AM_CANNIBALIZE: /* バイオプラント */ - case AM_SPHEREMINE: /* スフィア?マイン */ - if(type&1){ - int c=0; - int summons[5] = { 1020, 1068, 1118, 1500, 1368 }; - int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill); - int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142; - if(battle_config.pc_land_skill_limit && maxcount>0) { - map_foreachinarea(skill_check_condition_mob_master_sub ,sd->bl.m, 0, 0, map[sd->bl.m].xs, map[sd->bl.m].ys, BL_MOB, sd->bl.id, mob_class,&c ); - if(c >= maxcount){ - clif_skill_fail(sd,skill,0,0); - return 0; - } - } - } - break; - case MG_FIREWALL: /* ファイア?ウォ?ル */ - case WZ_QUAGMIRE: - case WZ_FIREPILLAR: // celest - case PF_FOGWALL: - /* ?制限 */ - if(battle_config.pc_land_skill_limit) { - int maxcount = skill_get_maxcount(skill); - if(maxcount > 0) { - int i,c; - for(i=c=0;i<MAX_SKILLUNITGROUP;i++) { - if(sd->skillunit[i].alive_count > 0 && sd->skillunit[i].skill_id == skill) - c++; - } - if(c >= maxcount) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - } - } - break; - // skills require arrows as of 12/07 [celest] - case AC_DOUBLE: - case AC_SHOWER: - case AC_CHARGEARROW: - case BA_MUSICALSTRIKE: - case DC_THROWARROW: - case SN_SHARPSHOOTING: - case CG_ARROWVULCAN: - if(sd->equip_index[10] < 0) { - clif_arrow_fail(sd,0); - return 0; - } - arrow_flag = 1; - break; - case RG_BACKSTAP: - if(sd->status.weapon == 11) { - if (sd->equip_index[10] < 0) { - clif_arrow_fail(sd,0); - return 0; - } - arrow_flag = 1; - } - break; - } - - if(!(type&2)){ - if( hp>0 && sd->status.hp < hp) { /* HPチェック */ - clif_skill_fail(sd,skill,2,0); /* HP不足:失敗通知 */ - return 0; - } - if( sp>0 && sd->status.sp < sp) { /* SPチェック */ - clif_skill_fail(sd,skill,1,0); /* SP不足:失敗通知 */ - return 0; - } - if( zeny>0 && sd->status.zeny < zeny) { - clif_skill_fail(sd,skill,5,0); - return 0; - } - if(!(weapon & (1<<sd->status.weapon) ) ) { - clif_skill_fail(sd,skill,6,0); - return 0; - } - if( spiritball > 0 && sd->spiritball < spiritball) { - clif_skill_fail(sd,skill,0,0); // 氣球不足 - return 0; - } - } - - switch(state) { - case ST_HIDING: - if(!(sd->status.option&2)) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_CLOAKING: - if(!(sd->status.option&4)) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_HIDDEN: - if(!pc_ishiding(sd)) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_RIDING: - if(!pc_isriding(sd)) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_FALCON: - if(!pc_isfalcon(sd)) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_CART: - if(!pc_iscarton(sd)) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_SHIELD: - if(sd->status.shield <= 0) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_SIGHT: - if(sd->sc_data[SC_SIGHT].timer == -1 && type&1) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_EXPLOSIONSPIRITS: - if (skill == MO_EXTREMITYFIST && ((sd->sc_data[SC_COMBO].timer != -1 && (sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH || sd->sc_data[SC_COMBO].val1 == CH_CHAINCRUSH)) || sd->sc_data[SC_BLADESTOP].timer!=-1)) { - break; - } - if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer == -1) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_RECOV_WEIGHT_RATE: - if(battle_config.natural_heal_weight_rate <= 100 && sd->weight*100/sd->max_weight >= battle_config.natural_heal_weight_rate) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - case ST_MOVE_ENABLE: - { - struct walkpath_data wpd; - if(path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,sd->skillx,sd->skilly,1)==-1) { - clif_skill_fail(sd,skill,0,0); - return 0; - } - } - break; - case ST_WATER: - if((!map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))&& (sd->sc_data[SC_DELUGE].timer==-1)){ //水場判定 - clif_skill_fail(sd,skill,0,0); - return 0; - } - break; - } - - for(i=0;i<10;i++) { - int x = lv%11 - 1; - index[i] = -1; - if(itemid[i] <= 0) - continue; - if(itemid[i] >= 715 && itemid[i] <= 717 && sd->special_state.no_gemstone) - continue; - if(((itemid[i] >= 715 && itemid[i] <= 717) || itemid[i] == 1065) && sd->sc_data[SC_INTOABYSS].timer != -1) - continue; - if(skill == WZ_FIREPILLAR && lv<=5) - continue; // no gemstones for 1-5 [Celest] - if((skill == AM_POTIONPITCHER || - skill == CR_SLIMPITCHER) && i != x) - continue; - - index[i] = pc_search_inventory(sd,itemid[i]); - if(index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i]) { - if(itemid[i] == 716 || itemid[i] == 717) - clif_skill_fail(sd,skill,(7+(itemid[i]-716)),0); - else - clif_skill_fail(sd,skill,0,0); - return 0; - } - } - - if(!(type&1)) - return 1; - - if(skill != AM_POTIONPITCHER && - skill != CR_SLIMPITCHER && - skill != MG_STONECURSE) { - if(skill == AL_WARP && !(type&2)) - return 1; - for(i=0;i<10;i++) { - if(index[i] >= 0) - pc_delitem(sd,index[i],amount[i],0); // アイテム消費 - } - if (arrow_flag && battle_config.arrow_decrement) - pc_delitem(sd,sd->equip_index[10],1,0); - } - - if(type&2) - return 1; - - if(sp > 0) { // SP消費 - sd->status.sp-=sp; - clif_updatestatus(sd,SP_SP); - } - if(hp > 0) { // HP消費 - sd->status.hp-=hp; - clif_updatestatus(sd,SP_HP); - } - if(zeny > 0) // Zeny消費 - pc_payzeny(sd,zeny); - if(spiritball > 0) // 氣球消費 - pc_delspiritball(sd,spiritball,0); - - - return 1; -} - -/*========================================== - * 詠唱時間計算 - *------------------------------------------ - */ -int skill_castfix( struct block_list *bl, int time ) -{ - struct map_session_data *sd = NULL; - struct mob_data *md; // [Valaris] - struct status_change *sc_data; - int castrate=100; - int skill,lv; - - nullpo_retr(0, bl); - - if(bl->type==BL_MOB){ // Crash fix [Valaris] - nullpo_retr(0, md=(struct mob_data*)bl); - skill = md->skillid; - lv = md->skilllv; - } else { - nullpo_retr(0, sd=(struct map_session_data*)bl); - skill = sd->skillid; - lv = sd->skilllv; - } - - if(lv <= 0) return 0; - - sc_data = status_get_sc_data(bl); - - if (skill > MAX_SKILL_DB || skill < 0) - return 0; - - /* サフラギウム */ - if(sc_data && sc_data[SC_SUFFRAGIUM].timer!=-1 ) - time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100; - status_change_end( bl, SC_SUFFRAGIUM, -1); - - if(time==0) - return 0; - if (sd) { - if(!skill_get_castnodex(skill, lv) > 0) { - castrate=((struct map_session_data *)bl)->castrate; - time=time*castrate*(battle_config.castrate_dex_scale - status_get_dex(bl))/(battle_config.castrate_dex_scale * 100); - time=time*battle_config.cast_rate/100; - } - } - - /* ブラギの詩 */ - if(sc_data && sc_data[SC_POEMBRAGI].timer!=-1) - time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2 - +(sc_data[SC_POEMBRAGI].val3>>16)))/100; - - return (time>0)?time:0; -} -/*========================================== - * ディレイ計算 - *------------------------------------------ - */ -int skill_delayfix( struct block_list *bl, int time ) -{ - struct status_change *sc_data; - struct map_session_data *sd = NULL; - int skill = 0,lv = 0; - int delayrate = 100; - - nullpo_retr(0, bl); - - if(bl->type == BL_PC){ - nullpo_retr(0, sd = (struct map_session_data*)bl); - skill = sd->skillid; - lv = sd->skilllv; - } - - if(lv <= 0) return 0; - - sc_data = status_get_sc_data(bl); - - if(sd) { - delayrate = sd->delayrate; - - // instant cast attack skills depend on aspd as delay [celest] - if (time == 0) { - if (skill_db[skill].skill_type == BF_WEAPON) - time = status_get_adelay (bl)/2; - else - time = 300; // default delay, according to official servers - } else if (time < 0) - time = abs(time) + status_get_adelay (bl)/2; // if set to <0, the aspd delay will be added - - if(battle_config.delay_dependon_dex && /* dexの影響を計算する */ - !skill_get_delaynodex(skill, lv)) // if skill casttime is allowed to be reduced by dex - time = time * (battle_config.castrate_dex_scale - status_get_dex(bl)) / (battle_config.castrate_dex_scale); - - time = time * delayrate * battle_config.delay_rate / 10000; - - if (time < battle_config.min_skill_delay_limit) // check minimum skill delay - time = battle_config.min_skill_delay_limit; - } - - /* ブラギの詩 */ - if(sc_data && sc_data[SC_POEMBRAGI].timer != -1 ) - time = time * (100 - (sc_data[SC_POEMBRAGI].val1 * 3 + sc_data[SC_POEMBRAGI].val2 - + (sc_data[SC_POEMBRAGI].val3 & 0xffff))) / 100; - - return (time>0)?time:0; -} - -/*========================================== - * スキル使用(ID指定) - *------------------------------------------ - */ -int skill_use_id (struct map_session_data *sd, int target_id, int skill_num, int skill_lv) -{ - int casttime = 0, delay = 0, skill, range; - struct map_session_data* tsd = NULL; - struct block_list *bl = NULL; - struct status_change *sc_data; - int forcecast = 0; - unsigned int tick = gettick(); - - nullpo_retr(0, sd); - - if ((bl = map_id2bl(target_id)) == NULL) - return 0; - if (bl->type == BL_PC) { - nullpo_retr(0, tsd = (struct map_session_data*)bl); - } - if(sd->bl.m != bl->m || pc_isdead(sd)) - return 0; - if(skillnotok(skill_num, sd)) // [MouseJstr] - return 0; - if (tsd && skill_num == ALL_RESURRECTION && !pc_isdead(tsd)) - return 0; - - sc_data = sd->sc_data; - - /* 沈?や異常(ただし、グリムなどの判定をする) */ - if (sd->opt1 > 0) - return 0; - if (sc_data) { - // allow to use only Chasewalk [celest] - if (sc_data[SC_CHASEWALK].timer != -1 && skill_num != ST_CHASEWALK) - return 0; - if (sc_data[SC_VOLCANO].timer != -1 && skill_num == WZ_ICEWALL) - return 0; - if (sc_data[SC_ROKISWEIL].timer != -1 && skill_num == BD_ADAPTATION) - return 0; - if (sc_data[SC_DIVINA].timer != -1 || - sc_data[SC_ROKISWEIL].timer != -1 || - (sc_data[SC_AUTOCOUNTER].timer != -1 && sd->skillid != KN_AUTOCOUNTER) || - sc_data[SC_STEELBODY].timer != -1 || - sc_data[SC_BERSERK].timer != -1 || - (sc_data[SC_MARIONETTE].timer != -1 && sd->skillid != CG_MARIONETTE)) - return 0; /* ?態異常や沈?など */ - if (sc_data[SC_BLADESTOP].timer != -1) { - if (sc_data[SC_BLADESTOP].val2 == 1) return 0;//白羽された側なのでダメ - switch (sc_data[SC_BLADESTOP].val1) { - case 1: return 0; - case 2: if (skill_num != MO_FINGEROFFENSIVE) return 0; else break; - case 3: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE) return 0; else break; - case 4: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE && skill_num != MO_CHAINCOMBO) return 0; else break; - case 5: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE && skill_num != MO_CHAINCOMBO && skill_num!=MO_EXTREMITYFIST) return 0; else break; - } - } - if (sc_data[SC_BASILICA].timer != -1) { // Disallow all other skills in Basilica [celest] - struct skill_unit_group *sg = (struct skill_unit_group *)sc_data[SC_BASILICA].val4; - // if caster is the owner of basilica - if (sg && sg->src_id == sd->bl.id && - skill_num == HP_BASILICA) ; // do nothing - // otherwise... - else return 0; - } - /* 演奏/ダンス中 */ - if (sc_data[SC_DANCING].timer != -1) { - if (sc_data[SC_DANCING].val4 && skill_num != BD_ADAPTATION) //合奏中はアドリブ以外不可 - return 0; - if (skill_num != BD_ADAPTATION && skill_num != BA_MUSICALSTRIKE && skill_num != DC_THROWARROW) - return 0; - } - } - - if (sd->status.option & 4 && skill_num == TF_HIDING) - return 0; - if (sd->status.option & 2 && skill_num != TF_HIDING && skill_num != AS_GRIMTOOTH && skill_num != RG_BACKSTAP && skill_num != RG_RAID) - return 0; - if(skill_get_inf2(skill_num) & 0x200 && sd->bl.id == target_id) - return 0; - - //直前のスキルが何か?える必要のあるスキル - switch (skill_num) { - case SA_CASTCANCEL: - if (sd->skillid != skill_num){ //キャストキャンセル自?は?えない - sd->skillid_old = sd->skillid; - sd->skilllv_old = sd->skilllv; - break; - } - - case BD_ENCORE: /* アンコ?ル */ - if (!sd->skillid_dance) { //前回使用した踊りがないとだめ - clif_skill_fail(sd,skill_num,0,0); - return 0; - } else { - sd->skillid_old = skill_num; - } - break; - - case GD_BATTLEORDER: - case GD_REGENERATION: - case GD_RESTORE: - case GD_EMERGENCYCALL: - { - struct guild *g; - if (!sd->status.guild_id) - return 0; - if ((g = guild_search(sd->status.guild_id)) == NULL) - return 0; - if (strcmp(sd->status.name,g->master)) - return 0; - skill_lv = guild_checkskill(g, skill_num); - if (skill_lv <= 0) return 0; - } - break; - - case BD_LULLABY: /* 子守歌 */ - case BD_RICHMANKIM: /* ニヨルドの宴 */ - case BD_ETERNALCHAOS: /* 永遠の混沌 */ - case BD_DRUMBATTLEFIELD: /* ?太鼓の響き */ - case BD_RINGNIBELUNGEN: /* ニ?ベルングの指輪 */ - case BD_ROKISWEIL: /* ロキの叫び */ - case BD_INTOABYSS: /* 深淵の中に */ - case BD_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - case BD_RAGNAROK: /* 神?の?昏 */ - case CG_MOONLIT: /* 月明りの泉に落ちる花びら */ - { - int range = 1; - int c = 0; - map_foreachinarea (skill_check_condition_char_sub, sd->bl.m, - sd->bl.x-range, sd->bl.y-range, - sd->bl.x+range, sd->bl.y+range, BL_PC, &sd->bl, &c); - if (c < 1) { - clif_skill_fail(sd,skill_num,0,0); - return 0; - } else if (c == 99) { //相方不要設定だった - ; - } else { - sd->skilllv = (c + skill_lv)/2; - } - } - break; - } - - sd->skillid = skill_num; - sd->skilllv = skill_lv; - if (!skill_check_condition(sd,0)) return 0; - - { - int check_range_flag = 0; - - /* 射程と障害物チェック */ - range = skill_get_range(skill_num,skill_lv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - // be lenient if the skill was cast before we have moved to the correct position [Celest] - if (sd->walktimer != -1) - range++; - else check_range_flag = 1; - if(!battle_check_range(&sd->bl,bl,range)) { - if (check_range_flag && battle_check_range(&sd->bl,bl,range + 1)) { - int mask[8][2] = {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}}; - int dir = map_calc_dir(&sd->bl,bl->x,bl->y); - pc_walktoxy (sd, sd->bl.x + mask[dir][0], sd->bl.y + mask[dir][1]); - } else - return 0; - } - } - - if ((skill_num != MO_CHAINCOMBO && - skill_num != MO_COMBOFINISH && - skill_num != MO_EXTREMITYFIST && - skill_num != CH_TIGERFIST && - skill_num != CH_CHAINCRUSH) || - (skill_num == CH_CHAINCRUSH && sd->state.skill_flag) || - (skill_num == MO_EXTREMITYFIST && sd->state.skill_flag) ) - pc_stopattack(sd); - - casttime = skill_castfix(&sd->bl, skill_get_cast(skill_num, skill_lv)); - if (skill_num != SA_MAGICROD) - delay = skill_delayfix(&sd->bl, skill_get_delay(skill_num, skill_lv)); - sd->state.skillcastcancel = skill_get_castcancel(skill_num); - - switch (skill_num) { /* 何か特殊な?理が必要 */ - case ALL_RESURRECTION: /* リザレクション */ - if (!tsd && battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) { /* 敵がアンデッドなら */ - forcecast = 1; /* タ?ンアンデットと同じ詠唱時間 */ - casttime = skill_castfix(&sd->bl, skill_get_cast(PR_TURNUNDEAD, skill_lv)); - } - break; - - case MO_FINGEROFFENSIVE: /* 指? */ - casttime += casttime * ((skill_lv > sd->spiritball) ? sd->spiritball : skill_lv); - break; - - case MO_CHAINCOMBO: /*連打掌*/ - target_id = sd->attacktarget; - if (sc_data && sc_data[SC_BLADESTOP].timer != -1){ - struct block_list *tbl; - if ((tbl=(struct block_list *)sc_data[SC_BLADESTOP].val4) == NULL) //タ?ゲットがいない? - return 0; - target_id = tbl->id; - } - break; - case MO_COMBOFINISH: /*猛龍拳*/ - case CH_CHAINCRUSH: /* 連柱崩? */ - target_id = sd->attacktarget; - break; - - case CH_TIGERFIST: /* 伏虎拳 */ - if (sc_data && sc_data[SC_COMBO].timer != -1 && sc_data[SC_COMBO].val1 == MO_COMBOFINISH) - target_id = sd->attacktarget; - break; - -// -- moonsoul (altered to allow proper usage of extremity from new champion combos) -// - case MO_EXTREMITYFIST: /*阿修羅覇鳳拳*/ - if (sc_data && sc_data[SC_COMBO].timer != -1 && (sc_data[SC_COMBO].val1 == MO_COMBOFINISH || sc_data[SC_COMBO].val1 == CH_CHAINCRUSH)) { - casttime = 0; - target_id = sd->attacktarget; - } - forcecast = 1; - break; - - case SA_MAGICROD: - case SA_SPELLBREAKER: - forcecast = 1; - break; - - case WE_MALE: - case WE_FEMALE: - { - struct map_session_data *p_sd = pc_get_partner(sd); - if (p_sd == NULL) - return 0; - if (skill_num == WE_MALE && sd->status.hp <= ((15*sd->status.max_hp)/100)) // Requires more than 15% of Max HP for WE_MALE - return 0; - else if (skill_num == WE_FEMALE && sd->status.sp <= ((15*sd->status.max_sp)/100)) // Requires more than 15% of Max SP for WE_FEMALE - return 0; - target_id = p_sd->bl.id; - //rangeをもう1回?査 - if (!battle_check_range(&sd->bl, &p_sd->bl, skill_get_range(skill_num,skill_lv))) - return 0; - } - break; - - // parent-baby skills - case WE_BABY: - case WE_CALLPARENT: - { - struct map_session_data *f_sd = pc_get_father(sd); - struct map_session_data *m_sd = pc_get_mother(sd); - - // set target as any one of the parent - if (f_sd) target_id = f_sd->bl.id; - else if (m_sd) target_id = m_sd->bl.id; - else return 0; // neither are found - - // skip range check - //rangeをもう1回?査 - //range = skill_get_range(skill_num,skill_lv); - //if(!battle_check_range(&sd->bl,&p_sd->bl,range)) - // return 0; - } - break; - - case WE_CALLBABY: - { - struct map_session_data *p_sd = pc_get_child(sd); - if (p_sd == NULL) - return 0; - target_id = p_sd->bl.id; - //rangeをもう1回?査 - if(!battle_check_range(&sd->bl, &p_sd->bl, skill_get_range(skill_num,skill_lv))) - return 0; - } - break; - - case HP_BASILICA: /* バジリカ */ - { - if (skill_check_unit_range(sd->bl.m,sd->bl.x,sd->bl.y,sd->skillid,sd->skilllv)) { - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - if (skill_check_unit_range2(&sd->bl,sd->bl.m,sd->bl.x,sd->bl.y,sd->skillid,sd->skilllv)) { - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - // cancel Basilica if already in effect - if (sc_data && sc_data[SC_BASILICA].timer != -1) { - struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc_data[SC_BASILICA].val4; - if (sg && sg->src_id == sd->bl.id) { - status_change_end(&sd->bl,SC_BASILICA,-1); - skill_delunitgroup (sg); - return 0; - } - } - } - break; - - case GD_BATTLEORDER: - case GD_REGENERATION: - case GD_RESTORE: - case GD_EMERGENCYCALL: - casttime = 1000; // temporary [Celest] - break; - } - - //メモライズ?態ならキャストタイムが1/3 - if (sc_data && sc_data[SC_MEMORIZE].timer != -1 && casttime > 0) { - casttime = casttime/2; - if ((--sc_data[SC_MEMORIZE].val2) <= 0) - status_change_end(&sd->bl, SC_MEMORIZE, -1); - } - - if (battle_config.pc_skill_log) - printf ("PC %d skill use target_id=%d skill=%d lv=%d cast=%d\n", - sd->bl.id, target_id, skill_num, skill_lv, casttime); - - if (casttime > 0 || forcecast) { /* 詠唱が必要 */ - struct mob_data *md; - clif_skillcasting(&sd->bl, sd->bl.id, target_id, 0,0, skill_num,casttime); - - /* 詠唱反?モンスタ? */ - if (bl->type == BL_MOB && (md = (struct mob_data *)bl) && mob_db[md->class_].mode & 0x10 && - md->state.state != MS_ATTACK && sd->invincible_timer == -1){ - md->target_id = sd->bl.id; - md->state.targettype = ATTACKABLE; - md->min_chase = 13; - } - } - - sd->skilltarget = target_id; - sd->skillx = 0; - sd->skilly = 0; - sd->canact_tick = tick + casttime + delay; - sd->canmove_tick = tick; - - if (!(battle_config.pc_cloak_check_type & 2) && sc_data && sc_data[SC_CLOAKING].timer != -1 && sd->skillid != AS_CLOAKING) - status_change_end(&sd->bl,SC_CLOAKING,-1); - if (casttime > 0) { - sd->skilltimer = add_timer (tick + casttime, skill_castend_id, sd->bl.id, 0); - if ((skill = pc_checkskill(sd,SA_FREECAST)) > 0) { - sd->prev_speed = sd->speed; - status_calc_speed (sd); - } - else - pc_stop_walking(sd,0); - } else { - sd->state.skillcastcancel = 0; /* 詠唱の無いものはキャンセルされない */ - if (skill_num != SA_CASTCANCEL) - sd->skilltimer = -1; - skill_castend_id(sd->skilltimer,tick,sd->bl.id,0); - } - - return 0; -} - -/*========================================== - * スキル使用(場所指定) - *------------------------------------------ - */ -int skill_use_pos (struct map_session_data *sd, int skill_x, int skill_y, int skill_num, int skill_lv) -{ - struct block_list bl; - struct status_change *sc_data; - int casttime = 0, delay = 0, skill, range; - unsigned int tick = gettick(); - - nullpo_retr(0, sd); - - if (pc_isdead(sd)) - return 0; - if (skillnotok(skill_num, sd)) // [MoueJstr] - return 0; - if (skill_num == WZ_ICEWALL && map[sd->bl.m].flag.noicewall && !map[sd->bl.m].flag.pvp) { // noicewall flag [Valaris] - clif_skill_fail(sd,sd->skillid,0,0); - return 0; - } - - sc_data = sd->sc_data; - - if (sd->opt1 > 0) - return 0; - if (sc_data){ - if (sc_data[SC_DIVINA].timer != -1 || - sc_data[SC_ROKISWEIL].timer != -1 || - sc_data[SC_AUTOCOUNTER].timer != -1 || - sc_data[SC_STEELBODY].timer != -1 || - sc_data[SC_DANCING].timer!=-1 || - sc_data[SC_BERSERK].timer != -1 || - sc_data[SC_MARIONETTE].timer != -1) - return 0; /* ?態異常や沈?など */ - - if (sc_data[SC_BASILICA].timer != -1) { - struct skill_unit_group *sg = (struct skill_unit_group *)sc_data[SC_BASILICA].val4; - // if caster is the owner of basilica - if (sg && sg->src_id == sd->bl.id && - skill_num == HP_BASILICA) ; // do nothing - // otherwise... - else return 0; - } - } - - if(sd->status.option & 2) - return 0; - - sd->skillid = skill_num; - sd->skilllv = skill_lv; - if (skill_lv <= 0) return 0; - sd->skillx = skill_x; - sd->skilly = skill_y; - if (!skill_check_condition(sd,0)) return 0; - - /* 射程と障害物チェック */ - bl.type = BL_NUL; - bl.m = sd->bl.m; - bl.x = skill_x; - bl.y = skill_y; - - { - int check_range_flag = 0; - - /* 射程と障害物チェック */ - range = skill_get_range(skill_num,skill_lv); - if(range < 0) - range = status_get_range(&sd->bl) - (range + 1); - // be lenient if the skill was cast before we have moved to the correct position [Celest] - if (sd->walktimer != -1) - range ++; - else check_range_flag = 1; - if(!battle_check_range(&sd->bl,&bl,range)) { - if (check_range_flag && battle_check_range(&sd->bl,&bl,range + 1)) { - int mask[8][2] = {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}}; - int dir = map_calc_dir(&sd->bl,bl.x,bl.y); - pc_walktoxy (sd, sd->bl.x + mask[dir][0], sd->bl.y + mask[dir][1]); - } else - return 0; - } - } - - pc_stopattack(sd); - - casttime = skill_castfix(&sd->bl, skill_get_cast( skill_num,skill_lv) ); - delay = skill_delayfix(&sd->bl, skill_get_delay( skill_num,skill_lv) ); - sd->state.skillcastcancel = skill_db[skill_num].castcancel; - - if (battle_config.pc_skill_log) - printf("PC %d skill use target_pos=(%d,%d) skill=%d lv=%d cast=%d\n", - sd->bl.id, skill_x, skill_y, skill_num, skill_lv, casttime); - - //メモライズ?態ならキャストタイムが1/3 - if (sc_data && sc_data[SC_MEMORIZE].timer != -1 && casttime > 0){ - casttime = casttime/3; - if ((--sc_data[SC_MEMORIZE].val2)<=0) - status_change_end(&sd->bl, SC_MEMORIZE, -1); - } - - if (casttime > 0) /* 詠唱が必要 */ - clif_skillcasting(&sd->bl, sd->bl.id, 0, skill_x, skill_y, skill_num, casttime); - - sd->skilltarget = 0; - sd->canact_tick = tick + casttime + delay; - sd->canmove_tick = tick; - if (!(battle_config.pc_cloak_check_type&2) && sc_data && sc_data[SC_CLOAKING].timer != -1) - status_change_end(&sd->bl,SC_CLOAKING,-1); - if (casttime > 0) { - sd->skilltimer = add_timer(tick + casttime, skill_castend_pos, sd->bl.id, 0); - if ((skill = pc_checkskill(sd,SA_FREECAST)) > 0) { - sd->prev_speed = sd->speed; - status_calc_speed (sd); - } - else - pc_stop_walking(sd,0); - } else { - sd->state.skillcastcancel = 0; /* 詠唱の無いものはキャンセルされない */ - sd->skilltimer = -1; - skill_castend_pos(sd->skilltimer,tick,sd->bl.id,0); - } - //マジックパワ?の?果終了 - if (skill_get_unit_id(skill_num, 0) != 0x86 && - sc_data && sc_data[SC_MAGICPOWER].timer != -1) - status_change_end(&sd->bl,SC_MAGICPOWER,-1); - - return 0; -} - -/*========================================== - * スキル詠唱キャンセル - *------------------------------------------ - */ -int skill_castcancel (struct block_list *bl, int type) -{ - int inf; - int ret = 0; - - nullpo_retr(0, bl); - - if (bl->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)bl; - unsigned long tick = gettick(); - nullpo_retr(0, sd); - sd->canact_tick = tick; - sd->canmove_tick = tick; - if (sd->skilltimer != -1) { - if (pc_checkskill(sd,SA_FREECAST) > 0) { - sd->speed = sd->prev_speed; - clif_updatestatus(sd,SP_SPEED); - } - if (!type) { - if ((inf = skill_get_inf( sd->skillid )) == 2 || inf == 32) - ret = delete_timer( sd->skilltimer, skill_castend_pos ); - else - ret=delete_timer( sd->skilltimer, skill_castend_id ); - if (ret < 0) - printf("delete timer error : skillid : %d\n", sd->skillid); - } else { - if ((inf = skill_get_inf( sd->skillid_old )) == 2 || inf == 32) - ret = delete_timer( sd->skilltimer, skill_castend_pos ); - else - ret = delete_timer( sd->skilltimer, skill_castend_id ); - if (ret < 0) - printf("delete timer error : skillid : %d\n", sd->skillid_old); - } - sd->skilltimer = -1; - clif_skillcastcancel(bl); - } - return 0; - } else if (bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)bl; - nullpo_retr(0, md); - if (md->skilltimer != -1) { - if ((inf = skill_get_inf( md->skillid )) == 2 || inf == 32) - ret = delete_timer( md->skilltimer, mobskill_castend_pos ); - else - ret = delete_timer( md->skilltimer, mobskill_castend_id ); - md->skilltimer = -1; - clif_skillcastcancel(bl); - } - if (ret < 0) - printf("delete timer error : skillid : %d\n", md->skillid); - return 0; - } - - return 1; -} -/*========================================= - * ブランディッシュスピア 初期範?決定 - *---------------------------------------- - */ -void skill_brandishspear_first(struct square *tc,int dir,int x,int y){ - - nullpo_retv(tc); - - if(dir == 0){ - tc->val1[0]=x-2; - tc->val1[1]=x-1; - tc->val1[2]=x; - tc->val1[3]=x+1; - tc->val1[4]=x+2; - tc->val2[0]= - tc->val2[1]= - tc->val2[2]= - tc->val2[3]= - tc->val2[4]=y-1; - } - else if(dir==2){ - tc->val1[0]= - tc->val1[1]= - tc->val1[2]= - tc->val1[3]= - tc->val1[4]=x+1; - tc->val2[0]=y+2; - tc->val2[1]=y+1; - tc->val2[2]=y; - tc->val2[3]=y-1; - tc->val2[4]=y-2; - } - else if(dir==4){ - tc->val1[0]=x-2; - tc->val1[1]=x-1; - tc->val1[2]=x; - tc->val1[3]=x+1; - tc->val1[4]=x+2; - tc->val2[0]= - tc->val2[1]= - tc->val2[2]= - tc->val2[3]= - tc->val2[4]=y+1; - } - else if(dir==6){ - tc->val1[0]= - tc->val1[1]= - tc->val1[2]= - tc->val1[3]= - tc->val1[4]=x-1; - tc->val2[0]=y+2; - tc->val2[1]=y+1; - tc->val2[2]=y; - tc->val2[3]=y-1; - tc->val2[4]=y-2; - } - else if(dir==1){ - tc->val1[0]=x-1; - tc->val1[1]=x; - tc->val1[2]=x+1; - tc->val1[3]=x+2; - tc->val1[4]=x+3; - tc->val2[0]=y-4; - tc->val2[1]=y-3; - tc->val2[2]=y-1; - tc->val2[3]=y; - tc->val2[4]=y+1; - } - else if(dir==3){ - tc->val1[0]=x+3; - tc->val1[1]=x+2; - tc->val1[2]=x+1; - tc->val1[3]=x; - tc->val1[4]=x-1; - tc->val2[0]=y-1; - tc->val2[1]=y; - tc->val2[2]=y+1; - tc->val2[3]=y+2; - tc->val2[4]=y+3; - } - else if(dir==5){ - tc->val1[0]=x+1; - tc->val1[1]=x; - tc->val1[2]=x-1; - tc->val1[3]=x-2; - tc->val1[4]=x-3; - tc->val2[0]=y+3; - tc->val2[1]=y+2; - tc->val2[2]=y+1; - tc->val2[3]=y; - tc->val2[4]=y-1; - } - else if(dir==7){ - tc->val1[0]=x-3; - tc->val1[1]=x-2; - tc->val1[2]=x-1; - tc->val1[3]=x; - tc->val1[4]=x+1; - tc->val2[1]=y; - tc->val2[0]=y+1; - tc->val2[2]=y-1; - tc->val2[3]=y-2; - tc->val2[4]=y-3; - } - -} - -/*========================================= - * ブランディッシュスピア 方向判定 範??張 - *----------------------------------------- - */ -void skill_brandishspear_dir(struct square *tc,int dir,int are){ - - int c; - - nullpo_retv(tc); - - for(c=0;c<5;c++){ - if(dir==0){ - tc->val2[c]+=are; - }else if(dir==1){ - tc->val1[c]-=are; tc->val2[c]+=are; - }else if(dir==2){ - tc->val1[c]-=are; - }else if(dir==3){ - tc->val1[c]-=are; tc->val2[c]-=are; - }else if(dir==4){ - tc->val2[c]-=are; - }else if(dir==5){ - tc->val1[c]+=are; tc->val2[c]-=are; - }else if(dir==6){ - tc->val1[c]+=are; - }else if(dir==7){ - tc->val1[c]+=are; tc->val2[c]+=are; - } - } -} - -/*========================================== - * ディボ?ション 有?確認 - *------------------------------------------ - */ -void skill_devotion(struct map_session_data *md,int target) -{ - // ?確認 - int n; - - nullpo_retv(md); - - for(n=0;n<5;n++){ - if(md->dev.val1[n]){ - struct map_session_data *sd = map_id2sd(md->dev.val1[n]); - // 相手が見つからない // 相手をディボしてるのが自分じゃない // 距離が離れてる - if( sd == NULL || (sd->sc_data && (md->bl.id != sd->sc_data[SC_DEVOTION].val1)) || skill_devotion3(&md->bl,md->dev.val1[n])){ - skill_devotion_end(md,sd,n); - } - } - } -} -void skill_devotion2(struct block_list *bl,int crusader) -{ - // 被ディボ?ションが?いた時の距離チェック - struct map_session_data *sd = map_id2sd(crusader); - - nullpo_retv(bl); - - if(sd) skill_devotion3(&sd->bl,bl->id); -} -int skill_devotion3(struct block_list *bl,int target) -{ - // クルセが?いた時の距離チェック - struct map_session_data *md; - struct map_session_data *sd; - int n,r=0; - - nullpo_retr(1, bl); - md = (struct map_session_data *)bl; - - if ((sd = map_id2sd(target))==NULL) - return 1; - else - r = distance(bl->x,bl->y,sd->bl.x,sd->bl.y); - - if(pc_checkskill(md,CR_DEVOTION)+6 < r){ // 許容範?を超えてた - for(n=0;n<5;n++) - if(md->dev.val1[n]==target) - md->dev.val2[n]=0; // 離れた時は、?を切るだけ - clif_devotion(md,sd->bl.id); - return 1; - } - return 0; -} - -void skill_devotion_end(struct map_session_data *md,struct map_session_data *sd,int target) -{ - // クルセと被ディボキャラのリセット - nullpo_retv(md); - nullpo_retv(sd); - - md->dev.val1[target]=md->dev.val2[target]=0; - if(sd && sd->sc_data){ - // status_change_end(sd->bl,SC_DEVOTION,-1); - sd->sc_data[SC_DEVOTION].val1=0; - sd->sc_data[SC_DEVOTION].val2=0; - clif_status_change(&sd->bl,SC_DEVOTION,0); - clif_devotion(md,sd->bl.id); - } -} -/*========================================== - * オ?トスペル - *------------------------------------------ - */ -int skill_autospell(struct map_session_data *sd,int skillid) -{ - int skilllv; - int maxlv=1,lv; - - nullpo_retr(0, sd); - - skilllv = pc_checkskill(sd,SA_AUTOSPELL); - if(skilllv <= 0) return 0; - - if(skillid==MG_NAPALMBEAT) maxlv=3; - else if(skillid==MG_COLDBOLT || skillid==MG_FIREBOLT || skillid==MG_LIGHTNINGBOLT){ - if(skilllv==2) maxlv=1; - else if(skilllv==3) maxlv=2; - else if(skilllv>=4) maxlv=3; - } - else if(skillid==MG_SOULSTRIKE){ - if(skilllv==5) maxlv=1; - else if(skilllv==6) maxlv=2; - else if(skilllv>=7) maxlv=3; - } - else if(skillid==MG_FIREBALL){ - if(skilllv==8) maxlv=1; - else if(skilllv>=9) maxlv=2; - } - else if(skillid==MG_FROSTDIVER) maxlv=1; - else return 0; - - if(maxlv > (lv=pc_checkskill(sd,skillid))) - maxlv = lv; - - status_change_start(&sd->bl,SC_AUTOSPELL,skilllv,skillid,maxlv,0, // val1:スキルID val2:使用最大Lv - skill_get_time(SA_AUTOSPELL,skilllv),0);// にしてみたけどbscriptが書き易い???? - return 0; -} - -/*========================================== - * ギャングスタ?パラダイス判定?理(foreachinarea) - *------------------------------------------ - */ - -static int skill_gangster_count(struct block_list *bl,va_list ap) -{ - int *c; - struct map_session_data *sd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - sd=(struct map_session_data*)bl; - c=va_arg(ap,int *); - - if(sd && c && pc_issit(sd) && pc_checkskill(sd,RG_GANGSTER) > 0) - (*c)++; - return 0; -} - -static int skill_gangster_in(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - sd=(struct map_session_data*)bl; - if(sd && pc_issit(sd) && pc_checkskill(sd,RG_GANGSTER) > 0) - sd->state.gangsterparadise=1; - return 0; -} - -static int skill_gangster_out(struct block_list *bl,va_list ap) -{ - struct map_session_data *sd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - sd=(struct map_session_data*)bl; - if(sd && sd->state.gangsterparadise) - sd->state.gangsterparadise=0; - return 0; -} - -int skill_gangsterparadise(struct map_session_data *sd ,int type) -{ - int range=1; - int c=0; - - nullpo_retr(0, sd); - - if(pc_checkskill(sd,RG_GANGSTER) <= 0) - return 0; - - if(type==1) {/* 座った時の?理 */ - map_foreachinarea(skill_gangster_count,sd->bl.m, - sd->bl.x-range,sd->bl.y-range, - sd->bl.x+range,sd->bl.y+range,BL_PC,&c); - if(c > 1) {/*ギャングスタ?成功したら自分にもギャングスタ??性付?*/ - map_foreachinarea(skill_gangster_in,sd->bl.m, - sd->bl.x-range,sd->bl.y-range, - sd->bl.x+range,sd->bl.y+range,BL_PC); - sd->state.gangsterparadise = 1; - } - return 0; - } - else if(type==0) {/* 立ち上がったときの?理 */ - map_foreachinarea(skill_gangster_count,sd->bl.m, - sd->bl.x-range,sd->bl.y-range, - sd->bl.x+range,sd->bl.y+range,BL_PC,&c); - if(c < 2) - map_foreachinarea(skill_gangster_out,sd->bl.m, - sd->bl.x-range,sd->bl.y-range, - sd->bl.x+range,sd->bl.y+range,BL_PC); - sd->state.gangsterparadise = 0; - return 0; - } - return 0; -} -/*========================================== - * 寒いジョ?ク?スクリ?ム判定?理(foreachinarea) - *------------------------------------------ - */ -int skill_frostjoke_scream(struct block_list *bl,va_list ap) -{ - struct block_list *src; - int skillnum,skilllv; - unsigned int tick; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, src=va_arg(ap,struct block_list*)); - - skillnum=va_arg(ap,int); - skilllv=va_arg(ap,int); - if(skilllv <= 0) return 0; - tick=va_arg(ap,unsigned int); - - if(src == bl)//自分には?かない - return 0; - - if (map[src->m].flag.gvg || map[src->m].flag.pvp) - skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick); - // we freeze everybody except of ourselfes on pvp/gvg [veider] - else { - if(battle_check_target(src,bl,BCT_ENEMY) > 0) - skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick); - else if(battle_check_target(src,bl,BCT_PARTY) > 0 && rand()%100 < 10) - skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick); - } - // so on non-pvp/gvg we are just freezing as freezed before - - return 0; -} - -/*========================================== - * Moonlit creates a 'safe zone' [celest] - *------------------------------------------ - */ -static int skill_moonlit_count(struct block_list *bl,va_list ap) -{ - int *c, id; - struct map_session_data *sd; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, (sd=(struct map_session_data *)bl)); - - id=va_arg(ap,int); - c=va_arg(ap,int *); - - if (sd->bl.id != id && sd->sc_count && sd->sc_data[SC_MOONLIT].timer != -1 && c) - (*c)++; - return 0; -} - -int skill_check_moonlit (struct block_list *bl, int dx, int dy) -{ - int c=0; - nullpo_retr(0, bl); - map_foreachinarea(skill_moonlit_count,bl->m, - dx-1,dy-1,dx+1,dy+1,BL_PC,bl->id,&c); - return (c>0); -} - -/*========================================== - * バジリカのセルを設定する - *------------------------------------------ - */ -void skill_basilica_cell(struct skill_unit *unit,int flag) -{ - int i,x,y,range = skill_get_unit_range(HP_BASILICA); - int size = range*2+1; - - for (i=0;i<size*size;i++) { - x = unit->bl.x+(i%size-range); - y = unit->bl.y+(i/size-range); - map_setcell(unit->bl.m,x,y,flag); - } -} - -/*========================================== - * - *------------------------------------------ - */ -int skill_attack_area(struct block_list *bl,va_list ap) -{ - struct block_list *src,*dsrc; - int atk_type,skillid,skilllv,flag,type; - unsigned int tick; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - atk_type = va_arg(ap,int); - if((src=va_arg(ap,struct block_list*)) == NULL) - return 0; - if((dsrc=va_arg(ap,struct block_list*)) == NULL) - return 0; - skillid=va_arg(ap,int); - skilllv=va_arg(ap,int); - //if(skilllv <= 0) return 0; - if(skillid > 0 && skilllv <= 0) return 0; // celest - tick=va_arg(ap,unsigned int); - flag=va_arg(ap,int); - type=va_arg(ap,int); - - if(battle_check_target(dsrc,bl,type) > 0) - skill_attack(atk_type,src,dsrc,bl,skillid,skilllv,tick,flag); - - return 0; -} -/*========================================== - * - *------------------------------------------ - */ -int skill_clear_element_field(struct block_list *bl) -{ - struct mob_data *md=NULL; - struct map_session_data *sd=NULL; - int i,max,skillid; - - nullpo_retr(0, bl); - - if (bl->type==BL_MOB) { - max = MAX_MOBSKILLUNITGROUP; - md = (struct mob_data *)bl; - } else if(bl->type==BL_PC) { - max = MAX_SKILLUNITGROUP; - sd = (struct map_session_data *)bl; - } else - return 0; - - for (i=0;i<max;i++) { - if(sd){ - skillid=sd->skillunit[i].skill_id; - if(skillid==SA_DELUGE||skillid==SA_VOLCANO||skillid==SA_VIOLENTGALE||skillid==SA_LANDPROTECTOR) - skill_delunitgroup(&sd->skillunit[i]); - }else if(md){ - skillid=md->skillunit[i].skill_id; - if(skillid==SA_DELUGE||skillid==SA_VOLCANO||skillid==SA_VIOLENTGALE||skillid==SA_LANDPROTECTOR) - skill_delunitgroup(&md->skillunit[i]); - } - } - return 0; -} -/*========================================== - * ランドプロテクタ?チェック(foreachinarea) - *------------------------------------------ - */ -int skill_landprotector(struct block_list *bl, va_list ap ) -{ - int skillid; - int *alive; - struct skill_unit *unit; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - skillid = va_arg(ap,int); - alive = va_arg(ap,int *); - - if ((unit = (struct skill_unit *)bl) == NULL) - return 0; - - if (skillid == SA_LANDPROTECTOR) - skill_delunit(unit); - else if (alive && unit->group && unit->group->skill_id == SA_LANDPROTECTOR) - (*alive) = 0; - - return 0; -} -/*========================================== - * イドゥンの林檎の回復?理(foreachinarea) - *------------------------------------------ - */ -int skill_idun_heal (struct block_list *bl, va_list ap) -{ - struct skill_unit *unit; - struct skill_unit_group *sg; - int heal; - - nullpo_retr(0, bl); - if (bl->type != BL_PC && bl->type != BL_MOB) - return 0; - - nullpo_retr(0, ap); - nullpo_retr(0, unit = va_arg(ap,struct skill_unit *)); - nullpo_retr(0, sg = unit->group); - if (bl->id == sg->src_id) - return 0; - - heal = 30 + sg->skill_lv * 5 + ((sg->val1) >> 16) * 5 + ((sg->val1) & 0xfff) / 2; - clif_skill_nodamage(&unit->bl, bl, AL_HEAL, heal, 1); - battle_heal(NULL, bl, heal, 0, 0); - - return 0; -} - -/*========================================== - * 指定範??でsrcに?して有?なタ?ゲットのblの?を?える(foreachinarea) - *------------------------------------------ - */ -int skill_count_target (struct block_list *bl, va_list ap) -{ - struct block_list *src; - int *c; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - - if ((src = va_arg(ap,struct block_list *)) == NULL) - return 0; - if ((c = va_arg(ap,int *)) == NULL) - return 0; - if (battle_check_target(src,bl,BCT_ENEMY) > 0) - (*c)++; - return 0; -} -/*========================================== - * トラップ範??理(foreachinarea) - *------------------------------------------ - */ -int skill_trap_splash (struct block_list *bl, va_list ap) -{ - struct block_list *src; - int tick; - int splash_count; - struct skill_unit *unit; - struct skill_unit_group *sg; - struct block_list *ss; - int i; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, src = va_arg(ap,struct block_list *)); - nullpo_retr(0, unit = (struct skill_unit *)src); - nullpo_retr(0, sg = unit->group); - nullpo_retr(0, ss = map_id2bl(sg->src_id)); - - tick = va_arg(ap,int); - splash_count = va_arg(ap,int); - - if(battle_check_target(src,bl,BCT_ENEMY) > 0){ - switch(sg->unit_id){ - case 0x95: /* サンドマン */ - case 0x96: /* フラッシャ? */ - case 0x94: /* ショックウェ?ブトラップ */ - skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,tick); - break; - case 0x8f: /* ブラストマイン */ - case 0x98: /* クレイモア?トラップ */ - for(i=0;i<splash_count;i++){ - skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,(sg->val2)?0x0500:0); - } - break; - case 0x97: /* フリ?ジングトラップ */ - skill_attack(BF_WEAPON, ss,src,bl,sg->skill_id,sg->skill_lv,tick,(sg->val2)?0x0500:0); - break; - default: - break; - } - } - - return 0; -} - -/*========================================== - * ステ?タス異常終了 - *------------------------------------------ - */ -int skill_enchant_elemental_end (struct block_list *bl, int type) -{ - struct status_change *sc_data; - - nullpo_retr(0, bl); - nullpo_retr(0, sc_data = status_get_sc_data(bl)); - - if (type != SC_ENCPOISON && sc_data[SC_ENCPOISON].timer != -1) /* エンチャントポイズン解除 */ - status_change_end(bl, SC_ENCPOISON, -1); - if (type != SC_ASPERSIO && sc_data[SC_ASPERSIO].timer != -1) /* アスペルシオ解除 */ - status_change_end(bl, SC_ASPERSIO, -1); - if (type != SC_FLAMELAUNCHER && sc_data[SC_FLAMELAUNCHER].timer != -1) /* フレイムランチャ解除 */ - status_change_end(bl, SC_FLAMELAUNCHER, -1); - if (type != SC_FROSTWEAPON && sc_data[SC_FROSTWEAPON].timer != -1) /* フロストウェポン解除 */ - status_change_end(bl, SC_FROSTWEAPON, -1); - if (type != SC_LIGHTNINGLOADER && sc_data[SC_LIGHTNINGLOADER].timer != -1) /* ライトニングロ?ダ?解除 */ - status_change_end(bl, SC_LIGHTNINGLOADER, -1); - if (type != SC_SEISMICWEAPON && sc_data[SC_SEISMICWEAPON].timer != -1) /* サイスミックウェポン解除 */ - status_change_end(bl, SC_SEISMICWEAPON, -1); - - return 0; -} - -/* クロ?キング?査(周りに移動不可能地?があるか) */ -int skill_check_cloaking(struct block_list *bl) -{ - struct map_session_data *sd = NULL; - static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1}; //optimized by Lupus - static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1}; - int end = 1,i; - - nullpo_retr(1, bl); - - if (bl->type == BL_PC) { - nullpo_retr(1, sd = (struct map_session_data *)bl); - if (!battle_config.pc_cloak_check_type) // If it's No it shouldn't be checked - return 0; - } else if (bl->type == BL_MOB && !battle_config.monster_cloak_check_type) - return 0; - - for (i = 0; i < 8; i++) { - if (map_getcell(bl->m, bl->x+dx[i], bl->y+dy[i], CELL_CHKNOPASS)) { - end = 0; - break; - } - } - if(end){ - if ((sd && pc_checkskill(sd,AS_CLOAKING)<3) || bl->type == BL_MOB) { - status_change_end(bl, SC_CLOAKING, -1); - } - else if (sd && sd->sc_data[SC_CLOAKING].val3 != 130) { - sd->sc_data[SC_CLOAKING].val3 = 130; - status_calc_speed (sd); - } - } - else { - if (sd && sd->sc_data[SC_CLOAKING].val3 != 103) { - sd->sc_data[SC_CLOAKING].val3 = 103; - status_calc_speed (sd); - } - } - - return end; -} - -/* - *---------------------------------------------------------------------------- - * スキルユニット - *---------------------------------------------------------------------------- - */ - -/*========================================== - * 演奏/ダンスをやめる - * flag 1で合奏中なら相方にユニットを任せる - * - *------------------------------------------ - */ -void skill_stop_dancing(struct block_list *src, int flag) -{ - struct status_change* sc_data; - struct skill_unit_group* group; - short* sc_count; - - nullpo_retv(src); - nullpo_retv(sc_data = status_get_sc_data(src)); - nullpo_retv(sc_count = status_get_sc_count(src)); - - if((*sc_count) > 0 && sc_data[SC_DANCING].timer != -1) { - group = (struct skill_unit_group *)sc_data[SC_DANCING].val2; //ダンスのスキルユニットIDはval2に入ってる - if (src->type == BL_PC) { - if (group && sc_data[SC_DANCING].val4){ //合奏中? - struct map_session_data* dsd = map_id2sd(sc_data[SC_DANCING].val4); //相方のsd取得 - if (flag && dsd) { //ログアウトなど片方が落ちても演奏が??される - if (src->id == group->src_id) { //グル?プを持ってるPCが落ちる - group->src_id = sc_data[SC_DANCING].val4; //相方にグル?プを任せる - if (flag & 1) //ログアウト - dsd->sc_data[SC_DANCING].val4 = 0; //相方の相方を0にして合奏終了→通常のダンス?態 - if(flag & 2) //ハエ飛びなど - return; //合奏もダンス?態も終了させない&スキルユニットは置いてけぼり - } else if (dsd->bl.id == group->src_id) { //相方がグル?プを持っているPCが落ちる(自分はグル?プを持っていない) - if (flag & 1) //ログアウト - dsd->sc_data[SC_DANCING].val4 = 0; //相方の相方を0にして合奏終了→通常のダンス?態 - if(flag & 2) //ハエ飛びなど - return; //合奏もダンス?態も終了させない&スキルユニットは置いてけぼり - } - status_change_end(src, SC_DANCING, -1); //自分のステ?タスを終了させる - //そしてグル?プは消さない&消さないのでステ?タス計算もいらない? - return; - } else if (dsd) { - if (src->id == group->src_id) //グル?プを持ってるPCが止める - status_change_end(&dsd->bl, SC_DANCING, -1); //相手のステ?タスを終了させる - if(dsd->bl.id == group->src_id) //相方がグル?プを持っているPCが止める(自分はグル?プを持っていない) - status_change_end(src, SC_DANCING, -1); //自分のステ?タスを終了させる - } - } - if(flag & 2 && group) { //ハエで飛んだときとかはユニットも飛ぶ - struct map_session_data *sd = (struct map_session_data *)src; - if (sd) skill_unit_move_unit_group(group, sd->bl.m, (sd->to_x - sd->bl.x), (sd->to_y - sd->bl.y)); - return; - } - } - skill_delunitgroup(group); - } -} - -/*========================================== - * スキルユニット初期化 - *------------------------------------------ - */ -struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,int y) -{ - struct skill_unit *unit; - - nullpo_retr(NULL, group); - nullpo_retr(NULL, unit=&group->unit[idx]); - - if(!unit->alive) - group->alive_count++; - - unit->bl.id=map_addobject(&unit->bl); - unit->bl.type=BL_SKILL; - unit->bl.m=group->map; - unit->bl.x=x; - unit->bl.y=y; - unit->group=group; - unit->val1=unit->val2=0; - unit->alive=1; - - map_addblock(&unit->bl); - clif_skill_setunit(unit); - - if (group->skill_id==HP_BASILICA) - skill_basilica_cell(unit,CELL_SETBASILICA); - - return unit; -} - -/*========================================== - * スキルユニット削除 - *------------------------------------------ - */ -int skill_delunit(struct skill_unit *unit) -{ - struct skill_unit_group *group; - - nullpo_retr(0, unit); - if(!unit->alive) - return 0; - nullpo_retr(0, group=unit->group); - - /* onlimitイベント呼び出し */ - skill_unit_onlimit( unit,gettick() ); - - /* onoutイベント呼び出し */ - if (!unit->range) { - map_foreachinarea(skill_unit_effect,unit->bl.m, - unit->bl.x,unit->bl.y,unit->bl.x,unit->bl.y,0, - &unit->bl,gettick(),0); - } - - if (group->skill_id==HP_BASILICA) - skill_basilica_cell(unit,CELL_CLRBASILICA); - - clif_skill_delunit(unit); - - unit->group=NULL; - unit->alive=0; - map_delobjectnofree(unit->bl.id); - if(group->alive_count>0 && (--group->alive_count)<=0) - skill_delunitgroup(group); - - return 0; -} -/*========================================== - * スキルユニットグル?プ初期化 - *------------------------------------------ - */ -static int skill_unit_group_newid = MAX_SKILL_DB; -struct skill_unit_group *skill_initunitgroup(struct block_list *src, - int count,int skillid,int skilllv,int unit_id) -{ - int i; - struct skill_unit_group *group=NULL, *list=NULL; - int maxsug=0; - - if(skilllv <= 0) return 0; - - nullpo_retr(NULL, src); - - if(src->type==BL_PC){ - list=((struct map_session_data *)src)->skillunit; - maxsug=MAX_SKILLUNITGROUP; - }else if(src->type==BL_MOB){ - list=((struct mob_data *)src)->skillunit; - maxsug=MAX_MOBSKILLUNITGROUP; - }else if(src->type==BL_PET){ - list=((struct pet_data *)src)->skillunit; - maxsug=MAX_MOBSKILLUNITGROUP; - } - if(list){ - for(i=0;i<maxsug;i++) /* 空いているもの?索 */ - if(list[i].group_id==0){ - group=&list[i]; - break; - } - - if(group==NULL){ /* 空いてないので古いもの?索 */ - int j=0; - unsigned maxdiff=0,x,tick=gettick(); - for(i=0;i<maxsug;i++) - if((x=DIFF_TICK(tick,list[i].tick))>maxdiff){ - maxdiff=x; - j=i; - } - skill_delunitgroup(&list[j]); - group=&list[j]; - } - } - - if(group==NULL){ - printf("skill_initunitgroup: error unit group !\n"); - exit(1); - } - - group->src_id=src->id; - group->party_id=status_get_party_id(src); - group->guild_id=status_get_guild_id(src); - group->group_id=skill_unit_group_newid++; - if(skill_unit_group_newid<=0) - skill_unit_group_newid = MAX_SKILL_DB; - group->unit=(struct skill_unit *)aCalloc(count,sizeof(struct skill_unit)); - group->unit_count=count; - group->val1=group->val2=0; - group->skill_id=skillid; - group->skill_lv=skilllv; - group->unit_id=unit_id; - group->map=src->m; - group->limit=10000; - group->interval=1000; - group->tick=gettick(); - group->valstr=NULL; - - if (skill_get_unit_flag(skillid)&UF_DANCE) { - struct map_session_data *sd = NULL; - if(src->type==BL_PC && (sd=(struct map_session_data *)src) ){ - sd->skillid_dance=skillid; - sd->skilllv_dance=skilllv; - } - status_change_start(src,SC_DANCING,skillid,(int)group,0,0,skill_get_time(skillid,skilllv)+1000,0); - //合奏スキルは相方をダンス状態にする - if (sd && skill_get_unit_flag(skillid)&UF_ENSEMBLE) { - int c=0; - map_foreachinarea(skill_check_condition_use_sub,sd->bl.m, - sd->bl.x-1,sd->bl.y-1,sd->bl.x+1,sd->bl.y+1,BL_PC,&sd->bl,&c); - } - } - return group; -} - -/*========================================== - * スキルユニットグル?プ削除 - *------------------------------------------ - */ -int skill_delunitgroup(struct skill_unit_group *group) -{ - struct block_list *src; - int i; - - nullpo_retr(0, group); - if(group->unit_count<=0) - return 0; - - src=map_id2bl(group->src_id); - //ダンススキルはダンス状態を解除する - if(src) { - if (skill_get_unit_flag(group->skill_id)&UF_DANCE) - status_change_end(src,SC_DANCING,-1); - if (group->unit_id == 0x86) { - struct status_change *sc_data = status_get_sc_data(src); - if(sc_data && sc_data[SC_MAGICPOWER].timer != -1) //マジックパワ?の?果終了 - status_change_end(src,SC_MAGICPOWER,-1); - } - } - - group->alive_count=0; - if(group->unit!=NULL){ - for(i=0;i<group->unit_count;i++) - if(group->unit[i].alive) - skill_delunit(&group->unit[i]); - } - if(group->valstr!=NULL){ - map_freeblock(group->valstr); - group->valstr=NULL; - } - - map_freeblock(group->unit); /* aFree()の替わり */ - group->unit=NULL; - group->src_id=0; - group->group_id=0; - group->unit_count=0; - return 0; -} - -/*========================================== - * スキルユニットグル?プ全削除 - *------------------------------------------ - */ -int skill_clear_unitgroup(struct block_list *src) -{ - struct skill_unit_group *group=NULL; - int maxsug=0; - - nullpo_retr(0, src); - - if(src->type==BL_PC){ - group=((struct map_session_data *)src)->skillunit; - maxsug=MAX_SKILLUNITGROUP; - } else if(src->type==BL_MOB){ - group=((struct mob_data *)src)->skillunit; - maxsug=MAX_MOBSKILLUNITGROUP; - } else if(src->type==BL_PET){ // [Valaris] - group=((struct pet_data *)src)->skillunit; - maxsug=MAX_MOBSKILLUNITGROUP; - } else - return 0; - if(group){ - int i; - for(i=0;i<maxsug;i++) - if(group[i].group_id>0 && group[i].src_id == src->id) - skill_delunitgroup(&group[i]); - } - return 0; -} - -/*========================================== - * スキルユニットグル?プの被影響tick?索 - *------------------------------------------ - */ -struct skill_unit_group_tickset *skill_unitgrouptickset_search( - struct block_list *bl,struct skill_unit_group *group,int tick) -{ - int i,j=-1,k,s,id; - struct skill_unit_group_tickset *set; - - nullpo_retr(0, bl); - if (group->interval==-1) - return NULL; - - if (bl->type == BL_PC) - set = ((struct map_session_data *)bl)->skillunittick; - else if (bl->type == BL_MOB) - set = ((struct mob_data *)bl)->skillunittick; - else - return 0; - - if (skill_get_unit_flag(group->skill_id)&UF_NOOVERLAP) - id = s = group->skill_id; - else - id = s = group->group_id; - - for (i=0; i<MAX_SKILLUNITGROUPTICKSET; i++) { - k = (i+s) % MAX_SKILLUNITGROUPTICKSET; - if (set[k].id == id) - return &set[k]; - else if (j==-1 && (DIFF_TICK(tick,set[k].tick)>0 || set[k].id==0)) - j=k; - } - - if (j == -1) { - if(battle_config.error_log) { - sprintf (tmp_output, "skill_unitgrouptickset_search: tickset is full\n"); - ShowWarning (tmp_output); - } - j = id % MAX_SKILLUNITGROUPTICKSET; - } - - set[j].id = id; - set[j].tick = tick; - return &set[j]; -} - -/*========================================== - * スキルユニットタイマ??動?理用(foreachinarea) - *------------------------------------------ - */ -int skill_unit_timer_sub_onplace( struct block_list *bl, va_list ap ) -{ - struct skill_unit *unit; - struct skill_unit_group *group; - unsigned int tick; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - unit = va_arg(ap,struct skill_unit *); - tick = va_arg(ap,unsigned int); - - if (bl->type!=BL_PC && bl->type!=BL_MOB) - return 0; - if (!unit->alive || bl->prev==NULL) - return 0; - - nullpo_retr(0, group=unit->group); - - if (battle_check_target(&unit->bl,bl,group->target_flag)<=0) - return 0; - - skill_unit_onplace_timer(unit,bl,tick); - - return 0; -} - -/*========================================== - * スキルユニットタイマ??理用(foreachobject) - *------------------------------------------ - */ -int skill_unit_timer_sub( struct block_list *bl, va_list ap ) -{ - struct skill_unit *unit; - struct skill_unit_group *group; - int range; - unsigned int tick; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, unit=(struct skill_unit *)bl); - tick=va_arg(ap,unsigned int); - - if(!unit->alive) - return 0; - group=unit->group; - - nullpo_retr(0, group); - range = unit->range; - - /* onplace_timerイベント呼び出し */ - if (range>=0 && group->interval!=-1) { - map_foreachinarea(skill_unit_timer_sub_onplace, bl->m, - bl->x-range,bl->y-range,bl->x+range,bl->y+range,0,bl,tick); - if (!unit->alive) - return 0; - // マグヌスは発動したユニットは削除する - if (group->skill_id==PR_MAGNUS && unit->val2) { - skill_delunit(unit); - return 0; - } - } - // イドゥンの林檎による回復 - if (group->unit_id==0xaa && DIFF_TICK(tick,group->tick)>=6000*group->val3) { - struct block_list *src = map_id2bl(group->src_id); - int range = skill_get_unit_layout_type(group->skill_id,group->skill_lv); - nullpo_retr(0, src); - map_foreachinarea(skill_idun_heal,src->m, - src->x-range,src->y-range,src->x+range,src->y+range,0,unit); - group->val3++; - } - /* 時間切れ削除 */ - if((DIFF_TICK(tick,group->tick)>=group->limit || DIFF_TICK(tick,group->tick)>=unit->limit)){ - switch(group->unit_id){ - case 0x8f: /* ブラストマイン */ - group->unit_id = 0x8c; - clif_changelook(bl,LOOK_BASE,group->unit_id); - group->limit=DIFF_TICK(tick+1500,group->tick); - unit->limit=DIFF_TICK(tick+1500,group->tick); - break; - case 0x90: /* スキッドトラップ */ - case 0x91: /* アンクルスネア */ - case 0x93: /* ランドマイン */ - case 0x94: /* ショックウェ?ブトラップ */ - case 0x95: /* サンドマン */ - case 0x96: /* フラッシャ? */ - case 0x97: /* フリ?ジングトラップ */ - case 0x98: /* クレイモア?トラップ */ - case 0x99: /* ト?キ?ボックス */ - { - struct block_list *src=map_id2bl(group->src_id); - if(group->unit_id == 0x91 && group->val2); - else{ - if(src && src->type==BL_PC){ - struct item item_tmp; - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid=1065; - item_tmp.identify=1; - map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,NULL,NULL,NULL,0); // ?返還 - } - } - skill_delunit(unit); - } - break; - - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - { - struct block_list *src=map_id2bl(group->src_id); - if (src) - group->tick = tick; - } - break; - - default: - skill_delunit(unit); - } - } - - if(group->unit_id == 0x8d) { - unit->val1 -= 5; - if(unit->val1 <= 0 && unit->limit + group->tick > tick + 700) - unit->limit = DIFF_TICK(tick+700,group->tick); - } - - return 0; -} -/*========================================== - * スキルユニットタイマ??理 - *------------------------------------------ - */ -int skill_unit_timer( int tid,unsigned int tick,int id,int data) -{ - map_freeblock_lock(); - - map_foreachobject( skill_unit_timer_sub, BL_SKILL, tick ); - - map_freeblock_unlock(); - - return 0; -} - -/*========================================== - * スキルユニット移動時?理用(foreachinarea) - *------------------------------------------ - */ -int skill_unit_move_sub( struct block_list *bl, va_list ap ) -{ - struct skill_unit *unit = (struct skill_unit *)bl; - struct skill_unit_group *group; - struct block_list *target; - unsigned int tick,flag; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, target=va_arg(ap,struct block_list*)); - tick = va_arg(ap,unsigned int); - flag = va_arg(ap,int); - - if (target->type!=BL_PC && target->type!=BL_MOB) - return 0; - - nullpo_retr(0, group=unit->group); - if (group->interval!=-1) - return 0; - - if (!unit->alive || target->prev==NULL) - return 0; - - if (flag) - skill_unit_onplace(unit,target,tick); - else - skill_unit_onout(unit,target,tick); - - return 0; -} - -/*========================================== - * スキルユニット移動時?理 - *------------------------------------------ - */ -int skill_unit_move(struct block_list *bl,unsigned int tick,int flag) -{ - nullpo_retr(0, bl); - - if(bl->prev==NULL ) - return 0; - - map_foreachinarea(skill_unit_move_sub, - bl->m,bl->x,bl->y,bl->x,bl->y,BL_SKILL,bl,tick,flag); - - return 0; -} - -/*========================================== - * スキルユニット自?の移動時?理 - * 引?はグル?プと移動量 - *------------------------------------------ - */ -int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy) -{ - int i,j; - int tick = gettick(); - int *m_flag; - struct skill_unit *unit1; - struct skill_unit *unit2; - - nullpo_retr(0, group); - if (group->unit_count<=0) - return 0; - if (group->unit==NULL) - return 0; - - // 移動可能なスキルはダンス系と、ブラストマイン、クレイモアートラップのみ - if (!(skill_get_unit_flag(group->skill_id)&UF_DANCE) && - group->skill_id!=HT_CLAYMORETRAP && group->skill_id!=HT_BLASTMINE) - return 0; - - m_flag = (int *) aMalloc(sizeof(int)*group->unit_count); - memset(m_flag,0,sizeof(int)*group->unit_count);// 移動フラグ - // 先にフラグを全部決める - // m_flag - // 0: 単純移動 - // 1: ユニットを移動する(現位置からユニットがなくなる) - // 2: 残留&新位置が移動先となる(移動先にユニットが存在しない) - // 3: 残留 - for(i=0;i<group->unit_count;i++){ - unit1=&group->unit[i]; - if (!unit1->alive || unit1->bl.m!=m) - continue; - for(j=0;j<group->unit_count;j++){ - unit2=&group->unit[j]; - if (!unit2->alive) - continue; - if (unit1->bl.x+dx==unit2->bl.x && unit1->bl.y+dy==unit2->bl.y){ - // 移動先にユニットがかぶっている - m_flag[i] |= 0x1; - } - if (unit1->bl.x-dx==unit2->bl.x && unit1->bl.y-dy==unit2->bl.y){ - // ユニットがこの場所にやってくる - m_flag[i] |= 0x2; - } - } - } - // フラグに基づいてユニット移動 - // フラグが1のunitを探し、フラグが2のunitの移動先に移す - j = 0; - for (i=0;i<group->unit_count;i++) { - unit1=&group->unit[i]; - if (!unit1->alive) - continue; - if (!(m_flag[i]&0x2)) { - // ユニットがなくなる場所でスキルユニット影響を消す - map_foreachinarea(skill_unit_effect,unit1->bl.m, - unit1->bl.x,unit1->bl.y,unit1->bl.x,unit1->bl.y,0, - &unit1->bl,tick,0); - } - if (m_flag[i]==0) { - // 単純移動 - map_delblock(&unit1->bl); - unit1->bl.m = m; - unit1->bl.x += dx; - unit1->bl.y += dy; - map_addblock(&unit1->bl); - clif_skill_setunit(unit1); - } else if (m_flag[i]==1) { - // フラグが2のものを探してそのユニットの移動先に移動 - for(;j<group->unit_count;j++) { - if (m_flag[j]==2) { - // 継承移動 - unit2 = &group->unit[j]; - if (!unit2->alive) - continue; - map_delblock(&unit1->bl); - unit1->bl.m = m; - unit1->bl.x = unit2->bl.x+dx; - unit1->bl.y = unit2->bl.y+dy; - map_addblock(&unit1->bl); - clif_skill_setunit(unit1); - j++; - break; - } - } - } - if (!(m_flag[i]&0x2)) { - // 移動後の場所でスキルユニットを発動 - map_foreachinarea(skill_unit_effect,unit1->bl.m, - unit1->bl.x,unit1->bl.y,unit1->bl.x,unit1->bl.y,0, - &unit1->bl,tick,1); - } - } - aFree(m_flag); - return 0; -} - -/*---------------------------------------------------------------------------- - * アイテム合成 - *---------------------------------------------------------------------------- - */ - -/*========================================== - * アイテム合成可能判定 - *------------------------------------------ - */ -int skill_can_produce_mix( struct map_session_data *sd, int nameid, int trigger ) -{ - int i,j; - - nullpo_retr(0, sd); - - if(nameid<=0) - return 0; - - for(i=0;i<MAX_SKILL_PRODUCE_DB;i++){ - if(skill_produce_db[i].nameid == nameid ) - break; - } - if( i >= MAX_SKILL_PRODUCE_DB ) /* デ?タベ?スにない */ - return 0; - - if(trigger>=0){ - if(trigger == 32 || trigger == 16 || trigger==64 || trigger == 256) { - if(skill_produce_db[i].itemlv!=trigger) /* ファ?マシ?*ポ?ション類と溶??*?石以外はだめ */ - return 0; - }else{ - if(skill_produce_db[i].itemlv>=16) /* 武器以外はだめ */ - return 0; - if( itemdb_wlv(nameid)>trigger ) /* 武器Lv判定 */ - return 0; - } - } - if( (j=skill_produce_db[i].req_skill)>0 && pc_checkskill(sd,j)<=0 ) - return 0; /* スキルが足りない */ - - for(j=0;j<MAX_PRODUCE_RESOURCE;j++){ - int id,x,y; - if( (id=skill_produce_db[i].mat_id[j]) <= 0 ) /* これ以上は材料要らない */ - continue; - if(skill_produce_db[i].mat_amount[j] <= 0) { - if(pc_search_inventory(sd,id) < 0) - return 0; - } - else { - for(y=0,x=0;y<MAX_INVENTORY;y++) - if( sd->status.inventory[y].nameid == id ) - x+=sd->status.inventory[y].amount; - if(x<skill_produce_db[i].mat_amount[j]) /* アイテムが足りない */ - return 0; - } - } - return i+1; -} - -/*========================================== - * アイテム合成可能判定 - *------------------------------------------ - */ -int skill_produce_mix( struct map_session_data *sd, - int nameid, int slot1, int slot2, int slot3 ) -{ - int slot[3]; - int i,sc,ele,idx,equip,wlv,make_per,flag; - - nullpo_retr(0, sd); - - if( !(idx=skill_can_produce_mix(sd,nameid,-1)) ) /* ?件不足 */ - return 0; - idx--; - slot[0]=slot1; - slot[1]=slot2; - slot[2]=slot3; - - /* 埋め?み?理 */ - for(i=0,sc=0,ele=0;i<3;i++){ - int j; - if( slot[i]<=0 ) - continue; - j = pc_search_inventory(sd,slot[i]); - if(j < 0) /* 不正パケット(アイテム存在)チェック */ - continue; - if(slot[i]==1000){ /* 星のかけら */ - pc_delitem(sd,j,1,1); - sc++; - } - if(slot[i]>=994 && slot[i]<=997 && ele==0){ /* ?性石 */ - static const int ele_table[4]={3,1,4,2}; - pc_delitem(sd,j,1,1); - ele=ele_table[slot[i]-994]; - } - } - - /* 材料消費 */ - for(i=0;i<MAX_PRODUCE_RESOURCE;i++){ - int j,id,x; - if( (id=skill_produce_db[idx].mat_id[i]) <= 0 ) - continue; - x=skill_produce_db[idx].mat_amount[i]; /* 必要な個? */ - do{ /* 2つ以上のインデックスにまたがっているかもしれない */ - int y=0; - j = pc_search_inventory(sd,id); - - if(j >= 0){ - y = sd->status.inventory[j].amount; - if(y>x)y=x; /* 足りている */ - pc_delitem(sd,j,y,0); - }else { - if(battle_config.error_log) - printf("skill_produce_mix: material item error\n"); - } - - x-=y; /* まだ足りない個?を計算 */ - }while( j>=0 && x>0 ); /* 材料を消費するか、エラ?になるまで繰り返す */ - } - - /* 確率判定 */ - equip = itemdb_isequip(nameid); - if(!equip) { -// Corrected rates [DracoRPG] --------------------------// - if(skill_produce_db[idx].req_skill==AM_PHARMACY) { - make_per = pc_checkskill(sd,AM_LEARNINGPOTION)*100 - + pc_checkskill(sd,AM_PHARMACY)*300 + sd->status.job_level*20 - + sd->paramc[4]*10+sd->paramc[5]*10; - - if(nameid >= 501 && nameid <= 505) // Normal potions - make_per += 2000 + pc_checkskill(sd,AM_POTIONPITCHER)*100; - else if(nameid >= 605 && nameid <= 606) // Anodyne & Aloevera (not sure of the formula, I put the same base value as normal pots but without the Aid Potion bonus since they are not throwable pots ^^) - make_per += 2000; - else if(nameid >= 545 && nameid <= 547) // Concentrated potions - ; - else if(nameid == 970) // Alcohol - make_per += 1000; - else if(nameid == 7135) // Bottle Grenade - make_per += 500 + pc_checkskill(sd,AM_DEMONSTRATION)*100; - else if(nameid == 7136) // Acid Bottle - make_per += 500 + pc_checkskill(sd,AM_ACIDTERROR)*100; - else if(nameid == 7137) // Plant Bottle - make_per += 500 + pc_checkskill(sd,AM_CANNIBALIZE)*100; - else if(nameid == 7138) // Marine Sphere Bottle - make_per += 500 + pc_checkskill(sd,AM_SPHEREMINE)*100; - else if(nameid == 7139) // Glistening Coat - make_per += 500 + pc_checkskill(sd,AM_CP_WEAPON)*100 + pc_checkskill(sd,AM_CP_SHIELD)*100 + - pc_checkskill(sd,AM_CP_ARMOR)*100 + pc_checkskill(sd,AM_CP_HELM)*100; - } else if (skill_produce_db[idx].req_skill == ASC_CDP) { - make_per = 2000 + 40*sd->paramc[4] + 20*sd->paramc[5]; - } else { - if(nameid == 998) - make_per = 1500 + sd->status.job_level*35 + sd->paramc[4]*10 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*600; - else - make_per = 1000 + sd->status.job_level*35 + sd->paramc[4]*10 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*500; - } - if(battle_config.pp_rate != 100) - make_per = make_per * battle_config.pp_rate / 100; - } else { // Corrected rates [DracoRPG] - int add_per=0; - if(pc_search_inventory(sd,989) >= 0) add_per = 400; - else if(pc_search_inventory(sd,988) >= 0) add_per = 300; - else if(pc_search_inventory(sd,987) >= 0) add_per = 200; - else if(pc_search_inventory(sd,986) >= 0) add_per = 100; - wlv = itemdb_wlv(nameid); - make_per = 1500 + sd->status.job_level*35 + sd->paramc[4]*10 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*1000 + pc_checkskill(sd,BS_WEAPONRESEARCH)*100 + - ((wlv >= 3)? pc_checkskill(sd,BS_ORIDEOCON)*100 : 0) + add_per - (ele? 2500:0) - sc*((4-wlv)*500) - wlv*1000; - if(battle_config.wp_rate != 100) /* 確率補正 */ - make_per = make_per * battle_config.wp_rate / 100; - } -// -----------------------------------------------------// - - if(make_per < 1) make_per = 1; - -// if(battle_config.etc_log) -// printf("make rate = %d\n",make_per); - - if(rand()%10000 < make_per){ - /* 成功 */ - struct item tmp_item; - memset(&tmp_item,0,sizeof(tmp_item)); - tmp_item.nameid=nameid; - tmp_item.amount=1; - tmp_item.identify=1; - if(equip){ /* 武器の場合 */ - tmp_item.card[0]=0x00ff; /* 製造武器フラグ */ - tmp_item.card[1]=((sc*5)<<8)+ele; /* ?性とつよさ */ - *((unsigned long *)(&tmp_item.card[2]))=sd->char_id; /* キャラID */ - } - else if((battle_config.produce_item_name_input && skill_produce_db[idx].req_skill!=AM_PHARMACY) || - (battle_config.produce_potion_name_input && skill_produce_db[idx].req_skill==AM_PHARMACY)) { - tmp_item.card[0]=0x00fe; - tmp_item.card[1]=0; - *((unsigned long *)(&tmp_item.card[2]))=sd->char_id; /* キャラID */ - } - - if(log_config.produce > 0) - log_produce(sd,nameid,slot1,slot2,slot3,1); - - switch (skill_produce_db[idx].req_skill) { - case AM_PHARMACY: - clif_produceeffect(sd,2,nameid);/* 製?エフェクト */ - clif_misceffect(&sd->bl,5); /* 他人にも成功を通知 */ - break; - case ASC_CDP: - clif_produceeffect(sd,2,nameid);/* 暫定で製?エフェクト */ - clif_misceffect(&sd->bl,5); - break; - default: /* 武器製造、コイン製造 */ - clif_produceeffect(sd,0,nameid); /* 武器製造エフェクト */ - clif_misceffect(&sd->bl,3); - break; - } - - if((flag = pc_additem(sd,&tmp_item,1))) { - clif_additem(sd,0,0,flag); - map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } else { - if(log_config.produce > 0) - log_produce(sd,nameid,slot1,slot2,slot3,0); - - switch (skill_produce_db[idx].req_skill) { - case AM_PHARMACY: - clif_produceeffect(sd,3,nameid);/* 製?失敗エフェクト */ - clif_misceffect(&sd->bl,6); /* 他人にも失敗を通知 */ - break; - case ASC_CDP: - { - clif_produceeffect(sd,3,nameid); /* 暫定で製?エフェクト */ - clif_misceffect(&sd->bl,6); /* 他人にも失敗を通知 */ - pc_heal(sd, -(sd->status.max_hp>>2), 0); - } - break; - default: - clif_produceeffect(sd,1,nameid);/* 武器製造失敗エフェクト */ - clif_misceffect(&sd->bl,2); /* 他人にも失敗を通知 */ - break; - } - } - return 0; -} - -int skill_arrow_create( struct map_session_data *sd,int nameid) -{ - int i,j,flag,index=-1; - struct item tmp_item; - - nullpo_retr(0, sd); - - if(nameid <= 0) - return 1; - - for(i=0;i<MAX_SKILL_ARROW_DB;i++) - if(nameid == skill_arrow_db[i].nameid) { - index = i; - break; - } - - if(index < 0 || (j = pc_search_inventory(sd,nameid)) < 0) - return 1; - - pc_delitem(sd,j,1,0); - for(i=0;i<5;i++) { - memset(&tmp_item,0,sizeof(tmp_item)); - tmp_item.identify = 1; - tmp_item.nameid = skill_arrow_db[index].cre_id[i]; - tmp_item.amount = skill_arrow_db[index].cre_amount[i]; - if(battle_config.making_arrow_name_input) { - tmp_item.card[0]=0x00fe; - tmp_item.card[1]=0; - *((unsigned long *)(&tmp_item.card[2]))=sd->char_id; /* キャラID */ - } - if(tmp_item.nameid <= 0 || tmp_item.amount <= 0) - continue; - if((flag = pc_additem(sd,&tmp_item,tmp_item.amount))) { - clif_additem(sd,0,0,flag); - map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); - } - } - - return 0; -} - -/*---------------------------------------------------------------------------- - * 初期化系 - */ - -/*---------------------------------------------------------------------------- - * 初期化系 - */ - -/* - * 文字列処理 - * ',' で区切って val に戻す - */ -int skill_split_str(char *str,char **val,int num) -{ - int i; - - for (i=0; i<num && str; i++){ - val[i] = str; - str = strchr(str,','); - if (str) - *str++=0; - } - return i; -} -/* - * 文字列処理 - * ':' で区切ってatoiしてvalに戻す - */ -int skill_split_atoi(char *str,int *val) -{ - int i, max = 0; - - for (i=0; i<MAX_SKILL_LEVEL; i++) { - if (str) { - val[i] = max = atoi(str); - str = strchr(str,':'); - if (str) - *str++=0; - } else { - val[i] = max; - } - } - return i; -} - -/* - * スキルユニットの配置情報作成 - */ -void skill_init_unit_layout() -{ - int i,j,size,pos = 0; - - memset(skill_unit_layout,0,sizeof(skill_unit_layout)); - // 矩形のユニット配置を作成する - for (i=0; i<=MAX_SQUARE_LAYOUT; i++) { - size = i*2+1; - skill_unit_layout[i].count = size*size; - for (j=0; j<size*size; j++) { - skill_unit_layout[i].dx[j] = (j%size-i); - skill_unit_layout[i].dy[j] = (j/size-i); - } - } - pos = i; - // 矩形以外のユニット配置を作成する - for (i=0;i<MAX_SKILL_DB;i++) { - if (!skill_db[i].unit_id[0] || skill_db[i].unit_layout_type[0] != -1) - continue; - switch (i) { - case MG_FIREWALL: - case WZ_ICEWALL: - // ファイアーウォール、アイスウォールは方向で変わるので別処理 - break; - case PR_SANCTUARY: - { - static const int dx[] = { - -1, 0, 1,-2,-1, 0, 1, 2,-2,-1, - 0, 1, 2,-2,-1, 0, 1, 2,-1, 0, 1}; - static const int dy[]={ - -2,-2,-2,-1,-1,-1,-1,-1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2}; - skill_unit_layout[pos].count = 21; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - break; - } - case PR_MAGNUS: - { - static const int dx[] = { - -1, 0, 1,-1, 0, 1,-3,-2,-1, 0, - 1, 2, 3,-3,-2,-1, 0, 1, 2, 3, - -3,-2,-1, 0, 1, 2, 3,-1, 0, 1,-1, 0, 1}; - static const int dy[] = { - -3,-3,-3,-2,-2,-2,-1,-1,-1,-1, - -1,-1,-1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3}; - skill_unit_layout[pos].count = 33; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - break; - } - case AS_VENOMDUST: - { - static const int dx[] = {-1, 0, 0, 0, 1}; - static const int dy[] = { 0,-1, 0, 1, 0}; - skill_unit_layout[pos].count = 5; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - break; - } - case CR_GRANDCROSS: - case NPC_DARKGRANDCROSS: - { - static const int dx[] = { - 0, 0,-1, 0, 1,-2,-1, 0, 1, 2, - -4,-3,-2,-1, 0, 1, 2, 3, 4,-2, - -1, 0, 1, 2,-1, 0, 1, 0, 0}; - static const int dy[] = { - -4,-3,-2,-2,-2,-1,-1,-1,-1,-1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 2, 2, 2, 3, 4}; - skill_unit_layout[pos].count = 29; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - break; - } - case PF_FOGWALL: - { - static const int dx[] = { - -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; - static const int dy[] = { - -1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}; - skill_unit_layout[pos].count = 15; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - break; - } - case PA_GOSPEL: - { - static const int dx[] = { - -1, 0, 1,-1, 0, 1,-3,-2,-1, 0, - 1, 2, 3,-3,-2,-1, 0, 1, 2, 3, - -3,-2,-1, 0, 1, 2, 3,-1, 0, 1, - -1, 0, 1}; - static const int dy[] = { - -3,-3,-3,-2,-2,-2,-1,-1,-1,-1, - -1,-1,-1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 3, 3, 3}; - skill_unit_layout[pos].count = 33; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - break; - } - default: - printf("unknown unit layout at skill %d\n",i); - break; - } - if (!skill_unit_layout[pos].count) - continue; - for (j=0;j<MAX_SKILL_LEVEL;j++) - skill_db[i].unit_layout_type[j] = pos; - pos++; - } - // ファイヤーウォール - firewall_unit_pos = pos; - for (i=0;i<8;i++) { - if (i&1) { /* 斜め配置 */ - skill_unit_layout[pos].count = 5; - if (i&0x2) { - int dx[] = {-1,-1, 0, 0, 1}; - int dy[] = { 1, 0, 0,-1,-1}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } else { - int dx[] = { 1, 1 ,0, 0,-1}; - int dy[] = { 1, 0, 0,-1,-1}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } - } else { /* 縦横配置 */ - skill_unit_layout[pos].count = 3; - if (i%4==0) { /* 上下 */ - int dx[] = {-1, 0, 1}; - int dy[] = { 0, 0, 0}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } else { /* 左右 */ - int dx[] = { 0, 0, 0}; - int dy[] = {-1, 0, 1}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } - } - pos++; - } - // アイスウォール - icewall_unit_pos = pos; - for (i=0;i<8;i++) { - skill_unit_layout[pos].count = 5; - if (i&1) { /* 斜め配置 */ - if (i&0x2) { - int dx[] = {-2,-1, 0, 1, 2}; - int dy[] = { 2,-1, 0,-1,-2}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } else { - int dx[] = { 2, 1 ,0,-1,-2}; - int dy[] = { 2, 1, 0,-1,-2}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } - } else { /* 縦横配置 */ - if (i%4==0) { /* 上下 */ - int dx[] = {-2,-1, 0, 1, 2}; - int dy[] = { 0, 0, 0, 0, 0}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } else { /* 左右 */ - int dx[] = { 0, 0, 0, 0, 0}; - int dy[] = {-2,-1, 0, 1, 2}; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } - } - pos++; - } -} - -/*========================================== - * スキル?係ファイル?み?み - * skill_db.txt スキルデ?タ - * skill_cast_db.txt スキルの詠唱時間とディレイデ?タ - * produce_db.txt アイテム作成スキル用デ?タ - * create_arrow_db.txt 矢作成スキル用デ?タ - * abra_db.txt アブラカダブラ?動スキルデ?タ - *------------------------------------------ - */ -int skill_readdb(void) -{ - int i,j,k,l,m; - FILE *fp; - char line[1024],*p; - char *filename[]={"db/produce_db.txt","db/produce_db2.txt"}; - - /* スキルデ?タベ?ス */ - memset(skill_db,0,sizeof(skill_db)); - fp=fopen("db/skill_db.txt","r"); - if(fp==NULL){ - printf("can't read db/skill_db.txt\n"); - return 1; - } - while(fgets(line,1020,fp)){ - char *split[50]; - if(line[0]=='/' && line[1]=='/') - continue; - j = skill_split_str(line,split,14); - if(split[13]==NULL || j<14) - continue; - - i=atoi(split[0]); - if (i>=10000 && i<10015) // for guild skills [Celest] - i -= 9500; - else if(i<=0 || i>MAX_SKILL_DB) - continue; - -/* printf("skill id=%d\n",i); */ - skill_split_atoi(split[1],skill_db[i].range); - skill_db[i].hit=atoi(split[2]); - skill_db[i].inf=atoi(split[3]); - skill_db[i].pl=atoi(split[4]); - skill_db[i].nk=atoi(split[5]); - skill_db[i].max=atoi(split[6]); - skill_split_atoi(split[7],skill_db[i].num); - - if(strcmpi(split[8],"yes") == 0) - skill_db[i].castcancel=1; - else - skill_db[i].castcancel=0; - skill_db[i].cast_def_rate=atoi(split[9]); - skill_db[i].inf2=atoi(split[10]); - skill_db[i].maxcount=atoi(split[11]); - if(strcmpi(split[12],"weapon") == 0) - skill_db[i].skill_type=BF_WEAPON; - else if(strcmpi(split[12],"magic") == 0) - skill_db[i].skill_type=BF_MAGIC; - else if(strcmpi(split[12],"misc") == 0) - skill_db[i].skill_type=BF_MISC; - else - skill_db[i].skill_type=0; - skill_split_atoi(split[13],skill_db[i].blewcount); - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_db.txt"); - ShowStatus(tmp_output); - - fp=fopen("db/skill_require_db.txt","r"); - if(fp==NULL){ - printf("can't read db/skill_require_db.txt\n"); - return 1; - } - while(fgets(line,1020,fp)){ - char *split[50]; - if(line[0]=='/' && line[1]=='/') - continue; - j = skill_split_str(line,split,30); - if(split[29]==NULL || j<30) - continue; - - i=atoi(split[0]); - if (i>=10000 && i<10015) // for guild skills [Celest] - i -= 9500; - else if(i<=0 || i>MAX_SKILL_DB) - continue; - - skill_split_atoi(split[1],skill_db[i].hp); - skill_split_atoi(split[2],skill_db[i].mhp); - skill_split_atoi(split[3],skill_db[i].sp); - skill_split_atoi(split[4],skill_db[i].hp_rate); - skill_split_atoi(split[5],skill_db[i].sp_rate); - skill_split_atoi(split[6],skill_db[i].zeny); - - p = split[7]; - for(j=0;j<32;j++){ - l = atoi(p); - if (l==99) { - skill_db[i].weapon = 0xffffffff; - break; - } - else - skill_db[i].weapon |= 1<<l; - p=strchr(p,':'); - if(!p) - break; - p++; - } - - if( strcmpi(split[8],"hiding")==0 ) skill_db[i].state=ST_HIDING; - else if( strcmpi(split[8],"cloaking")==0 ) skill_db[i].state=ST_CLOAKING; - else if( strcmpi(split[8],"hidden")==0 ) skill_db[i].state=ST_HIDDEN; - else if( strcmpi(split[8],"riding")==0 ) skill_db[i].state=ST_RIDING; - else if( strcmpi(split[8],"falcon")==0 ) skill_db[i].state=ST_FALCON; - else if( strcmpi(split[8],"cart")==0 ) skill_db[i].state=ST_CART; - else if( strcmpi(split[8],"shield")==0 ) skill_db[i].state=ST_SHIELD; - else if( strcmpi(split[8],"sight")==0 ) skill_db[i].state=ST_SIGHT; - else if( strcmpi(split[8],"explosionspirits")==0 ) skill_db[i].state=ST_EXPLOSIONSPIRITS; - else if( strcmpi(split[8],"recover_weight_rate")==0 ) skill_db[i].state=ST_RECOV_WEIGHT_RATE; - else if( strcmpi(split[8],"move_enable")==0 ) skill_db[i].state=ST_MOVE_ENABLE; - else if( strcmpi(split[8],"water")==0 ) skill_db[i].state=ST_WATER; - else skill_db[i].state=ST_NONE; - - skill_split_atoi(split[9],skill_db[i].spiritball); - skill_db[i].itemid[0]=atoi(split[10]); - skill_db[i].amount[0]=atoi(split[11]); - skill_db[i].itemid[1]=atoi(split[12]); - skill_db[i].amount[1]=atoi(split[13]); - skill_db[i].itemid[2]=atoi(split[14]); - skill_db[i].amount[2]=atoi(split[15]); - skill_db[i].itemid[3]=atoi(split[16]); - skill_db[i].amount[3]=atoi(split[17]); - skill_db[i].itemid[4]=atoi(split[18]); - skill_db[i].amount[4]=atoi(split[19]); - skill_db[i].itemid[5]=atoi(split[20]); - skill_db[i].amount[5]=atoi(split[21]); - skill_db[i].itemid[6]=atoi(split[22]); - skill_db[i].amount[6]=atoi(split[23]); - skill_db[i].itemid[7]=atoi(split[24]); - skill_db[i].amount[7]=atoi(split[25]); - skill_db[i].itemid[8]=atoi(split[26]); - skill_db[i].amount[8]=atoi(split[27]); - skill_db[i].itemid[9]=atoi(split[28]); - skill_db[i].amount[9]=atoi(split[29]); - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_require_db.txt"); - ShowStatus(tmp_output); - - /* キャスティングデ?タベ?ス */ - fp=fopen("db/skill_cast_db.txt","r"); - if(fp==NULL){ - printf("can't read db/skill_cast_db.txt\n"); - return 1; - } - while(fgets(line,1020,fp)){ - char *split[50]; - memset(split,0,sizeof(split)); // [Valaris] thanks to fov - if(line[0]=='/' && line[1]=='/') - continue; - j = skill_split_str(line,split,5); - if(split[4]==NULL || j<5) - continue; - - i=atoi(split[0]); - if (i>=10000 && i<10015) // for guild skills [Celest] - i -= 9500; - else if(i<=0 || i>MAX_SKILL_DB) - continue; - - skill_split_atoi(split[1],skill_db[i].cast); - skill_split_atoi(split[2],skill_db[i].delay); - skill_split_atoi(split[3],skill_db[i].upkeep_time); - skill_split_atoi(split[4],skill_db[i].upkeep_time2); - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_cast_db.txt"); - ShowStatus(tmp_output); - - /* スキルユニットデータベース */ - fp = fopen("db/skill_unit_db.txt","r"); - if (fp==NULL) { - printf("can't read db/skill_unit_db.txt\n"); - return 1; - } - k = 0; - while (fgets(line,1020,fp)) { - char *split[50]; - if (line[0]=='/' && line[1]=='/') - continue; - j = skill_split_str(line,split,8); - if (split[7]==NULL || j<8) - continue; - - i=atoi(split[0]); - if (i>=10000 && i<10015) // for guild skills [Celest] - i -= 9500; - else if(i<=0 || i>MAX_SKILL_DB) - continue; - skill_db[i].unit_id[0] = strtol(split[1],NULL,16); - skill_db[i].unit_id[1] = strtol(split[2],NULL,16); - skill_split_atoi(split[3],skill_db[i].unit_layout_type); - skill_db[i].unit_range = atoi(split[4]); - skill_db[i].unit_interval = atoi(split[5]); - - if( strcmpi(split[6],"noenemy")==0 ) skill_db[i].unit_target=BCT_NOENEMY; - else if( strcmpi(split[6],"friend")==0 ) skill_db[i].unit_target=BCT_NOENEMY; - else if( strcmpi(split[6],"party")==0 ) skill_db[i].unit_target=BCT_PARTY; - else if( strcmpi(split[6],"all")==0 ) skill_db[i].unit_target=BCT_ALL; - else if( strcmpi(split[6],"enemy")==0 ) skill_db[i].unit_target=BCT_ENEMY; - else if( strcmpi(split[6],"self")==0 ) skill_db[i].unit_target=BCT_SELF; - else skill_db[i].unit_target = strtol(split[6],NULL,16); - - skill_db[i].unit_flag = strtol(split[7],NULL,16); - k++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_unit_db.txt"); - ShowStatus(tmp_output); - skill_init_unit_layout(); - - /* 製造系スキルデ?タベ?ス */ - memset(skill_produce_db,0,sizeof(skill_produce_db)); - for(m=0;m<2;m++){ - fp=fopen(filename[m],"r"); - if(fp==NULL){ - if(m>0) - continue; - printf("can't read %s\n",filename[m]); - return 1; - } - k=0; - while(fgets(line,1020,fp)){ - char *split[6 + MAX_PRODUCE_RESOURCE * 2]; - int x,y; - if(line[0]=='/' && line[1]=='/') - continue; - memset(split,0,sizeof(split)); - j = skill_split_str(line,split,(3 + MAX_PRODUCE_RESOURCE * 2)); - if(split[0]==0) //fixed by Lupus - continue; - i=atoi(split[0]); - if(i<=0) continue; - - skill_produce_db[k].nameid=i; - skill_produce_db[k].itemlv=atoi(split[1]); - skill_produce_db[k].req_skill=atoi(split[2]); - - for(x=3,y=0; split[x] && split[x+1] && y<MAX_PRODUCE_RESOURCE; x+=2,y++){ - skill_produce_db[k].mat_id[y]=atoi(split[x]); - skill_produce_db[k].mat_amount[y]=atoi(split[x+1]); - } - k++; - if(k >= MAX_SKILL_PRODUCE_DB) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",k,filename[m]); - ShowStatus(tmp_output); - } - - memset(skill_arrow_db,0,sizeof(skill_arrow_db)); - fp=fopen("db/create_arrow_db.txt","r"); - if(fp==NULL){ - printf("can't read db/create_arrow_db.txt\n"); - return 1; - } - k=0; - while(fgets(line,1020,fp)){ - char *split[16]; - int x,y; - if(line[0]=='/' && line[1]=='/') - continue; - memset(split,0,sizeof(split)); - j = skill_split_str(line,split,13); - if(split[0]==0) //fixed by Lupus - continue; - i=atoi(split[0]); - if(i<=0) - continue; - - skill_arrow_db[k].nameid=i; - - for(x=1,y=0;split[x] && split[x+1] && y<5;x+=2,y++){ - skill_arrow_db[k].cre_id[y]=atoi(split[x]); - skill_arrow_db[k].cre_amount[y]=atoi(split[x+1]); - } - k++; - if(k >= MAX_SKILL_ARROW_DB) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",k,"db/create_arrow_db.txt"); - ShowStatus(tmp_output); - - memset(skill_abra_db,0,sizeof(skill_abra_db)); - fp=fopen("db/abra_db.txt","r"); - if(fp==NULL){ - printf("can't read db/abra_db.txt\n"); - return 1; - } - k=0; - while(fgets(line,1020,fp)){ - char *split[16]; - if(line[0]=='/' && line[1]=='/') - continue; - memset(split,0,sizeof(split)); - j = skill_split_str(line,split,13); - if(split[0]==0) //fixed by Lupus - continue; - i=atoi(split[0]); - if(i<=0) - continue; - - skill_abra_db[i].req_lv=atoi(split[2]); - skill_abra_db[i].per=atoi(split[3]); - - k++; - if(k >= MAX_SKILL_ABRA_DB) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",k,"db/abra_db.txt"); - ShowStatus(tmp_output); - - fp=fopen("db/skill_castnodex_db.txt","r"); - if(fp==NULL){ - printf("can't read db/skill_castnodex_db.txt\n"); - return 1; - } - while(fgets(line,1020,fp)){ - char *split[50]; - if(line[0]=='/' && line[1]=='/') - continue; - memset(split,0,sizeof(split)); - j = skill_split_str(line,split,3); - if(split[0]==0) //fixed by Lupus - continue; - i=atoi(split[0]); - if (i>=10000 && i<10015) // for guild skills [Celest] - i -= 9500; - else if(i<=0 || i>MAX_SKILL_DB) - continue; - - skill_split_atoi(split[1],skill_db[i].castnodex); - if (!split[2]) - continue; - skill_split_atoi(split[2],skill_db[i].delaynodex); - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_castnodex_db.txt"); - ShowStatus(tmp_output); - - fp=fopen("db/skill_nocast_db.txt","r"); - if(fp==NULL){ - printf("can't read db/skill_nocast_db.txt\n"); - return 1; - } - k=0; - while(fgets(line,1020,fp)){ - char *split[16]; - if(line[0]=='/' && line[1]=='/') - continue; - memset(split,0,sizeof(split)); - j = skill_split_str(line,split,2); - if(split[0]==0) //fixed by Lupus - continue; - i=atoi(split[0]); - if (i>=10000 && i<10015) // for guild skills [Celest] - i -= 9500; - else if(i<=0 || i>MAX_SKILL_DB) - continue; - skill_db[i].nocast=atoi(split[1]); - k++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_nocast_db"); - ShowStatus(tmp_output); - - return 0; -} - -/*=============================================== - * For reading leveluseskillspamount.txt [Celest] - *----------------------------------------------- - */ -static int skill_read_skillspamount(void) -{ - char *buf,*p; - struct skill_db *skill = NULL; - int s, idx, new_flag=1, level=1, sp=0; - - buf=(char *) grfio_reads("data\\leveluseskillspamount.txt",&s); - - if(buf==NULL) - return -1; - - buf[s]=0; - for(p=buf;p-buf<s;){ - char buf2[64]; - - if (sscanf(p,"%[@]",buf2) == 1) { - level = 1; - new_flag = 1; - } else if (new_flag && sscanf(p,"%[^#]#",buf2) == 1) { - for (idx=0; skill_names[idx].id != 0; idx++) { - if (strstr(buf2, skill_names[idx].name) != NULL) { - skill = &skill_db[ skill_names[idx].id ]; - new_flag = 0; - break; - } - } - } else if (!new_flag && sscanf(p,"%d#",&sp) == 1) { - skill->sp[level-1]=sp; - level++; - } - - p=strchr(p,10); - if(!p) break; - p++; - } - aFree(buf); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\leveluseskillspamount.txt"); - ShowStatus(tmp_output); - - return 0; -} - -void skill_reload(void) -{ - skill_readdb(); - if (battle_config.skill_sp_override_grffile) - skill_read_skillspamount(); -} - -/*========================================== - * スキル?係初期化?理 - *------------------------------------------ - */ -int do_init_skill(void) -{ - skill_readdb(); - if (battle_config.skill_sp_override_grffile) - skill_read_skillspamount(); - - add_timer_func_list(skill_unit_timer,"skill_unit_timer"); - add_timer_func_list(skill_castend_id,"skill_castend_id"); - add_timer_func_list(skill_castend_pos,"skill_castend_pos"); - add_timer_func_list(skill_timerskill,"skill_timerskill"); - add_timer_interval(gettick()+SKILLUNITTIMER_INVERVAL,skill_unit_timer,0,0,SKILLUNITTIMER_INVERVAL); - - return 0; -} diff --git a/src/map/skill.h b/src/map/skill.h deleted file mode 100644 index 67d7a906c..000000000 --- a/src/map/skill.h +++ /dev/null @@ -1,731 +0,0 @@ -// $Id: skill.h,v 1.5 2004/12/23 7:43:16 PM Celestia $ -#ifndef _SKILL_H_ -#define _SKILL_H_ - -#include "map.h" - -#define MAX_SKILL_DB 750 -#define MAX_SKILL_PRODUCE_DB 150 -#define MAX_PRODUCE_RESOURCE 7 -#define MAX_SKILL_ARROW_DB 150 -#define MAX_SKILL_ABRA_DB 350 - -// スキルデ?タベ?ス -struct skill_db { - int range[MAX_SKILL_LEVEL],hit,inf,pl,nk,max; - int num[MAX_SKILL_LEVEL]; - int cast[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL]; - int upkeep_time[MAX_SKILL_LEVEL],upkeep_time2[MAX_SKILL_LEVEL]; - int castcancel,cast_def_rate; - int inf2,maxcount,skill_type; - int blewcount[MAX_SKILL_LEVEL]; - int hp[MAX_SKILL_LEVEL],sp[MAX_SKILL_LEVEL],mhp[MAX_SKILL_LEVEL],hp_rate[MAX_SKILL_LEVEL],sp_rate[MAX_SKILL_LEVEL],zeny[MAX_SKILL_LEVEL]; - int weapon,state,spiritball[MAX_SKILL_LEVEL]; - int itemid[10],amount[10]; - int castnodex[MAX_SKILL_LEVEL]; - int delaynodex[MAX_SKILL_LEVEL]; - int nocast; - int unit_id[2]; - int unit_layout_type[MAX_SKILL_LEVEL]; - int unit_range; - int unit_interval; - int unit_target; - int unit_flag; -}; -extern struct skill_db skill_db[MAX_SKILL_DB]; - -struct skill_name_db { - int id; // skill id - char *name; // search strings - char *desc; // description that shows up for search's -}; -extern const struct skill_name_db skill_names[]; - -#define MAX_SKILL_UNIT_LAYOUT 50 -#define MAX_SQUARE_LAYOUT 5 // 11*11のユニット配置が最大 -#define MAX_SKILL_UNIT_COUNT ((MAX_SQUARE_LAYOUT*2+1)*(MAX_SQUARE_LAYOUT*2+1)) -struct skill_unit_layout { - int count; - int dx[MAX_SKILL_UNIT_COUNT]; - int dy[MAX_SKILL_UNIT_COUNT]; -}; - -enum { - UF_DEFNOTENEMY = 0x0001, // defnotenemy 設定でBCT_NOENEMYに切り替え - UF_NOREITERATION = 0x0002, // 重複置き禁止 - UF_NOFOOTSET = 0x0004, // 足元置き禁止 - UF_NOOVERLAP = 0x0008, // ユニット効果が重複しない - UF_DANCE = 0x0100, // ダンススキル - UF_ENSEMBLE = 0x0200, // 合奏スキル -}; - -// アイテム作成デ?タベ?ス -struct skill_produce_db { - int nameid, trigger; - int req_skill,itemlv; - int mat_id[MAX_PRODUCE_RESOURCE],mat_amount[MAX_PRODUCE_RESOURCE]; -}; -extern struct skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB]; - -// 矢作成デ?タベ?ス -struct skill_arrow_db { - int nameid, trigger; - int cre_id[5],cre_amount[5]; -}; -extern struct skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB]; - -// アブラカダブラデ?タベ?ス -struct skill_abra_db { - int nameid; - int req_lv; - int per; -}; -extern struct skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB]; - -extern int enchant_eff[5]; -extern int deluge_eff[5]; - -struct block_list; -struct map_session_data; -struct skill_unit; -struct skill_unit_group; - -int do_init_skill(void); - -// スキルデ?タベ?スへのアクセサ -int skill_get_hit( int id ); -int skill_get_inf( int id ); -int skill_get_pl( int id ); -int skill_get_nk( int id ); -int skill_get_max( int id ); -int skill_get_range( int id , int lv ); -int skill_get_hp( int id ,int lv ); -int skill_get_mhp( int id ,int lv ); -int skill_get_sp( int id ,int lv ); -int skill_get_zeny( int id ,int lv ); -int skill_get_num( int id ,int lv ); -int skill_get_cast( int id ,int lv ); -int skill_get_delay( int id ,int lv ); -int skill_get_time( int id ,int lv ); -int skill_get_time2( int id ,int lv ); -int skill_get_castdef( int id ); -int skill_get_weapontype( int id ); -int skill_get_unit_id(int id,int flag); -int skill_get_inf2( int id ); -int skill_get_maxcount( int id ); -int skill_get_blewcount( int id ,int lv ); -int skill_get_unit_flag( int id ); -int skill_tree_get_max( int id, int b_class ); // Celest - -// スキルの使用 -int skill_use_id( struct map_session_data *sd, int target_id, - int skill_num,int skill_lv); -int skill_use_pos( struct map_session_data *sd, - int skill_x, int skill_y, int skill_num, int skill_lv); - -int skill_castend_map( struct map_session_data *sd,int skill_num, const char *map); - -int skill_cleartimerskill(struct block_list *src); -int skill_addtimerskill(struct block_list *src,unsigned int tick,int target,int x,int y,int skill_id,int skill_lv,int type,int flag); - -// 追加?果 -int skill_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick); - -// ユニットスキル -struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,int flag); -struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,int y); -int skill_delunit(struct skill_unit *unit); -struct skill_unit_group *skill_initunitgroup(struct block_list *src, - int count,int skillid,int skilllv,int unit_id); -int skill_delunitgroup(struct skill_unit_group *group); -int skill_clear_unitgroup(struct block_list *src); - -int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl, - int damage,unsigned int tick); - -int skill_castfix( struct block_list *bl, int time ); -int skill_delayfix( struct block_list *bl, int time ); -int skill_check_unit_range(int m,int x,int y,int skillid, int skilllv); -int skill_check_unit_range2(struct block_list *bl,int m,int x,int y,int skillid, int skilllv); -// -- moonsoul (added skill_check_unit_cell) -int skill_check_unit_cell(int skillid,int m,int x,int y,int unit_id); -int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range); -int skill_unit_move(struct block_list *bl,unsigned int tick,int flag); -int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy); - -struct skill_unit_group *skill_check_dancing( struct block_list *src ); -void skill_stop_dancing(struct block_list *src, int flag); - -// Guild skills [celest] -int skill_guildaura_sub (struct block_list *bl,va_list ap); - -// 詠唱キャンセル -int skill_castcancel(struct block_list *bl,int type); - -int skill_gangsterparadise(struct map_session_data *sd ,int type); -int skill_check_moonlit (struct block_list *bl, int dx, int dy); -void skill_brandishspear_first(struct square *tc,int dir,int x,int y); -void skill_brandishspear_dir(struct square *tc,int dir,int are); -int skill_autospell(struct map_session_data *md,int skillid); -void skill_devotion(struct map_session_data *md,int target); -void skill_devotion2(struct block_list *bl,int crusader); -int skill_devotion3(struct block_list *bl,int target); -void skill_devotion_end(struct map_session_data *md,struct map_session_data *sd,int target); - -#define skill_calc_heal(bl,skill_lv) (( status_get_lv(bl)+status_get_int(bl) )/8 *(4+ skill_lv*8)) - -// その他 -int skill_check_cloaking(struct block_list *bl); - -// ステ?タス異常 -int skill_enchant_elemental_end(struct block_list *bl, int type); -int skillnotok(int skillid, struct map_session_data *sd); - -// アイテム作成 -int skill_can_produce_mix( struct map_session_data *sd, int nameid, int trigger ); -int skill_produce_mix( struct map_session_data *sd, - int nameid, int slot1, int slot2, int slot3 ); - -int skill_arrow_create( struct map_session_data *sd,int nameid); - -// mobスキルのため -int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); -int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); -int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skilllv,unsigned int tick,int flag); - -// スキル攻?一括?理 -int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc, - struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); - -void skill_reload(void); - -enum { - ST_NONE,ST_HIDING,ST_CLOAKING,ST_HIDDEN,ST_RIDING,ST_FALCON,ST_CART,ST_SHIELD,ST_SIGHT,ST_EXPLOSIONSPIRITS, - ST_RECOV_WEIGHT_RATE,ST_MOVE_ENABLE,ST_WATER, -}; - -enum { - NV_BASIC = 1, - - SM_SWORD, - SM_TWOHAND, - SM_RECOVERY, - SM_BASH, - SM_PROVOKE, - SM_MAGNUM, - SM_ENDURE, - - MG_SRECOVERY, - MG_SIGHT, - MG_NAPALMBEAT, - MG_SAFETYWALL, - MG_SOULSTRIKE, - MG_COLDBOLT, - MG_FROSTDIVER, - MG_STONECURSE, - MG_FIREBALL, - MG_FIREWALL, - MG_FIREBOLT, - MG_LIGHTNINGBOLT, - MG_THUNDERSTORM, - - AL_DP, - AL_DEMONBANE, - AL_RUWACH, - AL_PNEUMA, - AL_TELEPORT, - AL_WARP, - AL_HEAL, - AL_INCAGI, - AL_DECAGI, - AL_HOLYWATER, - AL_CRUCIS, - AL_ANGELUS, - AL_BLESSING, - AL_CURE, - - MC_INCCARRY, - MC_DISCOUNT, - MC_OVERCHARGE, - MC_PUSHCART, - MC_IDENTIFY, - MC_VENDING, - MC_MAMMONITE, - - AC_OWL, - AC_VULTURE, - AC_CONCENTRATION, - AC_DOUBLE, - AC_SHOWER, - - TF_DOUBLE, - TF_MISS, - TF_STEAL, - TF_HIDING, - TF_POISON, - TF_DETOXIFY, - - ALL_RESURRECTION, - - KN_SPEARMASTERY, - KN_PIERCE, - KN_BRANDISHSPEAR, - KN_SPEARSTAB, - KN_SPEARBOOMERANG, - KN_TWOHANDQUICKEN, - KN_AUTOCOUNTER, - KN_BOWLINGBASH, - KN_RIDING, - KN_CAVALIERMASTERY, - - PR_MACEMASTERY, - PR_IMPOSITIO, - PR_SUFFRAGIUM, - PR_ASPERSIO, - PR_BENEDICTIO, - PR_SANCTUARY, - PR_SLOWPOISON, - PR_STRECOVERY, - PR_KYRIE, - PR_MAGNIFICAT, - PR_GLORIA, - PR_LEXDIVINA, - PR_TURNUNDEAD, - PR_LEXAETERNA, - PR_MAGNUS, - - WZ_FIREPILLAR, - WZ_SIGHTRASHER, - WZ_FIREIVY, - WZ_METEOR, - WZ_JUPITEL, - WZ_VERMILION, - WZ_WATERBALL, - WZ_ICEWALL, - WZ_FROSTNOVA, - WZ_STORMGUST, - WZ_EARTHSPIKE, - WZ_HEAVENDRIVE, - WZ_QUAGMIRE, - WZ_ESTIMATION, - - BS_IRON, - BS_STEEL, - BS_ENCHANTEDSTONE, - BS_ORIDEOCON, - BS_DAGGER, - BS_SWORD, - BS_TWOHANDSWORD, - BS_AXE, - BS_MACE, - BS_KNUCKLE, - BS_SPEAR, - BS_HILTBINDING, - BS_FINDINGORE, - BS_WEAPONRESEARCH, - BS_REPAIRWEAPON, - BS_SKINTEMPER, - BS_HAMMERFALL, - BS_ADRENALINE, - BS_WEAPONPERFECT, - BS_OVERTHRUST, - BS_MAXIMIZE, - - HT_SKIDTRAP, - HT_LANDMINE, - HT_ANKLESNARE, - HT_SHOCKWAVE, - HT_SANDMAN, - HT_FLASHER, - HT_FREEZINGTRAP, - HT_BLASTMINE, - HT_CLAYMORETRAP, - HT_REMOVETRAP, - HT_TALKIEBOX, - HT_BEASTBANE, - HT_FALCON, - HT_STEELCROW, - HT_BLITZBEAT, - HT_DETECTING, - HT_SPRINGTRAP, - - AS_RIGHT, - AS_LEFT, - AS_KATAR, - AS_CLOAKING, - AS_SONICBLOW, - AS_GRIMTOOTH, - AS_ENCHANTPOISON, - AS_POISONREACT, - AS_VENOMDUST, - AS_SPLASHER, - - NV_FIRSTAID, - NV_TRICKDEAD, - SM_MOVINGRECOVERY, - SM_FATALBLOW, - SM_AUTOBERSERK, - AC_MAKINGARROW, - AC_CHARGEARROW, - TF_SPRINKLESAND, - TF_BACKSLIDING, - TF_PICKSTONE, - TF_THROWSTONE, - MC_CARTREVOLUTION, - MC_CHANGECART, - MC_LOUD, - AL_HOLYLIGHT, - MG_ENERGYCOAT, - - NPC_PIERCINGATT, - NPC_MENTALBREAKER, - NPC_RANGEATTACK, - NPC_ATTRICHANGE, - NPC_CHANGEWATER, - NPC_CHANGEGROUND, - NPC_CHANGEFIRE, - NPC_CHANGEWIND, - NPC_CHANGEPOISON, - NPC_CHANGEHOLY, - NPC_CHANGEDARKNESS, - NPC_CHANGETELEKINESIS, - NPC_CRITICALSLASH, - NPC_COMBOATTACK, - NPC_GUIDEDATTACK, - NPC_SELFDESTRUCTION, - NPC_SPLASHATTACK, - NPC_SUICIDE, - NPC_POISON, - NPC_BLINDATTACK, - NPC_SILENCEATTACK, - NPC_STUNATTACK, - NPC_PETRIFYATTACK, - NPC_CURSEATTACK, - NPC_SLEEPATTACK, - NPC_RANDOMATTACK, - NPC_WATERATTACK, - NPC_GROUNDATTACK, - NPC_FIREATTACK, - NPC_WINDATTACK, - NPC_POISONATTACK, - NPC_HOLYATTACK, - NPC_DARKNESSATTACK, - NPC_TELEKINESISATTACK, - NPC_MAGICALATTACK, - NPC_METAMORPHOSIS, - NPC_PROVOCATION, - NPC_SMOKING, - NPC_SUMMONSLAVE, - NPC_EMOTION, - NPC_TRANSFORMATION, - NPC_BLOODDRAIN, - NPC_ENERGYDRAIN, - NPC_KEEPING, - NPC_DARKBREATH, - NPC_DARKBLESSING, - NPC_BARRIER, - NPC_DEFENDER, - NPC_LICK, - NPC_HALLUCINATION, - NPC_REBIRTH, - NPC_SUMMONMONSTER, - - RG_SNATCHER, - RG_STEALCOIN, - RG_BACKSTAP, - RG_TUNNELDRIVE, - RG_RAID, - RG_STRIPWEAPON, - RG_STRIPSHIELD, - RG_STRIPARMOR, - RG_STRIPHELM, - RG_INTIMIDATE, - RG_GRAFFITI, - RG_FLAGGRAFFITI, - RG_CLEANER, - RG_GANGSTER, - RG_COMPULSION, - RG_PLAGIARISM, - - AM_AXEMASTERY, - AM_LEARNINGPOTION, - AM_PHARMACY, - AM_DEMONSTRATION, - AM_ACIDTERROR, - AM_POTIONPITCHER, - AM_CANNIBALIZE, - AM_SPHEREMINE, - AM_CP_WEAPON, - AM_CP_SHIELD, - AM_CP_ARMOR, - AM_CP_HELM, - AM_BIOETHICS, - AM_BIOTECHNOLOGY, - AM_CREATECREATURE, - AM_CULTIVATION, - AM_FLAMECONTROL, - AM_CALLHOMUN, - AM_REST, - AM_DRILLMASTER, - AM_HEALHOMUN, - AM_RESURRECTHOMUN, - - CR_TRUST, - CR_AUTOGUARD, - CR_SHIELDCHARGE, - CR_SHIELDBOOMERANG, - CR_REFLECTSHIELD, - CR_HOLYCROSS, - CR_GRANDCROSS, - CR_DEVOTION, - CR_PROVIDENCE, - CR_DEFENDER, - CR_SPEARQUICKEN, - - MO_IRONHAND, - MO_SPIRITSRECOVERY, - MO_CALLSPIRITS, - MO_ABSORBSPIRITS, - MO_TRIPLEATTACK, - MO_BODYRELOCATION, - MO_DODGE, - MO_INVESTIGATE, - MO_FINGEROFFENSIVE, - MO_STEELBODY, - MO_BLADESTOP, - MO_EXPLOSIONSPIRITS, - MO_EXTREMITYFIST, - MO_CHAINCOMBO, - MO_COMBOFINISH, - - SA_ADVANCEDBOOK, - SA_CASTCANCEL, - SA_MAGICROD, - SA_SPELLBREAKER, - SA_FREECAST, - SA_AUTOSPELL, - SA_FLAMELAUNCHER, - SA_FROSTWEAPON, - SA_LIGHTNINGLOADER, - SA_SEISMICWEAPON, - SA_DRAGONOLOGY, - SA_VOLCANO, - SA_DELUGE, - SA_VIOLENTGALE, - SA_LANDPROTECTOR, - SA_DISPELL, - SA_ABRACADABRA, - SA_MONOCELL, - SA_CLASSCHANGE, - SA_SUMMONMONSTER, - SA_REVERSEORCISH, - SA_DEATH, - SA_FORTUNE, - SA_TAMINGMONSTER, - SA_QUESTION, - SA_GRAVITY, - SA_LEVELUP, - SA_INSTANTDEATH, - SA_FULLRECOVERY, - SA_COMA, - - BD_ADAPTATION, - BD_ENCORE, - BD_LULLABY, - BD_RICHMANKIM, - BD_ETERNALCHAOS, - BD_DRUMBATTLEFIELD, - BD_RINGNIBELUNGEN, - BD_ROKISWEIL, - BD_INTOABYSS, - BD_SIEGFRIED, - BD_RAGNAROK, - - BA_MUSICALLESSON, - BA_MUSICALSTRIKE, - BA_DISSONANCE, - BA_FROSTJOKE, - BA_WHISTLE, - BA_ASSASSINCROSS, - BA_POEMBRAGI, - BA_APPLEIDUN, - - DC_DANCINGLESSON, - DC_THROWARROW, - DC_UGLYDANCE, - DC_SCREAM, - DC_HUMMING, - DC_DONTFORGETME, - DC_FORTUNEKISS, - DC_SERVICEFORYOU, - - WE_MALE = 334, - WE_FEMALE, - WE_CALLPARTNER, - - NPC_SELFDESTRUCTION2 = 331, - ITM_TOMAHAWK = 337, - NPC_DARKCROSS = 338, - NPC_DARKGRANDCROSS, - NPC_DARKSOULSTRIKE, - NPC_DARKJUPITEL, - // temporary names for mob skills [Celest] - NPC_BIND, - NPC_BREAKWEAPON, - NPC_BREAKARMOR, - NPC_BREAKHELM, - NPC_BREAKSHIELD, - NPC_UNDEADATTACK, - - NPC_RUNAWAY = 348, - NPC_EXPLOSIONSPIRITS, - NPC_INCAGI, - - NPC_RECALL = 354, - - LK_AURABLADE = 355, - LK_PARRYING, - LK_CONCENTRATION, - LK_TENSIONRELAX, - LK_BERSERK, - LK_FURY, - HP_ASSUMPTIO, - HP_BASILICA, - HP_MEDITATIO, - HW_SOULDRAIN, - HW_MAGICCRASHER, - HW_MAGICPOWER, - PA_PRESSURE, - PA_SACRIFICE, - PA_GOSPEL, - CH_PALMSTRIKE, - CH_TIGERFIST, - CH_CHAINCRUSH, - PF_HPCONVERSION, - PF_SOULCHANGE, - PF_SOULBURN, - ASC_KATAR, - ASC_HALLUCINATION, - ASC_EDP, - ASC_BREAKER, - SN_SIGHT, - SN_FALCONASSAULT, - SN_SHARPSHOOTING, - SN_WINDWALK, - WS_MELTDOWN, - WS_CREATECOIN, - WS_CREATENUGGET, - WS_CARTBOOST, - WS_SYSTEMCREATE, - ST_CHASEWALK, - ST_REJECTSWORD, - ST_STEALBACKPACK, - CR_ALCHEMY, - CR_SYNTHESISPOTION, - CG_ARROWVULCAN, - CG_MOONLIT, - CG_MARIONETTE, - LK_SPIRALPIERCE, - LK_HEADCRUSH, - LK_JOINTBEAT, - HW_NAPALMVULCAN, - CH_SOULCOLLECT, - PF_MINDBREAKER, - PF_MEMORIZE, - PF_FOGWALL, - PF_SPIDERWEB, - ASC_METEORASSAULT, - ASC_CDP, - WE_BABY, - WE_CALLPARENT, - WE_CALLBABY, - - TK_RUN = 411, - TK_READYSTORM, - TK_STORMKICK, - TK_READYDOWN, - TK_DOWNKICK, - TK_READYTURN, - TK_TURNKICK, - TK_READYCOUNTER, - TK_COUNTER, - TK_DODGE, - TK_JUMPKICK, - TK_HPTIME, - TK_SPTIME, - TK_POWER, - TK_SEVENWIND, - TK_HIGHJUMP, - SG_FEEL, - SG_SUN_WARM, - SG_MOON_WARM, - SG_STAR_WARM, - SG_SUN_COMFORT, - SG_MOON_COMFORT, - SG_STAR_COMFORT, - SG_HATE, - SG_SUN_ANGER, - SG_MOON_ANGER, - SG_STAR_ANGER, - SG_SUN_BLESS, - SG_MOON_BLESS, - SG_STAR_BLESS, - SG_DEVIL, - SG_FRIEND, - SG_KNOWLEDGE, - SG_FUSION, - SL_ALCHEMIST, - AM_BERSERKPITCHER, - SL_MONK, - SL_STAR, - SL_SAGE, - SL_CRUSADER, - SL_SUPERNOVICE, - SL_KNIGHT, - SL_WIZARD, - SL_PRIEST, - SL_BARDDANCER, - SL_ROGUE, - SL_ASSASIN, - SL_BLACKSMITH, - BS_ADRENALINE2, - SL_HUNTER, - SL_SOULLINKER, - SL_KAIZEL, - SL_KAAHI, - SL_KAUPE, - SL_KAITE, - SL_KAINA, - SL_STIN, - SL_STUN, - SL_SMA, - SL_SWOO, - SL_SKE, - SL_SKA, - - ST_PRESERVE = 475, - ST_FULLSTRIP, - WS_WEAPONREFINE, - CR_SLIMPITCHER, - CR_FULLPROTECTION, - - -// moved to common/mmo.h -/* GD_APPROVAL=10000, - GD_KAFRACONTACT=10001, - GD_GUARDIANRESEARCH=10002, - GD_GUARDUP=10003, - GD_EXTENSION=10004, - GD_GLORYGUILD=10005, - GD_LEADERSHIP=10006, - GD_GLORYWOUNDS=10007, - GD_SOULCOLD=10008, - GD_HAWKEYES=10009, - GD_BATTLEORDER=10010, - GD_REGENERATION=10011, - GD_RESTORE=10012, - GD_EMERGENCYCALL=10013, - GD_DEVELOPMENT=10014,*/ -}; - -#endif diff --git a/src/map/status.c b/src/map/status.c deleted file mode 100644 index a9967d956..000000000 --- a/src/map/status.c +++ /dev/null @@ -1,5159 +0,0 @@ - -// ステータス計算、状態異常処理 -#include <time.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <memory.h> - -#include "pc.h" -#include "map.h" -#include "pet.h" -#include "mob.h" -#include "clif.h" -#include "guild.h" -#include "skill.h" -#include "itemdb.h" -#include "battle.h" -#include "chrif.h" -#include "status.h" - -#include "timer.h" -#include "nullpo.h" -#include "script.h" -#include "showmsg.h" - -/* スキル番?=>ステ?タス異常番??換テ?ブル */ -int SkillStatusChangeTable[]={ /* status.hのenumのSC_***とあわせること */ -/* 0- */ - -1,-1,-1,-1,-1,-1, - SC_PROVOKE, /* プロボック */ - -1, 1,-1, -/* 10- */ - SC_SIGHT, /* サイト */ - -1, - SC_SAFETYWALL, /* セーフティーウォール */ - -1,-1,-1, - SC_FREEZE, /* フロストダイバ? */ - SC_STONE, /* スト?ンカ?ス */ - -1,-1, -/* 20- */ - -1,-1,-1,-1, - SC_RUWACH, /* ルアフ */ - SC_PNEUMA, /* ニューマ */ - -1,-1,-1, - SC_INCREASEAGI, /* 速度?加 */ -/* 30- */ - SC_DECREASEAGI, /* 速度減少 */ - -1, - SC_SIGNUMCRUCIS, /* シグナムクルシス */ - SC_ANGELUS, /* エンジェラス */ - SC_BLESSING, /* ブレッシング */ - -1,-1,-1,-1,-1, -/* 40- */ - -1,-1,-1,-1,-1, - SC_CONCENTRATE, /* 集中力向上 */ - -1,-1,-1,-1, -/* 50- */ - -1, - SC_HIDING, /* ハイディング */ - -1,-1,-1,-1,-1,-1,-1,-1, -/* 60- */ - SC_TWOHANDQUICKEN, /* 2HQ */ - SC_AUTOCOUNTER, - -1,-1,-1,-1, - SC_IMPOSITIO, /* インポシティオマヌス */ - SC_SUFFRAGIUM, /* サフラギウム */ - SC_ASPERSIO, /* アスペルシオ */ - SC_BENEDICTIO, /* 聖?降福 */ -/* 70- */ - -1, - SC_SLOWPOISON, - -1, - SC_KYRIE, /* キリエエレイソン */ - SC_MAGNIFICAT, /* マグニフィカ?ト */ - SC_GLORIA, /* グロリア */ - SC_DIVINA, /* レックスディビ?ナ */ - -1, - SC_AETERNA, /* レックスエ?テルナ */ - -1, -/* 80- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 90- */ - -1,-1, - SC_QUAGMIRE, /* クァグマイア */ - -1,-1,-1,-1,-1,-1,-1, -/* 100- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 110- */ - -1, - SC_ADRENALINE, /* アドレナリンラッシュ */ - SC_WEAPONPERFECTION,/* ウェポンパ?フェクション */ - SC_OVERTHRUST, /* オ?バ?トラスト */ - SC_MAXIMIZEPOWER, /* マキシマイズパワ? */ - -1,-1,-1,-1,-1, -/* 120- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 130- */ - -1,-1,-1,-1,-1, - SC_CLOAKING, /* クロ?キング */ - SC_STAN, /* ソニックブロ? */ - -1, - SC_ENCPOISON, /* エンチャントポイズン */ - SC_POISONREACT, /* ポイズンリアクト */ -/* 140- */ - SC_POISON, /* ベノムダスト */ - SC_SPLASHER, /* ベナムスプラッシャ? */ - -1, - SC_TRICKDEAD, /* 死んだふり */ - -1,-1,SC_AUTOBERSERK,-1,-1,-1, -/* 150- */ - -1,-1,-1,-1,-1, - SC_LOUD, /* ラウドボイス */ - -1, - SC_ENERGYCOAT, /* エナジ?コ?ト */ - -1,-1, -/* 160- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1, - SC_SELFDESTRUCTION, - -1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1, - SC_KEEPING, - -1,-1, - SC_BARRIER, - -1,-1, - SC_HALLUCINATION, - -1,-1, -/* 210- */ - -1,-1,-1,-1,-1, - SC_STRIPWEAPON, - SC_STRIPSHIELD, - SC_STRIPARMOR, - SC_STRIPHELM, - -1, -/* 220- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 230- */ - -1,-1,-1,-1, - SC_CP_WEAPON, - SC_CP_SHIELD, - SC_CP_ARMOR, - SC_CP_HELM, - -1,-1, -/* 240- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1, - SC_AUTOGUARD, -/* 250- */ - -1,-1, - SC_REFLECTSHIELD, - -1,-1, - SC_DEVOTION, - SC_PROVIDENCE, - SC_DEFENDER, - SC_SPEARSQUICKEN, - -1, -/* 260- */ - -1,-1,-1,-1,-1,-1,-1,-1, - SC_STEELBODY, - SC_BLADESTOP_WAIT, -/* 270- */ - SC_EXPLOSIONSPIRITS, - SC_EXTREMITYFIST, - -1,-1,-1,-1, - SC_MAGICROD, - -1,-1,-1, -/* 280- */ - SC_FLAMELAUNCHER, - SC_FROSTWEAPON, - SC_LIGHTNINGLOADER, - SC_SEISMICWEAPON, - -1, - SC_VOLCANO, - SC_DELUGE, - SC_VIOLENTGALE, - SC_LANDPROTECTOR, - -1, -/* 290- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 300- */ - -1,-1,-1,-1,-1,-1, - SC_LULLABY, - SC_RICHMANKIM, - SC_ETERNALCHAOS, - SC_DRUMBATTLE, -/* 310- */ - SC_NIBELUNGEN, - SC_ROKISWEIL, - SC_INTOABYSS, - SC_SIEGFRIED, - -1,-1,-1, - SC_DISSONANCE, - -1, - SC_WHISTLE, -/* 320- */ - SC_ASSNCROS, - SC_POEMBRAGI, - SC_APPLEIDUN, - -1,-1, - SC_UGLYDANCE, - -1, - SC_HUMMING, - SC_DONTFORGETME, - SC_FORTUNE, -/* 330- */ - SC_SERVICE4U, - SC_SELFDESTRUCTION, - -1,-1,-1,-1,-1,-1,-1,-1, -/* 340- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -/* 350- */ - -1,-1,-1,-1,-1, - SC_AURABLADE, - SC_PARRYING, - SC_CONCENTRATION, - SC_TENSIONRELAX, - SC_BERSERK, -/* 360- */ - SC_BERSERK, - SC_ASSUMPTIO, - SC_BASILICA, - -1,-1,-1, - SC_MAGICPOWER, - -1, - SC_SACRIFICE, - SC_GOSPEL, -/* 370- */ - -1,-1,-1,-1,-1,-1,-1,-1, - SC_EDP, - -1, -/* 380- */ - SC_TRUESIGHT, - -1,-1, - SC_WINDWALK, - SC_MELTDOWN, - -1,-1, - SC_CARTBOOST, - -1, - SC_CHASEWALK, -/* 390- */ - SC_REJECTSWORD, - -1,-1,-1,-1, - SC_MOONLIT, - SC_MARIONETTE, - -1, - SC_BLEEDING, - SC_JOINTBEAT, -/* 400 */ - -1,-1, - SC_MINDBREAKER, - SC_MEMORIZE, - SC_FOGWALL, - SC_SPIDERWEB, - -1,-1, - SC_BABY, - -1, -/* 410- */ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -}; - -static int max_weight_base[MAX_PC_CLASS]; -static int hp_coefficient[MAX_PC_CLASS]; -static int hp_coefficient2[MAX_PC_CLASS]; -static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL]; -static int sp_coefficient[MAX_PC_CLASS]; -static int aspd_base[MAX_PC_CLASS][20]; -static int refinebonus[5][3]; // 精錬ボーナステーブル(refine_db.txt) -int percentrefinery[5][10]; // 精錬成功率(refine_db.txt) -static int atkmods[3][20]; // 武器ATKサイズ修正(size_fix.txt) -static char job_bonus[3][MAX_PC_CLASS][MAX_LEVEL]; - -int current_equip_item_index; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus] -//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only -//to avoid cards exploits - -/*========================================== - * 精錬ボーナス - *------------------------------------------ - */ -int status_getrefinebonus(int lv,int type) -{ - if (lv >= 0 && lv < 5 && type >= 0 && type < 3) - return refinebonus[lv][type]; - return 0; -} - -/*========================================== - * 精錬成功率 - *------------------------------------------ - */ -int status_percentrefinery(struct map_session_data *sd,struct item *item) -{ - int percent; - - nullpo_retr(0, item); - percent=percentrefinery[itemdb_wlv(item->nameid)][(int)item->refine]; - - percent += pc_checkskill(sd,BS_WEAPONRESEARCH); // 武器研究スキル所持 - - // 確率の有効範囲チェック - if( percent > 100 ){ - percent = 100; - } - if( percent < 0 ){ - percent = 0; - } - - return percent; -} - -/*========================================== - * パラメータ計算 - * first==0の時、計算対象のパラメータが呼び出し前から - * 変 化した場合自動でsendするが、 - * 能動的に変化させたパラメータは自前でsendするように - *------------------------------------------ - */ - -int status_calc_pc(struct map_session_data* sd,int first) -{ - int b_speed,b_max_hp,b_max_sp,b_hp,b_sp,b_weight,b_max_weight,b_paramb[6],b_parame[6],b_hit,b_flee; - int b_aspd,b_watk,b_def,b_watk2,b_def2,b_flee2,b_critical,b_attackrange,b_matk1,b_matk2,b_mdef,b_mdef2,b_class; - int b_base_atk; - struct skill b_skill[MAX_SKILL]; - int i,bl,index; - int skill,aspd_rate,wele,wele_,def_ele,refinedef=0; - int pele=0,pdef_ele=0; - int str,dstr,dex; - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - //?生や養子の場合の元の職業を算出する - s_class = pc_calc_base_job(sd->status.class_); - - b_speed = sd->speed; - b_max_hp = sd->status.max_hp; - b_max_sp = sd->status.max_sp; - b_hp = sd->status.hp; - b_sp = sd->status.sp; - b_weight = sd->weight; - b_max_weight = sd->max_weight; - memcpy(b_paramb,&sd->paramb,sizeof(b_paramb)); - memcpy(b_parame,&sd->paramc,sizeof(b_parame)); - memcpy(b_skill,&sd->status.skill,sizeof(b_skill)); - b_hit = sd->hit; - b_flee = sd->flee; - b_aspd = sd->aspd; - b_watk = sd->watk; - b_def = sd->def; - b_watk2 = sd->watk2; - b_def2 = sd->def2; - b_flee2 = sd->flee2; - b_critical = sd->critical; - b_attackrange = sd->attackrange; - b_matk1 = sd->matk1; - b_matk2 = sd->matk2; - b_mdef = sd->mdef; - b_mdef2 = sd->mdef2; - b_class = sd->view_class; - sd->view_class = sd->status.class_; - b_base_atk = sd->base_atk; - - pc_calc_skilltree(sd); // スキルツリ?の計算 - - sd->max_weight = max_weight_base[s_class.job]+sd->status.str*300; - - if(first&1) { - sd->weight=0; - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL) - continue; - sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount; - } - sd->cart_max_weight=battle_config.max_cart_weight; - sd->cart_weight=0; - sd->cart_max_num=MAX_CART; - sd->cart_num=0; - for(i=0;i<MAX_CART;i++){ - if(sd->status.cart[i].nameid==0) - continue; - sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount; - sd->cart_num++; - } - } - - memset(sd->paramb,0,sizeof(sd->paramb)); - memset(sd->parame,0,sizeof(sd->parame)); - sd->hit = 0; - sd->flee = 0; - sd->flee2 = 0; - sd->critical = 0; - sd->aspd = 0; - sd->watk = 0; - sd->def = 0; - sd->mdef = 0; - sd->watk2 = 0; - sd->def2 = 0; - sd->mdef2 = 0; - sd->status.max_hp = 0; - sd->status.max_sp = 0; - sd->attackrange = 0; - sd->attackrange_ = 0; - sd->atk_ele = 0; - sd->def_ele = 0; - sd->star =0; - sd->overrefine =0; - sd->matk1 =0; - sd->matk2 =0; - sd->speed = DEFAULT_WALK_SPEED ; - sd->hprate=battle_config.hp_rate; - sd->sprate=battle_config.sp_rate; - sd->castrate=100; - sd->delayrate=100; - sd->dsprate=100; - sd->base_atk=0; - sd->arrow_atk=0; - sd->arrow_ele=0; - sd->arrow_hit=0; - sd->arrow_range=0; - sd->nhealhp=sd->nhealsp=sd->nshealhp=sd->nshealsp=sd->nsshealhp=sd->nsshealsp=0; - memset(sd->addele,0,sizeof(sd->addele)); - memset(sd->addrace,0,sizeof(sd->addrace)); - memset(sd->addsize,0,sizeof(sd->addsize)); - memset(sd->addele_,0,sizeof(sd->addele_)); - memset(sd->addrace_,0,sizeof(sd->addrace_)); - memset(sd->addsize_,0,sizeof(sd->addsize_)); - memset(sd->subele,0,sizeof(sd->subele)); - memset(sd->subrace,0,sizeof(sd->subrace)); - memset(sd->addeff,0,sizeof(sd->addeff)); - memset(sd->addeff2,0,sizeof(sd->addeff2)); - memset(sd->reseff,0,sizeof(sd->reseff)); - memset(&sd->special_state,0,sizeof(sd->special_state)); - memset(sd->weapon_coma_ele,0,sizeof(sd->weapon_coma_ele)); - memset(sd->weapon_coma_race,0,sizeof(sd->weapon_coma_race)); - memset(sd->weapon_atk,0,sizeof(sd->weapon_atk)); - memset(sd->weapon_atk_rate,0,sizeof(sd->weapon_atk_rate)); - - sd->watk_ = 0; //二刀流用(?) - sd->watk_2 = 0; - sd->atk_ele_ = 0; - sd->star_ = 0; - sd->overrefine_ = 0; - - sd->aspd_rate = 100; - sd->speed_rate = 100; - sd->hprecov_rate = 100; - sd->sprecov_rate = 100; - sd->critical_def = 0; - sd->double_rate = 0; - sd->near_attack_def_rate = sd->long_attack_def_rate = 0; - sd->atk_rate = sd->matk_rate = 100; - sd->ignore_def_ele = sd->ignore_def_race = 0; - sd->ignore_def_ele_ = sd->ignore_def_race_ = 0; - sd->ignore_mdef_ele = sd->ignore_mdef_race = 0; - sd->arrow_cri = 0; - sd->magic_def_rate = sd->misc_def_rate = 0; - memset(sd->arrow_addele,0,sizeof(sd->arrow_addele)); - memset(sd->arrow_addrace,0,sizeof(sd->arrow_addrace)); - memset(sd->arrow_addsize,0,sizeof(sd->arrow_addsize)); - memset(sd->arrow_addeff,0,sizeof(sd->arrow_addeff)); - memset(sd->arrow_addeff2,0,sizeof(sd->arrow_addeff2)); - memset(sd->magic_addele,0,sizeof(sd->magic_addele)); - memset(sd->magic_addrace,0,sizeof(sd->magic_addrace)); - memset(sd->magic_subrace,0,sizeof(sd->magic_subrace)); - sd->perfect_hit = 0; - sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100; - sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100; - sd->def_ratio_atk_ele = sd->def_ratio_atk_ele_ = 0; - sd->def_ratio_atk_race = sd->def_ratio_atk_race_ = 0; - sd->get_zeny_num = 0; - sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0; - sd->add_def_class_count = sd->add_mdef_class_count = 0; - sd->monster_drop_item_count = 0; - memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate)); - memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_)); - memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate)); - memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate)); - memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate)); - memset(sd->monster_drop_race,0,sizeof(sd->monster_drop_race)); - memset(sd->monster_drop_itemrate,0,sizeof(sd->monster_drop_itemrate)); - sd->speed_add_rate = sd->aspd_add_rate = 100; - sd->double_add_rate = sd->perfect_hit_add = sd->get_zeny_add_num = 0; - sd->splash_range = sd->splash_add_range = 0; - sd->autospell_id = sd->autospell_lv = sd->autospell_rate = 0; - sd->hp_drain_rate = sd->hp_drain_per = sd->sp_drain_rate = sd->sp_drain_per = 0; - sd->hp_drain_rate_ = sd->hp_drain_per_ = sd->sp_drain_rate_ = sd->sp_drain_per_ = 0; - sd->short_weapon_damage_return = sd->long_weapon_damage_return = 0; - sd->magic_damage_return = 0; //AppleGirl Was Here - sd->random_attack_increase_add = sd->random_attack_increase_per = 0; - sd->hp_drain_value = sd->hp_drain_value_ = sd->sp_drain_value = sd->sp_drain_value_ = 0; - sd->unbreakable_equip = 0; - - sd->break_weapon_rate = sd->break_armor_rate = 0; - sd->add_steal_rate = 0; - sd->crit_atk_rate = 0; - sd->no_regen = 0; - sd->unstripable_equip = 0; - sd->autospell2_id = sd->autospell2_lv = sd->autospell2_rate = 0; - memset(sd->critaddrace,0,sizeof(sd->critaddrace)); - memset(sd->addeff3,0,sizeof(sd->addeff3)); - memset(sd->addeff3_type,0,sizeof(sd->addeff3_type)); - memset(sd->skillatk,0,sizeof(sd->skillatk)); - sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0; - sd->add_def_class_count = sd->add_mdef_class_count = 0; - sd->add_damage_class_count2 = 0; - memset(sd->add_damage_classid,0,sizeof(sd->add_damage_classid)); - memset(sd->add_damage_classid_,0,sizeof(sd->add_damage_classid_)); - memset(sd->add_magic_damage_classid,0,sizeof(sd->add_magic_damage_classid)); - memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate)); - memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_)); - memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate)); - memset(sd->add_def_classid,0,sizeof(sd->add_def_classid)); - memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate)); - memset(sd->add_mdef_classid,0,sizeof(sd->add_mdef_classid)); - memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate)); - memset(sd->add_damage_classid2,0,sizeof(sd->add_damage_classid2)); - memset(sd->add_damage_classrate2,0,sizeof(sd->add_damage_classrate2)); - sd->sp_gain_value = 0; - sd->ignore_def_mob = sd->ignore_def_mob_ = 0; - sd->hp_loss_rate = sd->hp_loss_value = sd->hp_loss_type = 0; - memset(sd->addrace2,0,sizeof(sd->addrace2)); - memset(sd->addrace2_,0,sizeof(sd->addrace2_)); - sd->hp_gain_value = sd->sp_drain_type = 0; - memset(sd->subsize,0,sizeof(sd->subsize)); - memset(sd->unequip_losehp,0,sizeof(sd->unequip_losehp)); - memset(sd->unequip_losesp,0,sizeof(sd->unequip_losesp)); - memset(sd->subrace2,0,sizeof(sd->subrace2)); - memset(sd->expaddrace,0,sizeof(sd->expaddrace)); - memset(sd->sp_gain_race,0,sizeof(sd->sp_gain_race)); - - if(!sd->disguiseflag && sd->disguise) { - sd->disguise=0; - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); - clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); - clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); - clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); - clif_clearchar(&sd->bl, 9); - pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3); - } - - if (sd->status.guild_id > 0) { - struct guild *g = guild_search(sd->status.guild_id); - if (g && strcmp(sd->status.name,g->master)==0) - sd->state.gmaster_flag = (int)g; - } - - for(i=0;i<10;i++) { - current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] - if(index < 0) - continue; - if(i == 9 && sd->equip_index[8] == index) - continue; - if(i == 5 && sd->equip_index[4] == index) - continue; - if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) - continue; - - if(sd->inventory_data[index]) { - if(sd->inventory_data[index]->type == 4) { - if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) { - int j; - for(j=0;j<sd->inventory_data[index]->slot;j++){ // カ?ド - int c=sd->status.inventory[index].card[j]; - if(c>0){ - if(i == 8 && sd->status.inventory[index].equip == 0x20) - sd->state.lr_flag = 1; - run_script(itemdb_equipscript(c),0,sd->bl.id,0); - sd->state.lr_flag = 0; - } - } - } - } - else if(sd->inventory_data[index]->type==5){ // 防具 - if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) { - int j; - for(j=0;j<sd->inventory_data[index]->slot;j++){ // カ?ド - int c=sd->status.inventory[index].card[j]; - if(c>0) - run_script(itemdb_equipscript(c),0,sd->bl.id,0); - } - } - } - } - } - wele = sd->atk_ele; - wele_ = sd->atk_ele_; - def_ele = sd->def_ele; - if(sd->status.pet_id > 0) { - struct pet_data *pd=sd->pd; - if((pd && battle_config.pet_status_support==1) && (battle_config.pet_equip_required==0 || (battle_config.pet_equip_required && pd->equip > 0))) { - if(sd->status.pet_id > 0 && sd->petDB && sd->pet.intimate > 0 && - pd->state.skillbonus == 1) { - pc_bonus(sd,pd->skillbonustype,pd->skillbonusval); -// run_script(sd->petDB->script,0,sd->bl.id,0); - } - pele = sd->atk_ele; - pdef_ele = sd->def_ele; - sd->atk_ele = sd->def_ele = 0; - } - } - memcpy(sd->paramcard,sd->parame,sizeof(sd->paramcard)); - - // ?備品によるステ?タス?化はここで?行 - for(i=0;i<10;i++) { - current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] - if(index < 0) - continue; - if(i == 9 && sd->equip_index[8] == index) - continue; - if(i == 5 && sd->equip_index[4] == index) - continue; - if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) - continue; - if(sd->inventory_data[index]) { - sd->def += sd->inventory_data[index]->def; - if(sd->inventory_data[index]->type == 4) { - int r,wlv = sd->inventory_data[index]->wlv; - if(i == 8 && sd->status.inventory[index].equip == 0x20) { - //二刀流用デ?タ入力 - sd->watk_ += sd->inventory_data[index]->atk; - sd->watk_2 = (r=sd->status.inventory[index].refine)* // 精?攻?力 - refinebonus[wlv][0]; - if( (r-=refinebonus[wlv][2])>0 ) // 過?精?ボ?ナス - sd->overrefine_ = r*refinebonus[wlv][1]; - - if(sd->status.inventory[index].card[0]==0x00ff){ // 製造武器 - sd->star_ = (sd->status.inventory[index].card[1]>>8); // 星のかけら - wele_= (sd->status.inventory[index].card[1]&0x0f); // ? 性 - } - sd->attackrange_ += sd->inventory_data[index]->range; - sd->state.lr_flag = 1; - run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); - sd->state.lr_flag = 0; - } - else { //二刀流武器以外 - sd->watk += sd->inventory_data[index]->atk; - sd->watk2 += (r=sd->status.inventory[index].refine)* // 精?攻?力 - refinebonus[wlv][0]; - if( (r-=refinebonus[wlv][2])>0 ) // 過?精?ボ?ナス - sd->overrefine += r*refinebonus[wlv][1]; - - if(sd->status.inventory[index].card[0]==0x00ff){ // 製造武器 - sd->star += (sd->status.inventory[index].card[1]>>8); // 星のかけら - wele = (sd->status.inventory[index].card[1]&0x0f); // ? 性 - } - sd->attackrange += sd->inventory_data[index]->range; - run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); - } - } - else if(sd->inventory_data[index]->type == 5) { - sd->watk += sd->inventory_data[index]->atk; - refinedef += sd->status.inventory[index].refine*refinebonus[0][0]; - run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); - } - } - } - - if(sd->equip_index[10] >= 0){ // 矢 - index = sd->equip_index[10]; - if(sd->inventory_data[index]){ //まだ?性が入っていない - sd->state.lr_flag = 2; - run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); - sd->state.lr_flag = 0; - sd->arrow_atk += sd->inventory_data[index]->atk; - } - } - sd->def += (refinedef+50)/100; - - if(sd->attackrange < 1) sd->attackrange = 1; - if(sd->attackrange_ < 1) sd->attackrange_ = 1; - if(sd->attackrange < sd->attackrange_) - sd->attackrange = sd->attackrange_; - if(sd->status.weapon == 11) - sd->attackrange += sd->arrow_range; - if(wele > 0) - sd->atk_ele = wele; - if(wele_ > 0) - sd->atk_ele_ = wele_; - if(def_ele > 0) - sd->def_ele = def_ele; - if(battle_config.pet_status_support) { - if(pele > 0 && !sd->atk_ele) - sd->atk_ele = pele; - if(pdef_ele > 0 && !sd->def_ele) - sd->def_ele = pdef_ele; - } - sd->double_rate += sd->double_add_rate; - sd->perfect_hit += sd->perfect_hit_add; - sd->get_zeny_num += sd->get_zeny_add_num; - sd->splash_range += sd->splash_add_range; - if(sd->speed_add_rate != 100) - sd->speed_rate += sd->speed_add_rate - 100; - if(sd->aspd_add_rate != 100) - sd->aspd_rate += sd->aspd_add_rate - 100; - - // 武器ATKサイズ補正 (右手) - sd->atkmods[0] = atkmods[0][sd->weapontype1]; - sd->atkmods[1] = atkmods[1][sd->weapontype1]; - sd->atkmods[2] = atkmods[2][sd->weapontype1]; - //武器ATKサイズ補正 (左手) - sd->atkmods_[0] = atkmods[0][sd->weapontype2]; - sd->atkmods_[1] = atkmods[1][sd->weapontype2]; - sd->atkmods_[2] = atkmods[2][sd->weapontype2]; - - // jobボ?ナス分 - for(i=0;i<sd->status.job_level && i<MAX_LEVEL;i++){ - if(job_bonus[s_class.upper][s_class.job][i]) - sd->paramb[job_bonus[s_class.upper][s_class.job][i]-1]++; - } - - if( (skill=pc_checkskill(sd,MC_INCCARRY))>0 ) // skill can be used with an item now, thanks to orn [Valaris] - sd->max_weight += skill*2000; - - if( (skill=pc_checkskill(sd,AC_OWL))>0 ) // ふくろうの目 - sd->paramb[4] += skill; - - if((skill=pc_checkskill(sd,BS_HILTBINDING))>0) { // Hilt binding gives +1 str +4 atk - sd->paramb[0] ++; - sd->base_atk += 4; - } - if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // Dragonology increases +1 int every 2 levels - sd->paramb[3] += (int) ((skill+1)*0.5); - } - - // ステ?タス?化による基本パラメ?タ補正 - if(sd->sc_count){ - if(sd->sc_data[SC_CONCENTRATE].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1){ // 集中力向上 - sd->paramb[1]+= (sd->status.agi+sd->paramb[1]+sd->parame[1]-sd->paramcard[1])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100; - sd->paramb[4]+= (sd->status.dex+sd->paramb[4]+sd->parame[4]-sd->paramcard[4])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100; - } - if(sd->sc_data[SC_INCREASEAGI].timer!=-1){ // 速度?加 - sd->paramb[1]+= 2+sd->sc_data[SC_INCREASEAGI].val1; - sd->speed -= sd->speed *25/100; - } - if(sd->sc_data[SC_DECREASEAGI].timer!=-1) { // 速度減少(agiはbattle.cで) - sd->speed = sd->speed *125/100; - sd->paramb[1] -= 2 + sd->sc_data[SC_DECREASEAGI].val1; // reduce agility [celest] - } - if(sd->sc_data[SC_CLOAKING].timer!=-1) { - sd->critical_rate += 100; // critical increases - sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100; - } - if(sd->sc_data[SC_CHASEWALK].timer!=-1) { - sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100; // slow down by chasewalk - if(sd->sc_data[SC_CHASEWALK].val4) - sd->paramb[0] += (1<<(sd->sc_data[SC_CHASEWALK].val1-1)); // increases strength after 10 seconds - } - if(sd->sc_data[SC_SLOWDOWN].timer!=-1) - sd->speed = sd->speed*150/100; - if(sd->sc_data[SC_SPEEDUP0].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) - sd->speed -= sd->speed*25/100; - if(sd->sc_data[SC_BLESSING].timer!=-1){ // ブレッシング - sd->paramb[0]+= sd->sc_data[SC_BLESSING].val1; - sd->paramb[3]+= sd->sc_data[SC_BLESSING].val1; - sd->paramb[4]+= sd->sc_data[SC_BLESSING].val1; - } - if(sd->sc_data[SC_GLORIA].timer!=-1) // グロリア - sd->paramb[5]+= 30; - if(sd->sc_data[SC_LOUD].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1) // ラウドボイス - sd->paramb[0]+= 4; - if(sd->sc_data[SC_QUAGMIRE].timer!=-1){ // クァグマイア - //int agib = (sd->status.agi+sd->paramb[1]+sd->parame[1])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100; - //int dexb = (sd->status.dex+sd->paramb[4]+sd->parame[4])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100; - //sd->paramb[1]-= agib > 50 ? 50 : agib; - //sd->paramb[4]-= dexb > 50 ? 50 : dexb; - sd->paramb[1]-= sd->sc_data[SC_QUAGMIRE].val1*5; - sd->paramb[4]-= sd->sc_data[SC_QUAGMIRE].val1*5; - sd->speed = sd->speed*3/2; - } - if(sd->sc_data[SC_TRUESIGHT].timer!=-1){ // トゥル?サイト - sd->paramb[0]+= 5; - sd->paramb[1]+= 5; - sd->paramb[2]+= 5; - sd->paramb[3]+= 5; - sd->paramb[4]+= 5; - sd->paramb[5]+= 5; - } - if(sd->sc_data[SC_MARIONETTE].timer!=-1){ - // skip partner checking -- should be handled in status_change_timer - //struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3); - //if (psd) { // if partner is found - sd->paramb[0]-= sd->status.str/2; // bonuses not included - sd->paramb[1]-= sd->status.agi/2; - sd->paramb[2]-= sd->status.vit/2; - sd->paramb[3]-= sd->status.int_/2; - sd->paramb[4]-= sd->status.dex/2; - sd->paramb[5]-= sd->status.luk/2; - //} - } - else if(sd->sc_data[SC_MARIONETTE2].timer!=-1){ - struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3); - if (psd) { // if partner is found - sd->paramb[0] += sd->status.str+psd->status.str/2 > 99 ? 99-sd->status.str : psd->status.str/2; - sd->paramb[1] += sd->status.agi+psd->status.agi/2 > 99 ? 99-sd->status.agi : psd->status.agi/2; - sd->paramb[2] += sd->status.vit+psd->status.vit/2 > 99 ? 99-sd->status.vit : psd->status.vit/2; - sd->paramb[3] += sd->status.int_+psd->status.int_/2 > 99 ? 99-sd->status.int_ : psd->status.int_/2; - sd->paramb[4] += sd->status.dex+psd->status.dex/2 > 99 ? 99-sd->status.dex : psd->status.dex/2; - sd->paramb[5] += sd->status.luk+psd->status.luk/2 > 99 ? 99-sd->status.luk : psd->status.luk/2; - } - } - if(sd->sc_data[SC_GOSPEL].timer!=-1 && sd->sc_data[SC_GOSPEL].val4 == BCT_PARTY){ - if (sd->sc_data[SC_GOSPEL].val3 == 6) { - sd->paramb[0]+= 2; - sd->paramb[1]+= 2; - sd->paramb[2]+= 2; - sd->paramb[3]+= 2; - sd->paramb[4]+= 2; - sd->paramb[5]+= 2; - } - } - // New guild skills - Celest - if (sd->sc_data[SC_BATTLEORDERS].timer != -1) { - sd->paramb[0]+= 5; - sd->paramb[3]+= 5; - sd->paramb[4]+= 5; - } - if (sd->sc_data[SC_GUILDAURA].timer != -1) { - if (sd->sc_data[SC_GUILDAURA].val4 & 1<<0) - sd->paramb[0] += 2; - if (sd->sc_data[SC_GUILDAURA].val4 & 1<<1) - sd->paramb[2] += 2; - if (sd->sc_data[SC_GUILDAURA].val4 & 1<<2) - sd->paramb[1] += 2; - if (sd->sc_data[SC_GUILDAURA].val4 & 1<<3) - sd->paramb[4] += 2; - } - } - - //1度も死んでないJob70スパノビに+10 - if(s_class.job == 23 && sd->die_counter == 0 && sd->status.job_level >= 70){ - sd->paramb[0]+= 15; - sd->paramb[1]+= 15; - sd->paramb[2]+= 15; - sd->paramb[3]+= 15; - sd->paramb[4]+= 15; - sd->paramb[5]+= 15; - } - sd->paramc[0]=sd->status.str+sd->paramb[0]+sd->parame[0]; - sd->paramc[1]=sd->status.agi+sd->paramb[1]+sd->parame[1]; - sd->paramc[2]=sd->status.vit+sd->paramb[2]+sd->parame[2]; - sd->paramc[3]=sd->status.int_+sd->paramb[3]+sd->parame[3]; - sd->paramc[4]=sd->status.dex+sd->paramb[4]+sd->parame[4]; - sd->paramc[5]=sd->status.luk+sd->paramb[5]+sd->parame[5]; - for(i=0;i<6;i++) - if(sd->paramc[i] < 0) sd->paramc[i] = 0; - - if (sd->sc_count) { - if (sd->sc_data[SC_CURSE].timer!=-1) - sd->paramc[5] = 0; - } - - if(sd->status.weapon == 11 || sd->status.weapon == 13 || sd->status.weapon == 14) { - str = sd->paramc[4]; - dex = sd->paramc[0]; - } - else { - str = sd->paramc[0]; - dex = sd->paramc[4]; - } - dstr = str/10; - sd->base_atk += str + dstr*dstr + dex/5 + sd->paramc[5]/5; - sd->matk1 += sd->paramc[3]+(sd->paramc[3]/5)*(sd->paramc[3]/5); - sd->matk2 += sd->paramc[3]+(sd->paramc[3]/7)*(sd->paramc[3]/7); - if(sd->matk1 < sd->matk2) { - int temp = sd->matk2; - sd->matk2 = sd->matk1; - sd->matk1 = temp; - } - sd->hit += sd->paramc[4] + sd->status.base_level; - sd->flee += sd->paramc[1] + sd->status.base_level; - sd->def2 += sd->paramc[2]; - sd->mdef2 += sd->paramc[3]; - sd->flee2 += sd->paramc[5]+10; - sd->critical += (sd->paramc[5]*3)+10; - - if(sd->base_atk < 1) - sd->base_atk = 1; - if(sd->critical_rate != 100) - sd->critical = (sd->critical*sd->critical_rate)/100; - if(sd->critical < 10) sd->critical = 10; - if(sd->hit_rate != 100) - sd->hit = (sd->hit*sd->hit_rate)/100; - if(sd->hit < 1) sd->hit = 1; - if(sd->flee_rate != 100) - sd->flee = (sd->flee*sd->flee_rate)/100; - if(sd->flee < 1) sd->flee = 1; - if(sd->flee2_rate != 100) - sd->flee2 = (sd->flee2*sd->flee2_rate)/100; - if(sd->flee2 < 10) sd->flee2 = 10; - if(sd->def_rate != 100) - sd->def = (sd->def*sd->def_rate)/100; - if(sd->def < 0) sd->def = 0; - if(sd->def2_rate != 100) - sd->def2 = (sd->def2*sd->def2_rate)/100; - if(sd->def2 < 1) sd->def2 = 1; - if(sd->mdef_rate != 100) - sd->mdef = (sd->mdef*sd->mdef_rate)/100; - if(sd->mdef < 0) sd->mdef = 0; - if(sd->mdef2_rate != 100) - sd->mdef2 = (sd->mdef2*sd->mdef2_rate)/100; - if(sd->mdef2 < 1) sd->mdef2 = 1; - - // 二刀流 ASPD 修正 - if (sd->status.weapon <= 16) - sd->aspd += aspd_base[s_class.job][sd->status.weapon]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->status.weapon]/1000; - else - sd->aspd += ( - (aspd_base[s_class.job][sd->weapontype1]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype1]/1000) + - (aspd_base[s_class.job][sd->weapontype2]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype2]/1000) - ) * 140 / 200; - - aspd_rate = sd->aspd_rate; - - //攻?速度?加 - - if((skill=pc_checkskill(sd,AC_VULTURE))>0){ // ワシの目 - sd->hit += skill; - if(sd->status.weapon == 11) - sd->attackrange += skill; - } - - if( (skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0) // 武器?究の命中率?加 - sd->hit += skill*2; - if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) // トンネルドライブ // トンネルドライブ - sd->speed += (100-16*skill)*DEFAULT_WALK_SPEED/100; - //sd->speed += (1.2*DEFAULT_WALK_SPEED - skill*9); - if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0) // カ?トによる速度低下 - sd->speed += (short) ((10-skill) * (DEFAULT_WALK_SPEED * 0.1)); - else if (pc_isriding(sd)) { // ペコペコ?りによる速度?加 - sd->speed -= (short) ((0.25 * DEFAULT_WALK_SPEED)); - sd->max_weight += 10000; - } - if((skill=pc_checkskill(sd,CR_TRUST))>0) { // フェイス - sd->status.max_hp += skill*200; - sd->subele[6] += skill*5; - } - if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) { - sd->subele[0] += skill; - sd->subele[3] += skill*5; - } - if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 ) - aspd_rate -= (int) (skill*0.5); - - bl=sd->status.base_level; - - sd->status.max_hp += (3500 + bl*hp_coefficient2[s_class.job] + hp_sigma_val[s_class.job][(bl > 0)? bl-1:0])/100 * (100 + sd->paramc[2])/100 + (sd->parame[2] - sd->paramcard[2]); - if (s_class.upper==1) // [MouseJstr] - sd->status.max_hp = sd->status.max_hp * 130/100; - else if (s_class.upper==2) - sd->status.max_hp = sd->status.max_hp * 70/100; - - if (sd->hprate <= 0) - sd->hprate = 1; - if(sd->hprate!=100) - sd->status.max_hp = sd->status.max_hp*sd->hprate/100; - - if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1){ // バ?サ?ク - sd->status.max_hp = sd->status.max_hp * 3; - // sd->status.hp = sd->status.hp * 3; - if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris - sd->status.max_hp = battle_config.max_hp; - if(sd->status.hp > battle_config.max_hp) // removed negative max hp bug by Valaris - sd->status.hp = battle_config.max_hp; - } - if(s_class.job == 23 && sd->status.base_level >= 99){ - sd->status.max_hp = sd->status.max_hp + 2000; - } - - if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris - sd->status.max_hp = battle_config.max_hp; - if(sd->status.max_hp <= 0) sd->status.max_hp = 1; // end - - // 最大SP計算 - sd->status.max_sp += ((sp_coefficient[s_class.job] * bl) + 1000)/100 * (100 + sd->paramc[3])/100 + (sd->parame[3] - sd->paramcard[3]); - if (s_class.upper==1) // [MouseJstr] - sd->status.max_sp = sd->status.max_sp * 130/100; - else if (s_class.upper==2) - sd->status.max_sp = sd->status.max_sp * 70/100; - if (sd->sprate <= 0) - sd->sprate = 1; - if(sd->sprate!=100) - sd->status.max_sp = sd->status.max_sp*sd->sprate/100; - - if((skill=pc_checkskill(sd,HP_MEDITATIO))>0) // メディテイティオ - sd->status.max_sp += sd->status.max_sp*skill/100; - if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0) /* ソウルドレイン */ - sd->status.max_sp += sd->status.max_sp*2*skill/100; - - if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp) - sd->status.max_sp = battle_config.max_sp; - - //自然回復HP - sd->nhealhp = 1 + (sd->paramc[2]/5) + (sd->status.max_hp/200); - if((skill=pc_checkskill(sd,SM_RECOVERY)) > 0) { /* HP回復力向上 */ - sd->nshealhp = skill*5 + (sd->status.max_hp*skill/500); - if(sd->nshealhp > 0x7fff) sd->nshealhp = 0x7fff; - } - //自然回復SP - sd->nhealsp = 1 + (sd->paramc[3]/6) + (sd->status.max_sp/100); - if(sd->paramc[3] >= 120) - sd->nhealsp += ((sd->paramc[3]-120)>>1) + 4; - if((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0) { /* SP回復力向上 */ - sd->nshealsp = skill*3 + (sd->status.max_sp*skill/500); - if(sd->nshealsp > 0x7fff) sd->nshealsp = 0x7fff; - } - - if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0) { - sd->nsshealhp = skill*4 + (sd->status.max_hp*skill/500); - sd->nsshealsp = skill*2 + (sd->status.max_sp*skill/500); - if(sd->nsshealhp > 0x7fff) sd->nsshealhp = 0x7fff; - if(sd->nsshealsp > 0x7fff) sd->nsshealsp = 0x7fff; - } - if(sd->hprecov_rate != 100) { - sd->nhealhp = sd->nhealhp*sd->hprecov_rate/100; - if(sd->nhealhp < 1) sd->nhealhp = 1; - } - if(sd->sprecov_rate != 100) { - sd->nhealsp = sd->nhealsp*sd->sprecov_rate/100; - if(sd->nhealsp < 1) sd->nhealsp = 1; - } - /* if((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0) { // f?fffBfefCfefBfI,I'SPR,A*,I',E`,。ゥZ((c)。ョR「カn~.ゥォ,E',(c),(c),e' - sd->nhealsp += 3*skill*(sd->status.max_sp)/100; - if(sd->nhealsp > 0x7fff) sd->nhealsp = 0x7fff; - } Increase natural SP regen instead of colossal SP Recovery effect [DracoRPG]*/ - - // 種族耐性(これでいいの? ディバインプロテクションと同じ?理がいるかも) - if( (skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // ドラゴノロジ? - skill = skill*4; - sd->addrace[9]+=skill; - sd->addrace_[9]+=skill; - sd->subrace[9]+=skill; - sd->magic_addrace[9]+=skill; - sd->magic_subrace[9]-=skill; - } - - //Flee上昇 - if( (skill=pc_checkskill(sd,TF_MISS))>0 ){ // 回避率?加 - sd->flee += skill*((sd->status.class_==12 || sd->status.class_==17 || sd->status.class_==4013 || sd->status.class_==4018) ? 4 : 3); - if((sd->status.class_==12 || sd->status.class_==4013) && (sd->sc_count && sd->sc_data[SC_CLOAKING].timer==-1)) - sd->speed -= (short)(skill*1.5/100 * DEFAULT_WALK_SPEED); - } - if( (skill=pc_checkskill(sd,MO_DODGE))>0 ) // 見切り - sd->flee += (skill*3)>>1; - - // スキルやステ?タス異常による?りのパラメ?タ補正 - if(sd->sc_count){ - // ATK/DEF?化形 - if(sd->sc_data[SC_ANGELUS].timer!=-1) // エンジェラス - sd->def2 = sd->def2*(110+5*sd->sc_data[SC_ANGELUS].val1)/100; - if(sd->sc_data[SC_IMPOSITIO].timer!=-1) {// インポシティオマヌス - sd->watk += sd->sc_data[SC_IMPOSITIO].val1*5; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4) - sd->watk_ += sd->sc_data[SC_IMPOSITIO].val1*5; - } - if(sd->sc_data[SC_PROVOKE].timer!=-1){ // プロボック - sd->def2 = sd->def2*(100-6*sd->sc_data[SC_PROVOKE].val1)/100; - sd->base_atk = sd->base_atk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100; - sd->watk = sd->watk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4) - sd->watk_ = sd->watk_*(100+2*sd->sc_data[SC_PROVOKE].val1)/100; - } - if(sd->sc_data[SC_ENDURE].timer!=-1) - sd->mdef2 += sd->sc_data[SC_ENDURE].val1; - if(sd->sc_data[SC_MINDBREAKER].timer!=-1){ // プロボック - sd->mdef2 = sd->mdef2*(100-6*sd->sc_data[SC_MINDBREAKER].val1)/100; - sd->matk1 = sd->matk1*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100; - sd->matk2 = sd->matk2*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100; - } - if(sd->sc_data[SC_POISON].timer!=-1) // 毒?態 - sd->def2 = sd->def2*75/100; - if(sd->sc_data[SC_CURSE].timer!=-1){ - sd->base_atk = sd->base_atk*75/100; - sd->watk = sd->watk*75/100; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4) - sd->watk_ = sd->watk_*75/100; - } - if(sd->sc_data[SC_DRUMBATTLE].timer!=-1){ // ?太鼓の響き - sd->watk += sd->sc_data[SC_DRUMBATTLE].val2; - sd->def += sd->sc_data[SC_DRUMBATTLE].val3; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4) - sd->watk_ += sd->sc_data[SC_DRUMBATTLE].val2; - } - if(sd->sc_data[SC_NIBELUNGEN].timer!=-1) { // ニ?ベルングの指輪 - index = sd->equip_index[9]; - /*if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3) - sd->watk += sd->sc_data[SC_NIBELUNGEN].val3; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3) - sd->watk_ += sd->sc_data[SC_NIBELUNGEN].val3; - index = sd->equip_index[9];*/ - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4) - sd->watk2 += sd->sc_data[SC_NIBELUNGEN].val3; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4) - sd->watk_2 += sd->sc_data[SC_NIBELUNGEN].val3; - } - - if(sd->sc_data[SC_VOLCANO].timer!=-1 && sd->def_ele==3){ // ボルケ?ノ - sd->watk += sd->sc_data[SC_VOLCANO].val3; - } - - if(sd->sc_data[SC_SIGNUMCRUCIS].timer!=-1) - sd->def = sd->def * (100 - sd->sc_data[SC_SIGNUMCRUCIS].val2)/100; - if(sd->sc_data[SC_ETERNALCHAOS].timer!=-1) // エタ?ナルカオス - sd->def=0; - - if(sd->sc_data[SC_CONCENTRATION].timer!=-1){ //コンセントレ?ション - sd->watk = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100; - index = sd->equip_index[8]; - if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4) - sd->watk_ = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100; - sd->def = sd->def * (100 - 5*sd->sc_data[SC_CONCENTRATION].val1)/100; - } - - if(sd->sc_data[SC_MAGICPOWER].timer!=-1){ //魔法力?幅 - sd->matk1 = sd->matk1*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100; - sd->matk2 = sd->matk2*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100; - } - if(sd->sc_data[SC_ATKPOT].timer!=-1) - sd->watk += sd->sc_data[SC_ATKPOT].val1; - if(sd->sc_data[SC_MATKPOT].timer!=-1){ - sd->matk1 += sd->sc_data[SC_MATKPOT].val1; - sd->matk2 += sd->sc_data[SC_MATKPOT].val1; - } - - // ASPD/移動速度?化系 - if(sd->sc_data[SC_TWOHANDQUICKEN].timer != -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // 2HQ - aspd_rate -= 30; - if(sd->sc_data[SC_ADRENALINE].timer != -1 && sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 && - sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) { // アドレナリンラッシュ - if(sd->sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty) - aspd_rate -= 30; - else - aspd_rate -= 25; - } - if(sd->sc_data[SC_SPEARSQUICKEN].timer != -1 && sd->sc_data[SC_ADRENALINE].timer == -1 && - sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // スピアクィッケン - aspd_rate -= sd->sc_data[SC_SPEARSQUICKEN].val2; - if(sd->sc_data[SC_ASSNCROS].timer!=-1 && // 夕陽のアサシンクロス - sd->sc_data[SC_TWOHANDQUICKEN].timer==-1 && sd->sc_data[SC_ADRENALINE].timer==-1 && sd->sc_data[SC_SPEARSQUICKEN].timer==-1 && - sd->sc_data[SC_DONTFORGETME].timer == -1) - aspd_rate -= 5+sd->sc_data[SC_ASSNCROS].val1+sd->sc_data[SC_ASSNCROS].val2+sd->sc_data[SC_ASSNCROS].val3; - if(sd->sc_data[SC_DONTFORGETME].timer!=-1){ // 私を忘れないで - aspd_rate += sd->sc_data[SC_DONTFORGETME].val1*3 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3>>16); - sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100; - } - if( sd->sc_data[i=SC_SPEEDPOTION3].timer!=-1 || - sd->sc_data[i=SC_SPEEDPOTION2].timer!=-1 || - sd->sc_data[i=SC_SPEEDPOTION1].timer!=-1 || - sd->sc_data[i=SC_SPEEDPOTION0].timer!=-1) // ? 速ポ?ション - aspd_rate -= sd->sc_data[i].val2; - if(sd->sc_data[SC_WINDWALK].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) //ウィンドウォ?ク暫ヘLv*2%減算 - sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100; - if(sd->sc_data[SC_CARTBOOST].timer!=-1) // カ?トブ?スト - sd->speed -= (DEFAULT_WALK_SPEED * 20)/100; - if(sd->sc_data[SC_BERSERK].timer!=-1) //バ?サ?ク中はIAと同じぐらい速い? - sd->speed -= sd->speed *25/100; - if(sd->sc_data[SC_WEDDING].timer!=-1) //結婚中は?くのが?い - sd->speed = 2*DEFAULT_WALK_SPEED; - - // HIT/FLEE?化系 - if(sd->sc_data[SC_WHISTLE].timer!=-1){ // 口笛 - sd->flee += sd->flee * (sd->sc_data[SC_WHISTLE].val1 - +sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3>>16))/100; - sd->flee2+= (sd->sc_data[SC_WHISTLE].val1+sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3&0xffff)) * 10; - } - if(sd->sc_data[SC_HUMMING].timer!=-1) // ハミング - sd->hit += (sd->sc_data[SC_HUMMING].val1*2+sd->sc_data[SC_HUMMING].val2 - +sd->sc_data[SC_HUMMING].val3) * sd->hit/100; - if(sd->sc_data[SC_VIOLENTGALE].timer!=-1 && sd->def_ele==4){ // バイオレントゲイル - sd->flee += sd->flee*sd->sc_data[SC_VIOLENTGALE].val3/100; - } - if(sd->sc_data[SC_BLIND].timer!=-1){ // 暗? - sd->hit -= sd->hit*25/100; - sd->flee -= sd->flee*25/100; - } - if(sd->sc_data[SC_WINDWALK].timer!=-1) // ウィンドウォ?ク - sd->flee += sd->flee*(sd->sc_data[SC_WINDWALK].val2)/100; - if(sd->sc_data[SC_SPIDERWEB].timer!=-1) //スパイダ?ウェブ - sd->flee -= sd->flee*50/100; - if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //トゥル?サイト - sd->hit += 3*(sd->sc_data[SC_TRUESIGHT].val1); - if(sd->sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレ?ション - sd->hit += (10*(sd->sc_data[SC_CONCENTRATION].val1)); - - // 耐性 - if(sd->sc_data[SC_SIEGFRIED].timer!=-1){ // 不死身のジ?クフリ?ド - sd->subele[1] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[2] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[3] += sd->sc_data[SC_SIEGFRIED].val2; // 火 - sd->subele[4] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[5] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[6] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[7] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[8] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - sd->subele[9] += sd->sc_data[SC_SIEGFRIED].val2; // 水 - } - if(sd->sc_data[SC_PROVIDENCE].timer!=-1){ // プロヴィデンス - sd->subele[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? 聖?性 - sd->subrace[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? ?魔 - } - - // その他 - if(sd->sc_data[SC_APPLEIDUN].timer!=-1){ // イドゥンの林檎 - sd->status.max_hp += ((5+sd->sc_data[SC_APPLEIDUN].val1*2+((sd->sc_data[SC_APPLEIDUN].val2+1)>>1) - +sd->sc_data[SC_APPLEIDUN].val3/10) * sd->status.max_hp)/100; - if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp) - sd->status.max_hp = battle_config.max_hp; - } - if(sd->sc_data[SC_DELUGE].timer!=-1 && sd->def_ele==1){ // デリュ?ジ - sd->status.max_hp += sd->status.max_hp * deluge_eff[sd->sc_data[SC_DELUGE].val1-1]/100; - if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp) - sd->status.max_hp = battle_config.max_hp; - } - if(sd->sc_data[SC_SERVICE4U].timer!=-1) { // サ?ビスフォ?ユ? - sd->status.max_sp += sd->status.max_sp*(10+sd->sc_data[SC_SERVICE4U].val1+sd->sc_data[SC_SERVICE4U].val2 - +sd->sc_data[SC_SERVICE4U].val3)/100; - if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp) - sd->status.max_sp = battle_config.max_sp; - sd->dsprate-=(10+sd->sc_data[SC_SERVICE4U].val1*3+sd->sc_data[SC_SERVICE4U].val2 - +sd->sc_data[SC_SERVICE4U].val3); - if(sd->dsprate<0)sd->dsprate=0; - } - - if(sd->sc_data[SC_FORTUNE].timer!=-1) // 幸運のキス - sd->critical += (10+sd->sc_data[SC_FORTUNE].val1+sd->sc_data[SC_FORTUNE].val2 - +sd->sc_data[SC_FORTUNE].val3)*10; - - if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer!=-1){ // 爆裂波動 - if(s_class.job==23) - sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val1*100; - else - sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val2; - } - - if(sd->sc_data[SC_STEELBODY].timer!=-1){ // 金剛 - sd->def = 90; - sd->mdef = 90; - aspd_rate += 25; - sd->speed = (sd->speed * 125) / 100; - } - if(sd->sc_data[SC_DEFENDER].timer != -1) { - //sd->aspd += (550 - sd->sc_data[SC_DEFENDER].val1*50); - aspd_rate += (25 - sd->sc_data[SC_DEFENDER].val1*5); - sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100; - } - if(sd->sc_data[SC_ENCPOISON].timer != -1) - sd->addeff[4] += sd->sc_data[SC_ENCPOISON].val2; - - if( sd->sc_data[SC_DANCING].timer!=-1 ){ // 演奏/ダンス使用中 - sd->speed = (short) ((double)sd->speed * (6.- 0.4 * pc_checkskill(sd, ((s_class.job == 19) ? BA_MUSICALLESSON : DC_DANCINGLESSON)))); - //sd->speed*=4; - sd->nhealsp = 0; - sd->nshealsp = 0; - sd->nsshealsp = 0; - } - if(sd->sc_data[SC_CURSE].timer!=-1) - sd->speed += 450; - - if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //トゥル?サイト - sd->critical += sd->critical*(sd->sc_data[SC_TRUESIGHT].val1)/100; - -/* if(sd->sc_data[SC_VOLCANO].timer!=-1) // エンチャントポイズン(?性はbattle.cで) - sd->addeff[2]+=sd->sc_data[SC_VOLCANO].val2;//% of granting - if(sd->sc_data[SC_DELUGE].timer!=-1) // エンチャントポイズン(?性はbattle.cで) - sd->addeff[0]+=sd->sc_data[SC_DELUGE].val2;//% of granting - */ - if(sd->sc_data[SC_BERSERK].timer!=-1) { //All Def/MDef reduced to 0 while in Berserk [DracoRPG] - sd->def = sd->def2 = 0; - sd->mdef = sd->mdef2 = 0; - sd->flee -= sd->flee*50/100; - aspd_rate -= 30; - //sd->base_atk *= 3; - } - if(sd->sc_data[SC_KEEPING].timer!=-1) - sd->def = 100; - if(sd->sc_data[SC_BARRIER].timer!=-1) - sd->mdef = 100; - - if(sd->sc_data[SC_JOINTBEAT].timer!=-1) { // Random break [DracoRPG] - switch(sd->sc_data[SC_JOINTBEAT].val2) { - case 1: //Ankle break - sd->speed_rate += 50; - break; - case 2: //Wrist break - sd->aspd_rate += 25; - break; - case 3: //Knee break - sd->speed_rate += 30; - sd->aspd_rate += 10; - break; - case 4: //Shoulder break - sd->def2 -= sd->def2*50/100; - break; - case 5: //Waist break - sd->def2 -= sd->def2*50/100; - sd->base_atk -= sd->base_atk*25/100; - break; - } - } - - if(sd->sc_data[SC_GOSPEL].timer!=-1) { - if (sd->sc_data[SC_GOSPEL].val4 == BCT_PARTY){ - switch (sd->sc_data[SC_GOSPEL].val3) - { - case 4: - sd->status.max_hp += sd->status.max_hp * 25 / 100; - if(sd->status.max_hp > battle_config.max_hp) - sd->status.max_hp = battle_config.max_hp; - break; - case 5: - sd->status.max_sp += sd->status.max_sp * 25 / 100; - if(sd->status.max_sp > battle_config.max_sp) - sd->status.max_sp = battle_config.max_sp; - break; - case 11: - sd->def += sd->def * 25 / 100; - sd->def2 += sd->def2 * 25 / 100; - break; - case 12: - sd->base_atk += sd->base_atk * 8 / 100; - break; - case 13: - sd->flee += sd->flee * 5 / 100; - break; - case 14: - sd->hit += sd->hit * 5 / 100; - break; - } - } else if (sd->sc_data[SC_GOSPEL].val4 == BCT_ENEMY){ - switch (sd->sc_data[SC_GOSPEL].val3) - { - case 5: - sd->def = 0; - sd->def2 = 0; - break; - case 6: - sd->base_atk = 0; - sd->watk = 0; - sd->watk2 = 0; - break; - case 7: - sd->flee = 0; - break; - case 8: - sd->speed_rate += 75; - aspd_rate += 75; - break; - } - } - } - // custom stats, since there's no info on how much it actually gives ^^; [Celest] - if (sd->sc_data[SC_GUILDAURA].timer != -1) { - if (sd->sc_data[SC_GUILDAURA].val4 & 1<<4) { - sd->hit += 10; - sd->flee += 10; - } - } - } - - if (sd->speed_rate <= 0) - sd->speed_rate = 1; - - if(sd->speed_rate != 100) - sd->speed = sd->speed*sd->speed_rate/100; - if(sd->speed < 1) sd->speed = 1; - if(aspd_rate != 100) - sd->aspd = sd->aspd*aspd_rate/100; - if(pc_isriding(sd)) // 騎兵修練 - sd->aspd = sd->aspd*(100 + 10*(5 - pc_checkskill(sd,KN_CAVALIERMASTERY)))/ 100; - if(sd->aspd < battle_config.max_aspd) sd->aspd = battle_config.max_aspd; - sd->amotion = sd->aspd; - sd->dmotion = 800-sd->paramc[1]*4; - if(sd->dmotion<400) - sd->dmotion = 400; - if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) { - sd->prev_speed = sd->speed; - sd->speed = sd->speed*(175 - skill*5)/100; - } - - if(sd->status.hp>sd->status.max_hp) - sd->status.hp=sd->status.max_hp; - if(sd->status.sp>sd->status.max_sp) - sd->status.sp=sd->status.max_sp; - - if(first&4) - return 0; - if(first&3) { - clif_updatestatus(sd,SP_SPEED); - clif_updatestatus(sd,SP_MAXHP); - clif_updatestatus(sd,SP_MAXSP); - if(first&1) { - clif_updatestatus(sd,SP_HP); - clif_updatestatus(sd,SP_SP); - } - return 0; - } - - if(b_class != sd->view_class) { - clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); -#if PACKETVER < 4 - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); -#else - clif_changelook(&sd->bl,LOOK_WEAPON,0); -#endif - } - - if( memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)) || b_attackrange != sd->attackrange) - clif_skillinfoblock(sd); // スキル送信 - - if(b_speed != sd->speed) - clif_updatestatus(sd,SP_SPEED); - if(b_weight != sd->weight) - clif_updatestatus(sd,SP_WEIGHT); - if(b_max_weight != sd->max_weight) { - clif_updatestatus(sd,SP_MAXWEIGHT); - pc_checkweighticon(sd); - } - for(i=0;i<6;i++) - if(b_paramb[i] + b_parame[i] != sd->paramb[i] + sd->parame[i]) - clif_updatestatus(sd,SP_STR+i); - if(b_hit != sd->hit) - clif_updatestatus(sd,SP_HIT); - if(b_flee != sd->flee) - clif_updatestatus(sd,SP_FLEE1); - if(b_aspd != sd->aspd) - clif_updatestatus(sd,SP_ASPD); - if(b_watk != sd->watk || b_base_atk != sd->base_atk) - clif_updatestatus(sd,SP_ATK1); - if(b_def != sd->def) - clif_updatestatus(sd,SP_DEF1); - if(b_watk2 != sd->watk2) - clif_updatestatus(sd,SP_ATK2); - if(b_def2 != sd->def2) - clif_updatestatus(sd,SP_DEF2); - if(b_flee2 != sd->flee2) - clif_updatestatus(sd,SP_FLEE2); - if(b_critical != sd->critical) - clif_updatestatus(sd,SP_CRITICAL); - if(b_matk1 != sd->matk1) - clif_updatestatus(sd,SP_MATK1); - if(b_matk2 != sd->matk2) - clif_updatestatus(sd,SP_MATK2); - if(b_mdef != sd->mdef) - clif_updatestatus(sd,SP_MDEF1); - if(b_mdef2 != sd->mdef2) - clif_updatestatus(sd,SP_MDEF2); - if(b_attackrange != sd->attackrange) - clif_updatestatus(sd,SP_ATTACKRANGE); - if(b_max_hp != sd->status.max_hp) - clif_updatestatus(sd,SP_MAXHP); - if(b_max_sp != sd->status.max_sp) - clif_updatestatus(sd,SP_MAXSP); - if(b_hp != sd->status.hp) - clif_updatestatus(sd,SP_HP); - if(b_sp != sd->status.sp) - clif_updatestatus(sd,SP_SP); - -/* if(before.cart_num != before.cart_num || before.cart_max_num != before.cart_max_num || - before.cart_weight != before.cart_weight || before.cart_max_weight != before.cart_max_weight ) - clif_updatestatus(sd,SP_CARTINFO);*/ - - //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 && - if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 && - (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ) && !pc_isdead(sd)) - // オ?トバ?サ?ク?動 - status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0); - - return 0; -} - -/*========================================== - * For quick calculating [Celest] - *------------------------------------------ - */ -int status_calc_speed (struct map_session_data *sd) -{ - int b_speed, skill; - struct pc_base_job s_class; - - nullpo_retr(0, sd); - - s_class = pc_calc_base_job(sd->status.class_); - - b_speed = sd->speed; - sd->speed = DEFAULT_WALK_SPEED ; - - if(sd->sc_count){ - if(sd->sc_data[SC_INCREASEAGI].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1){ // 速度?加 - sd->speed -= sd->speed *25/100; - } - if(sd->sc_data[SC_DECREASEAGI].timer!=-1) { - sd->speed = sd->speed *125/100; - } - if(sd->sc_data[SC_CLOAKING].timer!=-1) { - sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100; - } - if(sd->sc_data[SC_CHASEWALK].timer!=-1) { - sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100; - } - if(sd->sc_data[SC_QUAGMIRE].timer!=-1){ - sd->speed = sd->speed*3/2; - } - if(sd->sc_data[SC_WINDWALK].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) { - sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100; - } - if(sd->sc_data[SC_CARTBOOST].timer!=-1) { - sd->speed -= (DEFAULT_WALK_SPEED * 20)/100; - } - if(sd->sc_data[SC_BERSERK].timer!=-1) { - sd->speed -= sd->speed *25/100; - } - if(sd->sc_data[SC_WEDDING].timer!=-1) { - sd->speed = 2*DEFAULT_WALK_SPEED; - } - if(sd->sc_data[SC_DONTFORGETME].timer!=-1){ - sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100; - } - if(sd->sc_data[SC_STEELBODY].timer!=-1){ - sd->speed = (sd->speed * 125) / 100; - } - if(sd->sc_data[SC_DEFENDER].timer != -1) { - sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100; - } - if( sd->sc_data[SC_DANCING].timer!=-1 ){ - sd->speed = (int) ((double)sd->speed * (6.- 0.4 * pc_checkskill(sd, ((s_class.job == 19) ? BA_MUSICALLESSON : DC_DANCINGLESSON)))); - } - if(sd->sc_data[SC_CURSE].timer!=-1) - sd->speed += 450; - if(sd->sc_data[SC_SLOWDOWN].timer!=-1) - sd->speed = sd->speed*150/100; - if(sd->sc_data[SC_SPEEDUP0].timer!=-1) - sd->speed -= sd->speed*25/100; - } - - if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) - sd->speed += (100-16*skill)*DEFAULT_WALK_SPEED/100; - if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0) - sd->speed += (short) ((10-skill) * (DEFAULT_WALK_SPEED * 0.1)); - else if (pc_isriding(sd)) { - sd->speed -= (short) ((0.25 * DEFAULT_WALK_SPEED)); - } - if((skill=pc_checkskill(sd,TF_MISS))>0) - if(s_class.job==12) - sd->speed -= (short) (sd->speed *(skill*1.5)/100); - - if(sd->speed_rate != 100) - sd->speed = sd->speed*sd->speed_rate/100; - if(sd->speed < 1) sd->speed = 1; - - if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) { - sd->prev_speed = sd->speed; - sd->speed = sd->speed*(175 - skill*5)/100; - } - - if(b_speed != sd->speed) - clif_updatestatus(sd,SP_SPEED); - - return 0; -} - -/*========================================== - * 対象のClassを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_class(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return ((struct mob_data *)bl)->class_; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->status.class_; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return ((struct pet_data *)bl)->class_; - else - return 0; -} -/*========================================== - * 対象の方向を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_dir(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return ((struct mob_data *)bl)->dir; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->dir; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return ((struct pet_data *)bl)->dir; - else - return 0; -} -/*========================================== - * 対象のレベルを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_lv(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return ((struct mob_data *)bl)->level; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->status.base_level; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return ((struct pet_data *)bl)->msd->pet.level; - else - return 0; -} - -/*========================================== - * 対象の射程を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_range(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return mob_db[((struct mob_data *)bl)->class_].range; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->attackrange; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return mob_db[((struct pet_data *)bl)->class_].range; - else - return 0; -} -/*========================================== - * 対象のHPを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_hp(struct block_list *bl) -{ - nullpo_retr(1, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return ((struct mob_data *)bl)->hp; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->status.hp; - else - return 1; -} -/*========================================== - * 対象のMHPを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_max_hp(struct block_list *bl) -{ - nullpo_retr(1, bl); - - if(bl->type==BL_PC && ((struct map_session_data *)bl)) - return ((struct map_session_data *)bl)->status.max_hp; - else { - struct status_change *sc_data; - int max_hp = 1; - - if(bl->type == BL_MOB) { - struct mob_data *md; - nullpo_retr(1, md = (struct mob_data *)bl); - max_hp = mob_db[md->class_].max_hp; - - if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris] - max_hp += (md->level - mob_db[md->class_].lv) * status_get_vit(bl); - - if(mob_db[md->class_].mexp > 0) { //MVP Monsters - if(battle_config.mvp_hp_rate != 100) { - double hp = (double)max_hp * battle_config.mvp_hp_rate / 100.0; - max_hp = (hp > 0x7FFFFFFF ? 0x7FFFFFFF : (int)hp); - } - } - else { //Common MONSTERS - if(battle_config.monster_hp_rate != 100) { - double hp = (double)max_hp * battle_config.monster_hp_rate / 100.0; - max_hp = (hp > 0x7FFFFFFF ? 0x7FFFFFFF : (int)hp); - } - } - } - else if(bl->type == BL_PET) { - struct pet_data *pd; - nullpo_retr(1, pd = (struct pet_data*)bl); - max_hp = mob_db[pd->class_].max_hp; - - if(mob_db[pd->class_].mexp > 0) { //MVP Monsters - if(battle_config.mvp_hp_rate != 100) - max_hp = (max_hp * battle_config.mvp_hp_rate)/100; - } - else { //Common MONSTERS - if(battle_config.monster_hp_rate != 100) - max_hp = (max_hp * battle_config.monster_hp_rate)/100; - } - } - - sc_data = status_get_sc_data(bl); - if(sc_data) { - if(sc_data[SC_APPLEIDUN].timer != -1) - max_hp += ((5 + sc_data[SC_APPLEIDUN].val1 * 2 + ((sc_data[SC_APPLEIDUN].val2 + 1) >> 1) - + sc_data[SC_APPLEIDUN].val3 / 10) * max_hp)/100; - if(sc_data[SC_GOSPEL].timer != -1 && - sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 4) - max_hp += max_hp * 25 / 100; - } - if(max_hp < 1) max_hp = 1; - return max_hp; - } - return 1; -} -/*========================================== - * 対象のStrを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_str(struct block_list *bl) -{ - int str = 0; - nullpo_retr(0, bl); - - if (bl->type == BL_PC && ((struct map_session_data *)bl)) - return ((struct map_session_data *)bl)->paramc[0]; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - - if(bl->type == BL_MOB && ((struct mob_data *)bl)) { - str = mob_db[((struct mob_data *)bl)->class_].str; - if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris] - str += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type == BL_PET && ((struct pet_data *)bl)) - str = mob_db[((struct pet_data *)bl)->class_].str; - - if(sc_data) { - if(sc_data[SC_LOUD].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1) - str += 4; - if( sc_data[SC_BLESSING].timer != -1){ // ブレッシング - int race = status_get_race(bl); - if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6) - str >>= 1; // 悪 魔/不死 - else str += sc_data[SC_BLESSING].val1; // その他 - } - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - str += 5; - } - } - if(str < 0) str = 0; - return str; -} -/*========================================== - * 対象のAgiを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ - -int status_get_agi(struct block_list *bl) -{ - int agi=0; - nullpo_retr(0, bl); - - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->paramc[1]; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - if(bl->type == BL_MOB && (struct mob_data *)bl) { - agi = mob_db[((struct mob_data *)bl)->class_].agi; - if(battle_config.mobs_level_up) // increase of mobs leveling up [Valaris] - agi += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type == BL_PET && (struct pet_data *)bl) - agi = mob_db[((struct pet_data *)bl)->class_].agi; - - if(sc_data) { - if(sc_data[SC_INCREASEAGI].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 速度増加(PCはpc.cで) - agi += 2 + sc_data[SC_INCREASEAGI].val1; - if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1) - agi += agi * (2 + sc_data[SC_CONCENTRATE].val1)/100; - if(sc_data[SC_DECREASEAGI].timer!=-1) // 速度減少 - agi -= 2 + sc_data[SC_DECREASEAGI].val1; - if(sc_data[SC_QUAGMIRE].timer!=-1 ) { // クァグマイア - //agi >>= 1; - //int agib = agi*(sc_data[SC_QUAGMIRE].val1*10)/100; - //agi -= agib > 50 ? 50 : agib; - agi -= sc_data[SC_QUAGMIRE].val1*10; - } - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - agi += 5; - } - } - if(agi < 0) agi = 0; - return agi; -} -/*========================================== - * 対象のVitを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_vit(struct block_list *bl) -{ - int vit = 0; - nullpo_retr(0, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->paramc[2]; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - if(bl->type == BL_MOB && (struct mob_data *)bl) { - vit = mob_db[((struct mob_data *)bl)->class_].vit; - if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris] - vit += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type == BL_PET && (struct pet_data *)bl) - vit = mob_db[((struct pet_data *)bl)->class_].vit; - if(sc_data) { - if(sc_data[SC_STRIPARMOR].timer != -1) - vit = vit*60/100; - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - vit += 5; - } - } - if(vit < 0) vit = 0; - return vit; -} -/*========================================== - * 対象のIntを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_int(struct block_list *bl) -{ - int int_=0; - nullpo_retr(0, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->paramc[3]; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - if(bl->type == BL_MOB && (struct mob_data *)bl){ - int_ = mob_db[((struct mob_data *)bl)->class_].int_; - if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris] - int_ += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type == BL_PET && (struct pet_data *)bl) - int_ = mob_db[((struct pet_data *)bl)->class_].int_; - - if(sc_data) { - if(sc_data[SC_BLESSING].timer != -1){ // ブレッシング - int race = status_get_race(bl); - if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6 ) - int_ >>= 1; // 悪 魔/不死 - else - int_ += sc_data[SC_BLESSING].val1; // その他 - } - if(sc_data[SC_STRIPHELM].timer != -1) - int_ = int_*60/100; - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - int_ += 5; - } - } - if(int_ < 0) int_ = 0; - return int_; -} -/*========================================== - * 対象のDexを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_dex(struct block_list *bl) -{ - int dex = 0; - nullpo_retr(0, bl); - - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->paramc[4]; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - if(bl->type == BL_MOB && (struct mob_data *)bl) { - dex = mob_db[((struct mob_data *)bl)->class_].dex; - if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris] - dex += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type == BL_PET && (struct pet_data *)bl) - dex = mob_db[((struct pet_data *)bl)->class_].dex; - - if(sc_data) { - if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1) - dex += dex*(2+sc_data[SC_CONCENTRATE].val1)/100; - if(sc_data[SC_BLESSING].timer != -1){ // ブレッシング - int race = status_get_race(bl); - if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6 ) - dex >>= 1; // 悪 魔/不死 - else dex += sc_data[SC_BLESSING].val1; // その他 - } - if(sc_data[SC_QUAGMIRE].timer!=-1) { // クァグマイア - // dex >>= 1; - //int dexb = dex*(sc_data[SC_QUAGMIRE].val1*10)/100; - //dex -= dexb > 50 ? 50 : dexb; - dex -= sc_data[SC_QUAGMIRE].val1*10; - } - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - dex += 5; - } - } - if(dex < 0) dex = 0; - return dex; -} -/*========================================== - * 対象のLukを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_luk(struct block_list *bl) -{ - int luk = 0; - nullpo_retr(0, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->paramc[5]; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - if(bl->type == BL_MOB && (struct mob_data *)bl) { - luk = mob_db[((struct mob_data *)bl)->class_].luk; - if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris] - luk += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type == BL_PET && (struct pet_data *)bl) - luk = mob_db[((struct pet_data *)bl)->class_].luk; - if(sc_data) { - if(sc_data[SC_GLORIA].timer!=-1) // グロリア(PCはpc.cで) - luk += 30; - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - luk += 5; - if(sc_data[SC_CURSE].timer!=-1) // 呪い - luk = 0; - } - } - if(luk < 0) luk = 0; - return luk; -} - -/*========================================== - * 対象のFleeを返す(汎用) - * 戻りは整数で1以上 - *------------------------------------------ - */ -int status_get_flee(struct block_list *bl) -{ - int flee = 1; - nullpo_retr(1, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->flee; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - flee = status_get_agi(bl) + status_get_lv(bl); - - if(sc_data){ - if(sc_data[SC_WHISTLE].timer!=-1) - flee += flee*(sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2 - +(sc_data[SC_WHISTLE].val3>>16))/100; - if(sc_data[SC_BLIND].timer!=-1) - flee -= flee*25/100; - if(sc_data[SC_WINDWALK].timer!=-1) // ウィンドウォーク - flee += flee*(sc_data[SC_WINDWALK].val2)/100; - if(sc_data[SC_SPIDERWEB].timer!=-1) //スパイダーウェブ - flee -= flee*50/100; - if(sc_data[SC_GOSPEL].timer!=-1) { - if (sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 13) - flee += flee*5/100; - else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 7) - flee = 0; - } - } - } - if(flee < 1) flee = 1; - return flee; -} -/*========================================== - * 対象のHitを返す(汎用) - * 戻りは整数で1以上 - *------------------------------------------ - */ -int status_get_hit(struct block_list *bl) -{ - int hit = 1; - nullpo_retr(1, bl); - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->hit; - else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - hit = status_get_dex(bl) + status_get_lv(bl); - - if(sc_data) { - if(sc_data[SC_HUMMING].timer!=-1) // - hit += hit*(sc_data[SC_HUMMING].val1*2+sc_data[SC_HUMMING].val2 - +sc_data[SC_HUMMING].val3)/100; - if(sc_data[SC_BLIND].timer!=-1) // 呪い - hit -= hit*25/100; - if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - hit += 3*(sc_data[SC_TRUESIGHT].val1); - if(sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレーション - hit += (hit*(10*(sc_data[SC_CONCENTRATION].val1)))/100; - if(sc_data[SC_GOSPEL].timer!=-1 && - sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 14) - hit += hit*5/100; - if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1) - hit += 20*sc_data[SC_EXPLOSIONSPIRITS].val1; - } - } - if(hit < 1) hit = 1; - return hit; -} -/*========================================== - * 対象の完全回避を返す(汎用) - * 戻りは整数で1以上 - *------------------------------------------ - */ -int status_get_flee2(struct block_list *bl) -{ - int flee2 = 1; - nullpo_retr(1, bl); - - if(bl->type==BL_PC && (struct map_session_data *)bl){ - return ((struct map_session_data *)bl)->flee2; - } else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - flee2 = status_get_luk(bl)+1; - - if(sc_data) { - if(sc_data[SC_WHISTLE].timer!=-1) - flee2 += (sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2 - +(sc_data[SC_WHISTLE].val3&0xffff))*10; - } - } - if(flee2 < 1) flee2 = 1; - return flee2; -} -/*========================================== - * 対象のクリティカルを返す(汎用) - * 戻りは整数で1以上 - *------------------------------------------ - */ -int status_get_critical(struct block_list *bl) -{ - int critical = 1; - nullpo_retr(1, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl){ - return ((struct map_session_data *)bl)->critical; - } else { - struct status_change *sc_data; - sc_data = status_get_sc_data(bl); - critical = status_get_luk(bl)*3 + 1; - - if(sc_data) { - if(sc_data[SC_FORTUNE].timer!=-1) - critical += (10+sc_data[SC_FORTUNE].val1+sc_data[SC_FORTUNE].val2 - + sc_data[SC_FORTUNE].val3)*10; - if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1) - critical += sc_data[SC_EXPLOSIONSPIRITS].val2; - if(sc_data[SC_TRUESIGHT].timer!=-1) //トゥルーサイト - critical += critical*sc_data[SC_TRUESIGHT].val1/100; - } - } - if(critical < 1) critical = 1; - return critical; -} -/*========================================== - * base_atkの取得 - * 戻りは整数で1以上 - *------------------------------------------ - */ -int status_get_baseatk(struct block_list *bl) -{ - int batk = 1; - nullpo_retr(1, bl); - - if(bl->type==BL_PC && (struct map_session_data *)bl) { - batk = ((struct map_session_data *)bl)->base_atk; //設定されているbase_atk - if (((struct map_session_data *)bl)->status.weapon < 16) - batk += ((struct map_session_data *)bl)->weapon_atk[((struct map_session_data *)bl)->status.weapon]; - } else { //それ以外なら - struct status_change *sc_data; - int str,dstr; - str = status_get_str(bl); //STR - dstr = str/10; - batk = dstr*dstr + str; //base_atkを計算する - sc_data = status_get_sc_data(bl); - - if(sc_data) { //状態異常あり - if(sc_data[SC_PROVOKE].timer!=-1) //PCでプロボック(SM_PROVOKE)状態 - batk = batk*(100+2*sc_data[SC_PROVOKE].val1)/100; //base_atk増加 - if(sc_data[SC_CURSE].timer!=-1) //呪われていたら - batk -= batk*25/100; //base_atkが25%減少 - if(sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレーション - batk += batk*(5*sc_data[SC_CONCENTRATION].val1)/100; - } - } - if(batk < 1) batk = 1; //base_atkは最低でも1 - return batk; -} -/*========================================== - * 対象のAtkを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_atk(struct block_list *bl) -{ - int atk = 0; - nullpo_retr(0, bl); - - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data*)bl)->watk; - else { - struct status_change *sc_data; - sc_data=status_get_sc_data(bl); - - if(bl->type == BL_MOB && (struct mob_data *)bl) - atk = mob_db[((struct mob_data*)bl)->class_].atk1; - else if(bl->type == BL_PET && (struct pet_data *)bl) - atk = mob_db[((struct pet_data*)bl)->class_].atk1; - - if(sc_data) { - if(sc_data[SC_PROVOKE].timer!=-1) - atk = atk*(100+2*sc_data[SC_PROVOKE].val1)/100; - if(sc_data[SC_CURSE].timer!=-1) - atk -= atk*25/100; - if(sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレーション - atk += atk*(5*sc_data[SC_CONCENTRATION].val1)/100; - if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1) - atk += (1000*sc_data[SC_EXPLOSIONSPIRITS].val1); - if(sc_data[SC_STRIPWEAPON].timer!=-1) - atk -= atk*10/100; - - if(sc_data[SC_GOSPEL].timer!=-1) { - if (sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 12) - atk += atk*8/100; - else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 6) - atk = 0; - } - } - } - if(atk < 0) atk = 0; - return atk; -} -/*========================================== - * 対象の左手Atkを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_atk_(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl){ - int atk=((struct map_session_data*)bl)->watk_; - return atk; - } - else - return 0; -} -/*========================================== - * 対象のAtk2を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_atk2(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data*)bl)->watk2; - else { - struct status_change *sc_data=status_get_sc_data(bl); - int atk2=0; - if(bl->type==BL_MOB && (struct mob_data *)bl) - atk2 = mob_db[((struct mob_data*)bl)->class_].atk2; - else if(bl->type==BL_PET && (struct pet_data *)bl) - atk2 = mob_db[((struct pet_data*)bl)->class_].atk2; - if(sc_data) { - if( sc_data[SC_IMPOSITIO].timer!=-1) - atk2 += sc_data[SC_IMPOSITIO].val1*5; - if( sc_data[SC_PROVOKE].timer!=-1 ) - atk2 = atk2*(100+2*sc_data[SC_PROVOKE].val1)/100; - if( sc_data[SC_CURSE].timer!=-1 ) - atk2 -= atk2*25/100; - if(sc_data[SC_DRUMBATTLE].timer!=-1) - atk2 += sc_data[SC_DRUMBATTLE].val2; - if(sc_data[SC_NIBELUNGEN].timer!=-1 && (status_get_element(bl)/10) >= 8 ) - atk2 += sc_data[SC_NIBELUNGEN].val3; - if(sc_data[SC_STRIPWEAPON].timer!=-1) - atk2 = atk2*sc_data[SC_STRIPWEAPON].val2/100; - if(sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレーション - atk2 += atk2*(5*sc_data[SC_CONCENTRATION].val1)/100; - if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1) - atk2 += (1000*sc_data[SC_EXPLOSIONSPIRITS].val1); - } - if(atk2 < 0) atk2 = 0; - return atk2; - } - return 0; -} -/*========================================== - * 対象の左手Atk2を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_atk_2(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data*)bl)->watk_2; - else - return 0; -} -/*========================================== - * 対象のMAtk1を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_matk1(struct block_list *bl) -{ - int matk = 0; - nullpo_retr(0, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->matk1; - else { - struct status_change *sc_data; - int int_ = status_get_int(bl); - matk = int_+(int_/5)*(int_/5); - - sc_data = status_get_sc_data(bl); - if(sc_data) { - if(sc_data[SC_MINDBREAKER].timer!=-1) - matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100; - } - } - return matk; -} -/*========================================== - * 対象のMAtk2を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_matk2(struct block_list *bl) -{ - int matk = 0; - nullpo_retr(0, bl); - - if(bl->type == BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->matk2; - else { - struct status_change *sc_data = status_get_sc_data(bl); - int int_ = status_get_int(bl); - matk = int_+(int_/7)*(int_/7); - - if(sc_data) { - if(sc_data[SC_MINDBREAKER].timer!=-1) - matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100; - } - } - return matk; -} -/*========================================== - * 対象のDefを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_def(struct block_list *bl) -{ - struct status_change *sc_data; - int def=0,skilltimer=-1,skillid=0; - - nullpo_retr(0, bl); - sc_data=status_get_sc_data(bl); - if(bl->type==BL_PC && (struct map_session_data *)bl){ - def = ((struct map_session_data *)bl)->def; - skilltimer = ((struct map_session_data *)bl)->skilltimer; - skillid = ((struct map_session_data *)bl)->skillid; - } - else if(bl->type==BL_MOB && (struct mob_data *)bl) { - def = mob_db[((struct mob_data *)bl)->class_].def; - skilltimer = ((struct mob_data *)bl)->skilltimer; - skillid = ((struct mob_data *)bl)->skillid; - } - else if(bl->type==BL_PET && (struct pet_data *)bl) - def = mob_db[((struct pet_data *)bl)->class_].def; - - if(def < 1000000) { - if(sc_data) { - //凍結、石化時は右シフト - if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0)) - def >>= 1; - - if (bl->type != BL_PC) { - //キーピング時はDEF100 - if( sc_data[SC_KEEPING].timer!=-1) - def = 100; - //プロボック時は減算 - if( sc_data[SC_PROVOKE].timer!=-1) - def = (def*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100; - //戦太鼓の響き時は加算 - if( sc_data[SC_DRUMBATTLE].timer!=-1) - def += sc_data[SC_DRUMBATTLE].val3; - //毒にかかっている時は減算 - if(sc_data[SC_POISON].timer!=-1) - def = def*75/100; - //ストリップシールド時は減算 - if(sc_data[SC_STRIPSHIELD].timer!=-1) - def = def*sc_data[SC_STRIPSHIELD].val2/100; - //シグナムクルシス時は減算 - if(sc_data[SC_SIGNUMCRUCIS].timer!=-1) - def = def * (100 - sc_data[SC_SIGNUMCRUCIS].val2)/100; - //永遠の混沌時はDEF0になる - if(sc_data[SC_ETERNALCHAOS].timer!=-1) - def = 0; - //コンセントレーション時は減算 - if( sc_data[SC_CONCENTRATION].timer!=-1) - def = (def*(100 - 5*sc_data[SC_CONCENTRATION].val1))/100; - - if(sc_data[SC_GOSPEL].timer!=-1) { - if (sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 11) - def += def*25/100; - else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 5) - def = 0; - } - if(sc_data[SC_JOINTBEAT].timer!=-1) { - if (sc_data[SC_JOINTBEAT].val2 == 4) - def -= def*50/100; - else if (sc_data[SC_JOINTBEAT].val2 == 5) - def -= def*25/100; - } - } - } - //詠唱中は詠唱時減算率に基づいて減算 - if(skilltimer != -1) { - int def_rate = skill_get_castdef(skillid); - if(def_rate != 0) - def = (def * (100 - def_rate))/100; - } - } - if(def < 0) def = 0; - return def; -} -/*========================================== - * 対象のMDefを返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_mdef(struct block_list *bl) -{ - struct status_change *sc_data; - int mdef=0; - - nullpo_retr(0, bl); - sc_data=status_get_sc_data(bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - mdef = ((struct map_session_data *)bl)->mdef; - else if(bl->type==BL_MOB && (struct mob_data *)bl) - mdef = mob_db[((struct mob_data *)bl)->class_].mdef; - else if(bl->type==BL_PET && (struct pet_data *)bl) - mdef = mob_db[((struct pet_data *)bl)->class_].mdef; - - if(mdef < 1000000) { - if(sc_data) { - //バリアー状態時はMDEF100 - if(sc_data[SC_BARRIER].timer != -1) - mdef = 100; - //凍結、石化時は1.25倍 - if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0)) - mdef = mdef*125/100; - if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC) - mdef -= (mdef*6*sc_data[SC_MINDBREAKER].val1)/100; - } - } - if(mdef < 0) mdef = 0; - return mdef; -} -/*========================================== - * 対象のDef2を返す(汎用) - * 戻りは整数で1以上 - *------------------------------------------ - */ -int status_get_def2(struct block_list *bl) -{ - int def2 = 1; - nullpo_retr(1, bl); - - if(bl->type==BL_PC) - return ((struct map_session_data *)bl)->def2; - else { - struct status_change *sc_data; - - if(bl->type==BL_MOB) - def2 = mob_db[((struct mob_data *)bl)->class_].vit; - else if(bl->type==BL_PET) - def2 = mob_db[((struct pet_data *)bl)->class_].vit; - - sc_data = status_get_sc_data(bl); - if(sc_data) { - if(sc_data[SC_ANGELUS].timer != -1) - def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100; - if(sc_data[SC_PROVOKE].timer!=-1) - def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100; - if(sc_data[SC_POISON].timer!=-1) - def2 = def2*75/100; - //コンセントレーション時は減算 - if( sc_data[SC_CONCENTRATION].timer!=-1) - def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100; - - if(sc_data[SC_GOSPEL].timer!=-1) { - if (sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 11) - def2 += def2*25/100; - else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 5) - def2 = 0; - } - } - } - if(def2 < 1) def2 = 1; - return def2; -} -/*========================================== - * 対象のMDef2を返す(汎用) - * 戻りは整数で0以上 - *------------------------------------------ - */ -int status_get_mdef2(struct block_list *bl) -{ - int mdef2 = 0; - nullpo_retr(0, bl); - - if(bl->type == BL_PC) - return ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1); - else { - struct status_change *sc_data = status_get_sc_data(bl); - if(bl->type == BL_MOB) - mdef2 = mob_db[((struct mob_data *)bl)->class_].int_ + (mob_db[((struct mob_data *)bl)->class_].vit>>1); - else if(bl->type == BL_PET) - mdef2 = mob_db[((struct pet_data *)bl)->class_].int_ + (mob_db[((struct pet_data *)bl)->class_].vit>>1); - if(sc_data) { - if(sc_data[SC_MINDBREAKER].timer!=-1) - mdef2 -= (mdef2*6*sc_data[SC_MINDBREAKER].val1)/100; - } - } - if(mdef2 < 0) mdef2 = 0; - return mdef2; -} -/*========================================== - * 対象のSpeed(移動速度)を返す(汎用) - * 戻りは整数で1以上 - * Speedは小さいほうが移動速度が速い - *------------------------------------------ - */ -int status_get_speed(struct block_list *bl) -{ - nullpo_retr(1000, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->speed; - else { - struct status_change *sc_data=status_get_sc_data(bl); - int speed = 1000; - if(bl->type==BL_MOB && (struct mob_data *)bl) { - speed = ((struct mob_data *)bl)->speed; - if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris] - speed-=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv; - } - else if(bl->type==BL_PET && (struct pet_data *)bl) - speed = ((struct pet_data *)bl)->msd->petDB->speed; - - if(sc_data) { - //速度増加時は25%減算 - if(sc_data[SC_INCREASEAGI].timer!=-1) - speed -= speed*25/100; - //ウィンドウォーク時はLv*2%減算 - else if(sc_data[SC_WINDWALK].timer!=-1) - speed -= (speed*(sc_data[SC_WINDWALK].val1*2))/100; - //速度減少時は25%加算 - if(sc_data[SC_DECREASEAGI].timer!=-1) - speed = speed*125/100; - //クァグマイア時は50%加算 - if(sc_data[SC_QUAGMIRE].timer!=-1) - speed = speed*3/2; - //私を忘れないで…時は加算 - if(sc_data[SC_DONTFORGETME].timer!=-1) - speed = speed*(100+sc_data[SC_DONTFORGETME].val1*2 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3&0xffff))/100; - //金剛時は25%加算 - if(sc_data[SC_STEELBODY].timer!=-1) - speed = speed*125/100; - //ディフェンダー時は加算 - if(sc_data[SC_DEFENDER].timer!=-1) - speed = (speed * (155 - sc_data[SC_DEFENDER].val1*5)) / 100; - //踊り状態は4倍遅い - if(sc_data[SC_DANCING].timer!=-1 ) - speed *= 6; - //呪い時は450加算 - if(sc_data[SC_CURSE].timer!=-1) - speed = speed + 450; - if(sc_data[SC_SLOWDOWN].timer!=-1) - speed = speed*150/100; - if(sc_data[SC_SPEEDUP0].timer!=-1) - speed -= speed*25/100; - if(sc_data[SC_GOSPEL].timer!=-1 && - sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 8) - speed = speed*125/100; - if(sc_data[SC_JOINTBEAT].timer!=-1) { - if (sc_data[SC_JOINTBEAT].val2 == 1) - speed = speed*150/100; - else if (sc_data[SC_JOINTBEAT].val2 == 3) - speed = speed*130/100; - } - } - if(speed < 1) speed = 1; - return speed; - } - - return 1000; -} -/*========================================== - * 対象のaDelay(攻撃時ディレイ)を返す(汎用) - * aDelayは小さいほうが攻撃速度が速い - *------------------------------------------ - */ -int status_get_adelay(struct block_list *bl) -{ - nullpo_retr(4000, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return (((struct map_session_data *)bl)->aspd<<1); - else { - struct status_change *sc_data=status_get_sc_data(bl); - int adelay=4000,aspd_rate = 100,i; - if(bl->type==BL_MOB && (struct mob_data *)bl) - adelay = mob_db[((struct mob_data *)bl)->class_].adelay; - else if(bl->type==BL_PET && (struct pet_data *)bl) - adelay = mob_db[((struct pet_data *)bl)->class_].adelay; - - if(sc_data) { - //ツーハンドクイッケン使用時でクァグマイアでも私を忘れないで…でもない時は3割減算 - if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ - aspd_rate -= 30; - //アドレナリンラッシュ使用時でツーハンドクイッケンでもクァグマイアでも私を忘れないで…でもない時は - if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 && - sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // アドレナリンラッシュ - //使用者とパーティメンバーで格差が出る設定でなければ3割減算 - if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty) - aspd_rate -= 30; - //そうでなければ2.5割減算 - else - aspd_rate -= 25; - } - //スピアクィッケン時は減算 - if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 && - sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // スピアクィッケン - aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2; - //夕日のアサシンクロス時は減算 - if(sc_data[SC_ASSNCROS].timer!=-1 && // 夕陽のアサシンクロス - sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 && - sc_data[SC_DONTFORGETME].timer == -1) - aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3; - //私を忘れないで…時は加算 - if(sc_data[SC_DONTFORGETME].timer!=-1) // 私を忘れないで - aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16); - //金剛時25%加算 - if(sc_data[SC_STEELBODY].timer!=-1) // 金剛 - aspd_rate += 25; - //増速ポーション使用時は減算 - if( sc_data[i=SC_SPEEDPOTION3].timer!=-1 || sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1) - aspd_rate -= sc_data[i].val2; - //ディフェンダー時は加算 - if(sc_data[SC_DEFENDER].timer != -1) - aspd_rate += (25 - sc_data[SC_DEFENDER].val1*5); - //adelay += (1100 - sc_data[SC_DEFENDER].val1*100); - if(sc_data[SC_GOSPEL].timer!=-1 && - sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 8) - aspd_rate = aspd_rate*125/100; - if(sc_data[SC_JOINTBEAT].timer!=-1) { - if (sc_data[SC_JOINTBEAT].val2 == 2) - aspd_rate = aspd_rate*125/100; - else if (sc_data[SC_JOINTBEAT].val2 == 3) - aspd_rate = aspd_rate*110/100; - } - } - if(aspd_rate != 100) - adelay = adelay*aspd_rate/100; - if(adelay < battle_config.monster_max_aspd<<1) adelay = battle_config.monster_max_aspd<<1; - return adelay; - } - return 4000; -} -int status_get_amotion(struct block_list *bl) -{ - nullpo_retr(2000, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->amotion; - else { - struct status_change *sc_data=status_get_sc_data(bl); - int amotion=2000,aspd_rate = 100,i; - if(bl->type==BL_MOB && (struct mob_data *)bl) - amotion = mob_db[((struct mob_data *)bl)->class_].amotion; - else if(bl->type==BL_PET && (struct pet_data *)bl) - amotion = mob_db[((struct pet_data *)bl)->class_].amotion; - - if(sc_data) { - if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ - aspd_rate -= 30; - if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 && - sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // アドレナリンラッシュ - if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty) - aspd_rate -= 30; - else - aspd_rate -= 25; - } - if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 && - sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // スピアクィッケン - aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2; - if(sc_data[SC_ASSNCROS].timer!=-1 && // 夕陽のアサシンクロス - sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 && - sc_data[SC_DONTFORGETME].timer == -1) - aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3; - if(sc_data[SC_DONTFORGETME].timer!=-1) // 私を忘れないで - aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16); - if(sc_data[SC_STEELBODY].timer!=-1) // 金剛 - aspd_rate += 25; - if( sc_data[i=SC_SPEEDPOTION3].timer!=-1 || sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1) - aspd_rate -= sc_data[i].val2; - if(sc_data[SC_DEFENDER].timer != -1) - aspd_rate += (25 - sc_data[SC_DEFENDER].val1*5); - //amotion += (550 - sc_data[SC_DEFENDER].val1*50); - } - if(aspd_rate != 100) - amotion = amotion*aspd_rate/100; - if(amotion < battle_config.monster_max_aspd) amotion = battle_config.monster_max_aspd; - return amotion; - } - return 2000; -} -int status_get_dmotion(struct block_list *bl) -{ - int ret; - struct status_change *sc_data; - - nullpo_retr(0, bl); - sc_data = status_get_sc_data(bl); - if(bl->type==BL_MOB && (struct mob_data *)bl){ - ret=mob_db[((struct mob_data *)bl)->class_].dmotion; - if(battle_config.monster_damage_delay_rate != 100) - ret = ret*battle_config.monster_damage_delay_rate/400; - } - else if(bl->type==BL_PC && (struct map_session_data *)bl){ - ret=((struct map_session_data *)bl)->dmotion; - if(battle_config.pc_damage_delay_rate != 100) - ret = ret*battle_config.pc_damage_delay_rate/400; - } - else if(bl->type==BL_PET && (struct pet_data *)bl) - ret=mob_db[((struct pet_data *)bl)->class_].dmotion; - else - return 2000; - - if((sc_data && (sc_data[SC_ENDURE].timer!=-1 || sc_data[SC_BERSERK].timer!=-1)) || - (bl->type == BL_PC && ((struct map_session_data *)bl)->special_state.infinite_endure)) - ret=0; - - return ret; -} -int status_get_element(struct block_list *bl) -{ - int ret = 20; - struct status_change *sc_data; - - nullpo_retr(ret, bl); - sc_data = status_get_sc_data(bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) // 10の位=Lv*2、1の位=属性 - ret=((struct mob_data *)bl)->def_ele; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - ret=20+((struct map_session_data *)bl)->def_ele; // 防御属性Lv1 - else if(bl->type==BL_PET && (struct pet_data *)bl) - ret = mob_db[((struct pet_data *)bl)->class_].element; - - if(sc_data) { - if( sc_data[SC_BENEDICTIO].timer!=-1 ) // 聖体降福 - ret=26; - if( sc_data[SC_FREEZE].timer!=-1 ) // 凍結 - ret=21; - if( sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) - ret=22; - } - - return ret; -} - -int status_get_attack_element(struct block_list *bl) -{ - int ret = 0; - struct status_change *sc_data=status_get_sc_data(bl); - - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - ret=0; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - ret=((struct map_session_data *)bl)->atk_ele; - else if(bl->type==BL_PET && (struct pet_data *)bl) - ret=0; - - if(sc_data) { - if( sc_data[SC_FROSTWEAPON].timer!=-1) // フロストウェポン - ret=1; - if( sc_data[SC_SEISMICWEAPON].timer!=-1) // サイズミックウェポン - ret=2; - if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // フレームランチャー - ret=3; - if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ライトニングローダー - ret=4; - if( sc_data[SC_ENCPOISON].timer!=-1) // エンチャントポイズン - ret=5; - if( sc_data[SC_ASPERSIO].timer!=-1) // アスペルシオ - ret=6; - } - - return ret; -} -int status_get_attack_element2(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) { - int ret = ((struct map_session_data *)bl)->atk_ele_; - struct status_change *sc_data = ((struct map_session_data *)bl)->sc_data; - - if(sc_data) { - if( sc_data[SC_FROSTWEAPON].timer!=-1) // フロストウェポン - ret=1; - if( sc_data[SC_SEISMICWEAPON].timer!=-1) // サイズミックウェポン - ret=2; - if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // フレームランチャー - ret=3; - if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ライトニングローダー - ret=4; - if( sc_data[SC_ENCPOISON].timer!=-1) // エンチャントポイズン - ret=5; - if( sc_data[SC_ASPERSIO].timer!=-1) // アスペルシオ - ret=6; - } - return ret; - } - return 0; -} -int status_get_party_id(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->status.party_id; - else if(bl->type==BL_MOB && (struct mob_data *)bl){ - struct mob_data *md=(struct mob_data *)bl; - if( md->master_id>0 ) - return -md->master_id; - return -md->bl.id; - } - else if(bl->type==BL_SKILL && (struct skill_unit *)bl) - return ((struct skill_unit *)bl)->group->party_id; - else - return 0; -} -int status_get_guild_id(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data *)bl)->status.guild_id; - else if(bl->type==BL_MOB && (struct mob_data *)bl) - return ((struct mob_data *)bl)->class_; - else if(bl->type==BL_SKILL && (struct skill_unit *)bl) - return ((struct skill_unit *)bl)->group->guild_id; - else - return 0; -} -int status_get_race(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return mob_db[((struct mob_data *)bl)->class_].race; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return 7; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return mob_db[((struct pet_data *)bl)->class_].race; - else - return 0; -} -int status_get_size(struct block_list *bl) -{ - nullpo_retr(1, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return mob_db[((struct mob_data *)bl)->class_].size; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return mob_db[((struct pet_data *)bl)->class_].size; - else if(bl->type==BL_PC) { - struct map_session_data *sd = (struct map_session_data *)bl; - //if (pc_isriding(sd)) // fact or rumour? - // return 2; - if (pc_calc_upper(sd->status.class_) == 2) - return 0; - return 1; - } else - return 1; -} -int status_get_mode(struct block_list *bl) -{ - nullpo_retr(0x01, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return mob_db[((struct mob_data *)bl)->class_].mode; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return mob_db[((struct pet_data *)bl)->class_].mode; - else - return 0x01; // とりあえず動くということで1 -} - -int status_get_mexp(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return mob_db[((struct mob_data *)bl)->class_].mexp; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return mob_db[((struct pet_data *)bl)->class_].mexp; - else - return 0; -} -int status_get_race2(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type == BL_MOB && (struct mob_data *)bl) - return mob_db[((struct mob_data *)bl)->class_].race2; - else if(bl->type==BL_PET && (struct pet_data *)bl) - return mob_db[((struct pet_data *)bl)->class_].race2; - else - return 0; -} -int status_isdead(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type == BL_MOB && (struct mob_data *)bl) - return ((struct mob_data *)bl)->state.state == MS_DEAD; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return pc_isdead((struct map_session_data *)bl); - else - return 0; -} - -// StatusChange系の所得 -struct status_change *status_get_sc_data(struct block_list *bl) -{ - nullpo_retr(NULL, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return ((struct mob_data*)bl)->sc_data; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return ((struct map_session_data*)bl)->sc_data; - return NULL; -} -short *status_get_sc_count(struct block_list *bl) -{ - nullpo_retr(NULL, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return &((struct mob_data*)bl)->sc_count; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return &((struct map_session_data*)bl)->sc_count; - return NULL; -} -short *status_get_opt1(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return &((struct mob_data*)bl)->opt1; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return &((struct map_session_data*)bl)->opt1; - else if(bl->type==BL_NPC && (struct npc_data *)bl) - return &((struct npc_data*)bl)->opt1; - return 0; -} -short *status_get_opt2(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return &((struct mob_data*)bl)->opt2; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return &((struct map_session_data*)bl)->opt2; - else if(bl->type==BL_NPC && (struct npc_data *)bl) - return &((struct npc_data*)bl)->opt2; - return 0; -} -short *status_get_opt3(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return &((struct mob_data*)bl)->opt3; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return &((struct map_session_data*)bl)->opt3; - else if(bl->type==BL_NPC && (struct npc_data *)bl) - return &((struct npc_data*)bl)->opt3; - return 0; -} -short *status_get_option(struct block_list *bl) -{ - nullpo_retr(0, bl); - if(bl->type==BL_MOB && (struct mob_data *)bl) - return &((struct mob_data*)bl)->option; - else if(bl->type==BL_PC && (struct map_session_data *)bl) - return &((struct map_session_data*)bl)->status.option; - else if(bl->type==BL_NPC && (struct npc_data *)bl) - return &((struct npc_data*)bl)->option; - return 0; -} - -int status_get_sc_def(struct block_list *bl, int type) -{ - int sc_def; - nullpo_retr(0, bl); - - switch (type) - { - case SP_MDEF1: // mdef - sc_def = 100 - (3 + status_get_mdef(bl) + status_get_luk(bl)/3); - break; - case SP_MDEF2: // int - sc_def = 100 - (3 + status_get_int(bl) + status_get_luk(bl)/3); - break; - case SP_DEF1: // def - sc_def = 100 - (3 + status_get_def(bl) + status_get_luk(bl)/3); - break; - case SP_DEF2: // vit - sc_def = 100 - (3 + status_get_vit(bl) + status_get_luk(bl)/3); - break; - case SP_LUK: // luck - sc_def = 100 - (3 + status_get_luk(bl)); - break; - - case SC_STONE: - case SC_FREEZE: - sc_def = 100 - (3 + status_get_mdef(bl) + status_get_luk(bl)/3); - break; - case SC_STAN: - case SC_POISON: - case SC_SILENCE: - sc_def = 100 - (3 + status_get_vit(bl) + status_get_luk(bl)/3); - break; - case SC_SLEEP: - case SC_CONFUSION: - case SC_BLIND: - sc_def = 100 - (3 + status_get_int(bl) + status_get_luk(bl)/3); - break; - case SC_CURSE: - sc_def = 100 - (3 + status_get_luk(bl)); - break; - - default: - sc_def = 100; - break; - } - - if(bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)bl; - if (md && md->class_ == 1288) - return 0; - if (sc_def < 50) - sc_def = 50; - } else if(bl->type == BL_PC) { - struct status_change* sc_data = status_get_sc_data(bl); - if (sc_data && sc_data[SC_GOSPEL].timer != -1 && - sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 3) - sc_def -= 25; - } - - return (sc_def < 0) ? 0 : sc_def; -} - -/*========================================== - * ステータス異常開始 - *------------------------------------------ - */ -int status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag) -{ - struct map_session_data *sd = NULL; - struct status_change* sc_data; - short *sc_count, *option, *opt1, *opt2, *opt3; - int opt_flag = 0, calc_flag = 0,updateflag = 0, save_flag = 0, race, mode, elem, undead_flag; - int scdef = 0; - int type2 = type; - - nullpo_retr(0, bl); - if(bl->type == BL_SKILL) - return 0; - if(bl->type == BL_MOB) - if (status_isdead(bl)) return 0; - - nullpo_retr(0, sc_data=status_get_sc_data(bl)); - nullpo_retr(0, sc_count=status_get_sc_count(bl)); - nullpo_retr(0, option=status_get_option(bl)); - nullpo_retr(0, opt1=status_get_opt1(bl)); - nullpo_retr(0, opt2=status_get_opt2(bl)); - nullpo_retr(0, opt3=status_get_opt3(bl)); - - - race=status_get_race(bl); - mode=status_get_mode(bl); - elem=status_get_elem_type(bl); - undead_flag=battle_check_undead(race,elem); - - if(type == SC_AETERNA && (sc_data[SC_STONE].timer != -1 || sc_data[SC_FREEZE].timer != -1) ) - return 0; - - switch(type){ - case SC_STONE: - case SC_FREEZE: - scdef=3+status_get_mdef(bl)+status_get_luk(bl)/3; - break; - case SC_STAN: - case SC_SILENCE: - case SC_POISON: - case SC_DPOISON: - scdef=3+status_get_vit(bl)+status_get_luk(bl)/3; - break; - case SC_SLEEP: - case SC_BLIND: - scdef=3+status_get_int(bl)+status_get_luk(bl)/3; - break; - case SC_CURSE: - scdef=3+status_get_luk(bl); - break; - -// case SC_CONFUSION: - default: - scdef=0; - } - if(scdef>=100) - return 0; - if(bl->type==BL_PC){ - sd=(struct map_session_data *)bl; - if( sd && type == SC_ADRENALINE && !(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon))) - return 0; - - if(SC_STONE<=type && type<=SC_BLIND){ /* カ?ドによる耐性 */ - if( sd && sd->reseff[type-SC_STONE] > 0 && rand()%10000<sd->reseff[type-SC_STONE]){ - if(battle_config.battle_log) - printf("PC %d skill_sc_start: cardによる異常耐性?動\n",sd->bl.id); - return 0; - } - } - } - else if(bl->type == BL_MOB) { - } - else { - if(battle_config.error_log) - printf("status_change_start: neither MOB nor PC !\n"); - return 0; - } - - if(type==SC_FREEZE && undead_flag && !(flag&1)) - return 0; - - if (type==SC_BLESSING && (bl->type==BL_PC || (!undead_flag && race!=6))) { - if (sc_data[SC_CURSE].timer!=-1) - status_change_end(bl,SC_CURSE,-1); - if (sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) - status_change_end(bl,SC_STONE,-1); - } - - if((type == SC_ADRENALINE || type == SC_WEAPONPERFECTION || type == SC_OVERTHRUST) && - sc_data[type].timer != -1 && sc_data[type].val2 && !val2) - return 0; - - if(mode & 0x20 && (type==SC_STONE || type==SC_FREEZE || - type==SC_STAN || type==SC_SLEEP || type==SC_SILENCE || type==SC_QUAGMIRE || type == SC_DECREASEAGI || type == SC_SIGNUMCRUCIS || type == SC_PROVOKE || - (type == SC_BLESSING && (undead_flag || race == 6))) && !(flag&1)){ - /* ボスには?かない(ただしカ?ドによる?果は適用される) */ - return 0; - } - if(type==SC_FREEZE || type==SC_STAN || type==SC_SLEEP) - battle_stopwalking(bl,1); - - if(sc_data[type].timer != -1){ /* すでに同じ異常になっている場合タイマ解除 */ - if(sc_data[type].val1 > val1 && type != SC_COMBO && type != SC_DANCING && type != SC_DEVOTION && - type != SC_SPEEDPOTION0 && type != SC_SPEEDPOTION1 && type != SC_SPEEDPOTION2 && type != SC_SPEEDPOTION3 - && type != SC_ATKPOT && type != SC_MATKPOT) // added atk and matk potions [Valaris] - return 0; - - if ((type >=SC_STAN && type <= SC_BLIND) || type == SC_DPOISON) - return 0;/* ?ぎ足しができない?態異常である時は?態異常を行わない */ - - (*sc_count)--; - delete_timer(sc_data[type].timer, status_change_timer); - sc_data[type].timer = -1; - } - - // クアグマイア/私を忘れないで中は無効なスキル - if ((sc_data[SC_QUAGMIRE].timer!=-1 || sc_data[SC_DONTFORGETME].timer!=-1) && - (type==SC_CONCENTRATE || type==SC_INCREASEAGI || - type==SC_TWOHANDQUICKEN || type==SC_SPEARSQUICKEN || - type==SC_ADRENALINE || type==SC_LOUD || type==SC_TRUESIGHT || - type==SC_WINDWALK || type==SC_CARTBOOST || type==SC_ASSNCROS)) - return 0; - - switch(type){ /* 異常の種類ごとの?理 */ - case SC_PROVOKE: /* プロボック */ - calc_flag = 1; - if(tick <= 0) tick = 1000; /* (オ?トバ?サ?ク) */ - break; - case SC_ENDURE: /* インデュア */ - if(tick <= 0) tick = 1000 * 60; - calc_flag = 1; // for updating mdef -#ifdef TWILIGHT - val2 = 40; // [Celest] -#else - val2 = 7; // [Celest] -#endif - break; - case SC_AUTOBERSERK: - { - tick = 60*1000; - if (bl->type == BL_PC && sd->status.hp<sd->status.max_hp>>2 && - (sc_data[SC_PROVOKE].timer==-1 || sc_data[SC_PROVOKE].val2==0)) - status_change_start(bl,SC_PROVOKE,10,1,0,0,0,0); - } - break; - - case SC_CONCENTRATE: /* 集中力向上 */ - case SC_BLESSING: /* ブレッシング */ - case SC_ANGELUS: /* アンゼルス */ - calc_flag = 1; - break; - - case SC_INCREASEAGI: /* 速度上昇 */ - calc_flag = 1; - if(sc_data[SC_DECREASEAGI].timer!=-1 ) - status_change_end(bl,SC_DECREASEAGI,-1); - // the effect will still remain [celest] -// if(sc_data[SC_WINDWALK].timer!=-1 ) /* ウインドウォ?ク */ -// status_change_end(bl,SC_WINDWALK,-1); - break; - case SC_DECREASEAGI: /* 速度減少 */ - if (bl->type == BL_PC) // Celest - tick>>=1; - calc_flag = 1; - if(sc_data[SC_INCREASEAGI].timer!=-1 ) - status_change_end(bl,SC_INCREASEAGI,-1); - if(sc_data[SC_ADRENALINE].timer!=-1 ) - status_change_end(bl,SC_ADRENALINE,-1); - if(sc_data[SC_SPEARSQUICKEN].timer!=-1 ) - status_change_end(bl,SC_SPEARSQUICKEN,-1); - if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 ) - status_change_end(bl,SC_TWOHANDQUICKEN,-1); - break; - case SC_SIGNUMCRUCIS: /* シグナムクルシス */ - calc_flag = 1; -// val2 = 14 + val1; - val2 = 10 + val1*2; - tick = 600*1000; - clif_emotion(bl,4); - break; - case SC_SLOWPOISON: - if (sc_data[SC_POISON].timer == -1 && sc_data[SC_DPOISON].timer == -1) - return 0; - break; - case SC_TWOHANDQUICKEN: /* 2HQ */ - if(sc_data[SC_DECREASEAGI].timer!=-1) - return 0; - *opt3 |= 1; - calc_flag = 1; - break; - case SC_ADRENALINE: /* アドレナリンラッシュ */ - if(sc_data[SC_DECREASEAGI].timer!=-1) - return 0; - if(bl->type == BL_PC) - if(pc_checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - calc_flag = 1; - break; - case SC_WEAPONPERFECTION: /* ウェポンパ?フェクション */ - if(bl->type == BL_PC) - if(pc_checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - break; - case SC_OVERTHRUST: /* オ?バ?スラスト */ - if(bl->type == BL_PC) - if(pc_checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - *opt3 |= 2; - break; - case SC_MAXIMIZEPOWER: /* マキシマイズパワ?(SPが1減る時間,val2にも) */ - if(bl->type == BL_PC) - val2 = tick; - else - tick = 5000*val1; - break; - case SC_ENCPOISON: /* エンチャントポイズン */ - calc_flag = 1; - val2=(((val1 - 1) / 2) + 3)*100; /* 毒付?確率 */ - skill_enchant_elemental_end(bl,SC_ENCPOISON); - break; - case SC_EDP: // [Celest] - val2 = val1 + 2; /* 猛毒付?確率(%) */ - calc_flag = 1; - break; - case SC_POISONREACT: /* ポイズンリアクト */ - val2=val1/2 + val1%2; // [Celest] - break; - case SC_IMPOSITIO: /* インポシティオマヌス */ - calc_flag = 1; - break; - case SC_ASPERSIO: /* アスペルシオ */ - skill_enchant_elemental_end(bl,SC_ASPERSIO); - break; - case SC_SUFFRAGIUM: /* サフラギム */ - case SC_BENEDICTIO: /* 聖? */ - case SC_MAGNIFICAT: /* マグニフィカ?ト */ - case SC_AETERNA: /* エ?テルナ */ - break; - case SC_ENERGYCOAT: /* エナジ?コ?ト */ - *opt3 |= 4; - break; - case SC_MAGICROD: - val2 = val1*20; - break; - case SC_KYRIE: /* キリエエレイソン */ - val2 = status_get_max_hp(bl) * (val1 * 2 + 10) / 100;/* 耐久度 */ - val3 = (val1 / 2 + 5); /* 回? */ -// -- moonsoul (added to undo assumptio status if target has it) - if(sc_data[SC_ASSUMPTIO].timer!=-1 ) - status_change_end(bl,SC_ASSUMPTIO,-1); - break; - case SC_MINDBREAKER: - calc_flag = 1; - if(tick <= 0) tick = 1000; /* (オ?トバ?サ?ク) */ - case SC_GLORIA: /* グロリア */ - calc_flag = 1; - break; - case SC_LOUD: /* ラウドボイス */ - calc_flag = 1; - break; - case SC_TRICKDEAD: /* 死んだふり */ - if (bl->type == BL_PC) { - pc_stopattack((struct map_session_data *)sd); - } - break; - case SC_QUAGMIRE: /* クァグマイア */ - calc_flag = 1; - if(sc_data[SC_CONCENTRATE].timer!=-1 ) /* 集中力向上解除 */ - status_change_end(bl,SC_CONCENTRATE,-1); - if(sc_data[SC_INCREASEAGI].timer!=-1 ) /* 速度上昇解除 */ - status_change_end(bl,SC_INCREASEAGI,-1); - if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 ) - status_change_end(bl,SC_TWOHANDQUICKEN,-1); - if(sc_data[SC_SPEARSQUICKEN].timer!=-1 ) - status_change_end(bl,SC_SPEARSQUICKEN,-1); - if(sc_data[SC_ADRENALINE].timer!=-1 ) - status_change_end(bl,SC_ADRENALINE,-1); - if(sc_data[SC_LOUD].timer!=-1 ) - status_change_end(bl,SC_LOUD,-1); - if(sc_data[SC_TRUESIGHT].timer!=-1 ) /* トゥル?サイト */ - status_change_end(bl,SC_TRUESIGHT,-1); - if(sc_data[SC_WINDWALK].timer!=-1 ) /* ウインドウォ?ク */ - status_change_end(bl,SC_WINDWALK,-1); - if(sc_data[SC_CARTBOOST].timer!=-1 ) /* カ?トブ?スト */ - status_change_end(bl,SC_CARTBOOST,-1); - break; - case SC_MAGICPOWER: - calc_flag = 1; - val2 = 1; - break; - case SC_SACRIFICE: - val2 = 5; - break; - case SC_FLAMELAUNCHER: /* フレ?ムランチャ? */ - skill_enchant_elemental_end(bl,SC_FLAMELAUNCHER); - break; - case SC_FROSTWEAPON: /* フロストウェポン */ - skill_enchant_elemental_end(bl,SC_FROSTWEAPON); - break; - case SC_LIGHTNINGLOADER: /* ライトニングロ?ダ? */ - skill_enchant_elemental_end(bl,SC_LIGHTNINGLOADER); - break; - case SC_SEISMICWEAPON: /* サイズミックウェポン */ - skill_enchant_elemental_end(bl,SC_SEISMICWEAPON); - break; - case SC_DEVOTION: /* ディボ?ション */ - calc_flag = 1; - break; - case SC_PROVIDENCE: /* プロヴィデンス */ - calc_flag = 1; - val2=val1*5; - break; - case SC_REFLECTSHIELD: - val2=10+val1*3; - break; - case SC_STRIPWEAPON: - if (val2==0) val2=90; - break; - case SC_STRIPSHIELD: - if (val2==0) val2=85; - break; - case SC_STRIPARMOR: - case SC_STRIPHELM: - case SC_CP_WEAPON: - case SC_CP_SHIELD: - case SC_CP_ARMOR: - case SC_CP_HELM: - break; - - case SC_AUTOSPELL: /* オ?トスペル */ - val4 = 5 + val1*2; - break; - - case SC_VOLCANO: - calc_flag = 1; - val3 = val1*10; - //val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) ); - break; - case SC_DELUGE: - calc_flag = 1; - //val3 = val1>=5?15: (val1==4?14: (val1==3?12: ( val1==2?9:5 ) ) ); - //val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) ); - if (sc_data[SC_FOGWALL].timer != -1 && sc_data[SC_BLIND].timer != -1) - status_change_end(bl,SC_BLIND,-1); - break; - case SC_VIOLENTGALE: - calc_flag = 1; - val3 = val1*3; - //val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) ); - break; - - case SC_SPEARSQUICKEN: /* スピアクイッケン */ - calc_flag = 1; - val2 = 20+val1; - *opt3 |= 1; - break; - case SC_COMBO: - break; - case SC_BLADESTOP_WAIT: /* 白刃取り(待ち) */ - break; - case SC_BLADESTOP: /* 白刃取り */ - if(val2==2) clif_bladestop((struct block_list *)val3,(struct block_list *)val4,1); - *opt3 |= 32; - break; - - case SC_LULLABY: /* 子守唄 */ - val2 = 11; - break; - case SC_RICHMANKIM: - break; - case SC_ETERNALCHAOS: /* エタ?ナルカオス */ - calc_flag = 1; - break; - case SC_DRUMBATTLE: /* ?太鼓の響き */ - calc_flag = 1; - val2 = (val1+1)*25; - val3 = (val1+1)*2; - break; - case SC_NIBELUNGEN: /* ニ?ベルングの指輪 */ - calc_flag = 1; - //val2 = (val1+2)*50; - val3 = (val1+2)*25; - break; - case SC_ROKISWEIL: /* ロキの叫び */ - break; - case SC_INTOABYSS: /* 深淵の中に */ - break; - case SC_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - calc_flag = 1; - val2 = 55 + val1*5; - val3 = val1*10; - break; - case SC_DISSONANCE: /* 不協和音 */ - val2 = 10; - break; - case SC_WHISTLE: /* 口笛 */ - calc_flag = 1; - break; - case SC_ASSNCROS: /* 夕陽のアサシンクロス */ - calc_flag = 1; - break; - case SC_POEMBRAGI: /* ブラギの詩 */ - break; - case SC_APPLEIDUN: /* イドゥンの林檎 */ - calc_flag = 1; - break; - case SC_UGLYDANCE: /* 自分勝手なダンス */ - val2 = 10; - break; - case SC_HUMMING: /* ハミング */ - calc_flag = 1; - break; - case SC_DONTFORGETME: /* 私を忘れないで */ - calc_flag = 1; - if(sc_data[SC_INCREASEAGI].timer!=-1 ) /* 速度上昇解除 */ - status_change_end(bl,SC_INCREASEAGI,-1); - if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 ) - status_change_end(bl,SC_TWOHANDQUICKEN,-1); - if(sc_data[SC_SPEARSQUICKEN].timer!=-1 ) - status_change_end(bl,SC_SPEARSQUICKEN,-1); - if(sc_data[SC_ADRENALINE].timer!=-1 ) - status_change_end(bl,SC_ADRENALINE,-1); - if(sc_data[SC_ASSNCROS].timer!=-1 ) - status_change_end(bl,SC_ASSNCROS,-1); - if(sc_data[SC_TRUESIGHT].timer!=-1 ) /* トゥル?サイト */ - status_change_end(bl,SC_TRUESIGHT,-1); - if(sc_data[SC_WINDWALK].timer!=-1 ) /* ウインドウォ?ク */ - status_change_end(bl,SC_WINDWALK,-1); - if(sc_data[SC_CARTBOOST].timer!=-1 ) /* カ?トブ?スト */ - status_change_end(bl,SC_CARTBOOST,-1); - break; - case SC_FORTUNE: /* 幸運のキス */ - calc_flag = 1; - break; - case SC_SERVICE4U: /* サ?ビスフォ?ユ? */ - calc_flag = 1; - break; - case SC_MOONLIT: - val2 = bl->id; - break; - case SC_DANCING: /* ダンス/演奏中 */ - calc_flag = 1; - val3= tick / 1000; - tick = 1000; - break; - - case SC_EXPLOSIONSPIRITS: // 爆裂波動 - calc_flag = 1; - val2 = 75 + 25*val1; - *opt3 |= 8; - break; - case SC_STEELBODY: // 金剛 - calc_flag = 1; - *opt3 |= 16; - break; - case SC_EXTREMITYFIST: /* 阿修羅覇凰拳 */ - break; - case SC_AUTOCOUNTER: - val3 = val4 = 0; - break; - - case SC_SPEEDPOTION0: /* ?速ポ?ション */ - case SC_SPEEDPOTION1: - case SC_SPEEDPOTION2: - case SC_SPEEDPOTION3: - calc_flag = 1; - tick = 1000 * tick; - val2 = 5*(2+type-SC_SPEEDPOTION0); - break; - - /* atk & matk potions [Valaris] */ - case SC_ATKPOT: - case SC_MATKPOT: - calc_flag = 1; - tick = 1000 * tick; - break; - case SC_WEDDING: //結婚用(結婚衣裳になって?くのが?いとか) - { - time_t timer; - - calc_flag = 1; - tick = 10000; - if(!val2) - val2 = time(&timer); - } - break; - case SC_NOCHAT: //チャット禁止?態 - { - time_t timer; - - if(!battle_config.muting_players) - break; - - tick = 60000; - if(!val2) - val2 = time(&timer); - updateflag = SP_MANNER; - save_flag = 1; // celest - } - break; - case SC_SELFDESTRUCTION: //自爆 - clif_skillcasting(bl,bl->id, bl->id,0,0,331,skill_get_time(val2,val1)); - val3 = tick / 1000; - tick = 1000; - break; - - /* option1 */ - case SC_STONE: /* 石化 */ - if(!(flag&2)) { - int sc_def = status_get_mdef(bl)*200; - tick = tick - sc_def; - } - val3 = tick/1000; - if(val3 < 1) val3 = 1; - tick = 5000; - val2 = 1; - break; - case SC_SLEEP: /* 睡眠 */ - if(!(flag&2)) { -// int sc_def = 100 - (status_get_int(bl) + status_get_luk(bl)/3); -// tick = tick * sc_def / 100; -// if(tick < 1000) tick = 1000; - tick = 30000;//睡眠はステ?タス耐性に?わらず30秒 - } - break; - case SC_FREEZE: /* 凍結 */ - if(!(flag&2)) { - int sc_def = 100 - status_get_mdef(bl); - tick = tick * sc_def / 100; - } - break; - case SC_STAN: /* スタン(val2にミリ秒セット) */ - if(!(flag&2)) { - int sc_def = status_get_sc_def_vit(bl); - tick = tick * sc_def / 100; - } - break; - - /* option2 */ - case SC_DPOISON: /* 猛毒 */ - { - int mhp = status_get_max_hp(bl); - int hp = status_get_hp(bl); - // MHP?1/4???????? - if (hp > mhp>>2) { - if(bl->type == BL_PC) { - int diff = mhp*10/100; - if (hp - diff < mhp>>2) - hp = hp - (mhp>>2); - pc_heal((struct map_session_data *)bl, -hp, 0); - } else if(bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data *)bl; - hp -= mhp*15/100; - if (hp > mhp>>2) - md->hp = hp; - else - md->hp = mhp>>2; - } - } - } // fall through - case SC_POISON: /* 毒 */ - calc_flag = 1; - if(!(flag&2)) { - int sc_def = 100 - (status_get_vit(bl) + status_get_luk(bl)/5); - tick = tick * sc_def / 100; - } - val3 = tick/1000; - if(val3 < 1) val3 = 1; - tick = 1000; - break; - case SC_SILENCE: /* 沈?(レックスデビ?ナ) */ - if (sc_data && sc_data[SC_GOSPEL].timer!=-1) { - skill_delunitgroup((struct skill_unit_group *)sc_data[SC_GOSPEL].val3); - status_change_end(bl,SC_GOSPEL,-1); - break; - } - if(!(flag&2)) { - int sc_def = 100 - status_get_vit(bl); - tick = tick * sc_def / 100; - } - break; - case SC_CONFUSION: - val2 = tick; - tick = 100; - clif_emotion(bl,1); - if (sd) { - pc_stop_walking (sd, 0); - } - break; - case SC_BLIND: /* 暗? */ - calc_flag = 1; - if(!(flag&2)) { - int sc_def = status_get_lv(bl)/10 + status_get_int(bl)/15; - tick = 30000 - sc_def; - } - break; - case SC_CURSE: - calc_flag = 1; - if(!(flag&2)) { - int sc_def = 100 - status_get_vit(bl); - tick = tick * sc_def / 100; - } - break; - - /* option */ - case SC_HIDING: /* ハイディング */ - calc_flag = 1; - if(bl->type == BL_PC) { - val2 = tick / 1000; /* 持?時間 */ - tick = 1000; - } - break; - case SC_CHASEWALK: - case SC_CLOAKING: /* クロ?キング */ - if(bl->type == BL_PC) { - calc_flag = 1; // [Celest] - val2 = tick; - val3 = type==SC_CLOAKING ? 130-val1*3 : 135-val1*5; - } - else - tick = 5000*val1; - break; - case SC_SIGHT: /* サイト/ルアフ */ - case SC_RUWACH: - val2 = tick/250; - tick = 10; - break; - - /* セ?フティウォ?ル、ニュ?マ */ - case SC_SAFETYWALL: case SC_PNEUMA: - tick=((struct skill_unit *)val2)->group->limit; - break; - - /* アンクル */ - case SC_ANKLE: - break; - - /* スキルじゃない/時間に?係しない */ - case SC_RIDING: - calc_flag = 1; - tick = 600*1000; - break; - case SC_FALCON: - case SC_WEIGHT50: - case SC_WEIGHT90: - case SC_BROKNWEAPON: - case SC_BROKNARMOR: - tick=600*1000; - break; - - case SC_AUTOGUARD: - { - int i,t; - for(i=val2=0;i<val1;i++) { - t = 5-(i>>1); - val2 += (t < 0)? 1:t; - } - } - break; - - case SC_DEFENDER: - calc_flag = 1; - val2 = 5 + val1*15; - break; - - case SC_KEEPING: - case SC_BARRIER: - calc_flag = 1; - - case SC_HALLUCINATION: - break; - - case SC_CONCENTRATION: /* コンセントレ?ション */ - *opt3 |= 1; - calc_flag = 1; - break; - - case SC_TENSIONRELAX: /* テンションリラックス */ - if(bl->type == BL_PC) { - tick = 10000; - } else return 0; - break; - - case SC_AURABLADE: /* オ?ラブレ?ド */ - case SC_PARRYING: /* パリイング */ -// case SC_ASSUMPTIO: /* */ -// case SC_HEADCRUSH: /* ヘッドクラッシュ */ -// case SC_JOINTBEAT: /* ジョイントビ?ト */ -// case SC_MARIONETTE: /* マリオネットコントロ?ル */ - - //とりあえず手?き - break; - -// -- moonsoul (for new upper class related skill status effects) -/* - case SC_AURABLADE: - val2 = val1*10; - break; - case SC_PARRYING: - val2=val1*3; - break; - case SC_CONCENTRATION: - calc_flag=1; - val2=val1*10; - val3=val1*5; - break; - case SC_TENSIONRELAX: -// val2 = 10; -// val3 = 15; - break; - case SC_BERSERK: - calc_flag=1; - break; - case SC_ASSUMPTIO: - if(sc_data[SC_KYRIE].timer!=-1 ) - status_change_end(bl,SC_KYRIE,-1); - break;*/ - - case SC_WINDWALK: /* ウインドウォ?ク */ - calc_flag = 1; - val2 = (val1 / 2); //Flee上昇率 - break; - - case SC_JOINTBEAT: // Random break [DracoRPG] - calc_flag = 1; - val2 = rand()%6 + 1; - if (val2 == 6) status_change_start(bl,SC_BLEEDING,val1,0,0,0,skill_get_time2(type,val1),0); - break; - - case SC_BERSERK: /* バ?サ?ク */ - if(sd){ - sd->status.hp = sd->status.max_hp * 3; - sd->status.sp = 0; - clif_updatestatus(sd,SP_HP); - clif_updatestatus(sd,SP_SP); - clif_status_change(bl,SC_INCREASEAGI,1); /* アイコン表示 */ - sd->canregen_tick = gettick() + 300000; - } - *opt3 |= 128; - tick = 10000; - calc_flag = 1; - break; - - case SC_ASSUMPTIO: /* アスムプティオ */ - if(sc_data[SC_KYRIE].timer!=-1 ) - status_change_end(bl,SC_KYRIE,-1); - break; - *opt3 |= 2048; - break; - - case SC_BASILICA: // [celest] - break; - - case SC_GOSPEL: - if (val4 == BCT_SELF) { // self effect - int i; - if (sd) { - sd->canact_tick += tick; - sd->canmove_tick += tick; - } - val2 = tick; - tick = 1000; - for (i=0; i<=26; i++) { - if(sc_data[i].timer!=-1) - status_change_end(bl,i,-1); - } - for (i=58; i<=62; i++) { - if(sc_data[i].timer!=-1) - status_change_end(bl,i,-1); - } - for (i=132; i<=136; i++) { - if(sc_data[i].timer!=-1) - status_change_end(bl,i,-1); - } - } - break; - - case SC_MARIONETTE: /* マリオネットコントロ?ル */ - case SC_MARIONETTE2: - val2 = tick; - if (!val3) - return 0; - tick = 1000; - calc_flag = 1; - *opt3 |= 1024; - break; - - case SC_MELTDOWN: /* メルトダウン */ - case SC_CARTBOOST: /* カ?トブ?スト */ - case SC_TRUESIGHT: /* トゥル?サイト */ - case SC_SPIDERWEB: /* スパイダ?ウェッブ */ - calc_flag = 1; - break; - - case SC_REJECTSWORD: /* リジェクトソ?ド */ - val2 = 3; //3回攻?を跳ね返す - break; - - case SC_MEMORIZE: /* メモライズ */ - val2 = 5; //回詠唱を1/3にする - break; - - case SC_SPLASHER: /* ベナムスプラッシャ? */ - break; - - case SC_FOGWALL: - break; - - case SC_PRESERVE: - break; - - case SC_BLEEDING: - { - // every 1 vit deducts 1 second - val3 = tick - status_get_vit(bl) * 1000; - // minimum 50 seconds - if (val3 < 50000) - val3 = 50000; - val4 = 10000; - tick = 1000; - } - break; - - case SC_SLOWDOWN: - case SC_SPEEDUP0: - calc_flag = 1; - break; - - case SC_REGENERATION: - val1 = 2; - case SC_BATTLEORDERS: - tick = 60000; // 1 minute - calc_flag = 1; - break; - - case SC_GUILDAURA: - calc_flag = 1; - tick = 1000; - break; - - case SC_BABY: - type2 = _SC_BABY; - break; - - default: - if(battle_config.error_log) - printf("UnknownStatusChange [%d]\n", type); - return 0; - } - - if(bl->type==BL_PC && - (type<SC_SENDMAX || type==SC_PRESERVE || type==SC_BATTLEORDERS || type==SC_BABY)) - clif_status_change(bl,type2,1); /* アイコン表示 */ - - /* optionの?更 */ - switch(type){ - case SC_STONE: - case SC_FREEZE: - case SC_STAN: - case SC_SLEEP: - battle_stopattack(bl); /* 攻?停止 */ - skill_stop_dancing(bl,0); /* 演奏/ダンスの中? */ - { /* 同時に掛からないステ?タス異常を解除 */ - int i; - for(i = SC_STONE; i <= SC_SLEEP; i++){ - if(sc_data[i].timer != -1){ - (*sc_count)--; - delete_timer(sc_data[i].timer, status_change_timer); - sc_data[i].timer = -1; - } - } - } - if(type == SC_STONE) - *opt1 = 6; - else - *opt1 = type - SC_STONE + 1; - opt_flag = 1; - break; - case SC_POISON: - case SC_CURSE: - case SC_SILENCE: - case SC_BLIND: - *opt2 |= 1<<(type-SC_POISON); - opt_flag = 1; - break; - case SC_DPOISON: // 暫定で毒のエフェクトを使用 - *opt2 |= 1; - opt_flag = 1; - break; - case SC_SIGNUMCRUCIS: - *opt2 |= 0x40; - opt_flag = 1; - break; - case SC_HIDING: - case SC_CLOAKING: - battle_stopattack(bl); /* 攻?停止 */ - *option |= ((type==SC_HIDING)?2:4); - opt_flag =1 ; - break; - case SC_CHASEWALK: - battle_stopattack(bl); /* 攻?停止 */ - *option |= 16388; - opt_flag =1 ; - break; - case SC_SIGHT: - *option |= 1; - opt_flag = 1; - break; - case SC_RUWACH: - *option |= 8192; - opt_flag = 1; - break; - case SC_WEDDING: - *option |= 4096; - opt_flag = 1; - } - - if(opt_flag) /* optionの?更 */ - clif_changeoption(bl); - - (*sc_count)++; /* ステ?タス異常の? */ - - sc_data[type].val1 = val1; - sc_data[type].val2 = val2; - sc_data[type].val3 = val3; - sc_data[type].val4 = val4; - /* タイマ?設定 */ - sc_data[type].timer = add_timer( - gettick() + tick, status_change_timer, bl->id, type); - - if(bl->type==BL_PC && calc_flag) - status_calc_pc(sd,0); /* ステ?タス再計算 */ - - if(bl->type==BL_PC && save_flag) - chrif_save(sd); // save the player status - - if(bl->type==BL_PC && updateflag) - clif_updatestatus(sd,updateflag); /* ステ?タスをクライアントに送る */ - - return 0; -} -/*========================================== - * ステータス異常全解除 - *------------------------------------------ - */ -int status_change_clear(struct block_list *bl,int type) -{ - struct status_change* sc_data; - short *sc_count, *option, *opt1, *opt2, *opt3; - int i; - - nullpo_retr(0, bl); - nullpo_retr(0, sc_data = status_get_sc_data(bl)); - nullpo_retr(0, sc_count = status_get_sc_count(bl)); - nullpo_retr(0, option = status_get_option(bl)); - nullpo_retr(0, opt1 = status_get_opt1(bl)); - nullpo_retr(0, opt2 = status_get_opt2(bl)); - nullpo_retr(0, opt3 = status_get_opt3(bl)); - - if (*sc_count == 0) - return 0; - for(i = 0; i < MAX_STATUSCHANGE; i++){ - if(sc_data[i].timer != -1){ /* 異常があるならタイマ?を削除する */ - status_change_end(bl, i, -1); - } - } - *sc_count = 0; - *opt1 = 0; - *opt2 = 0; - *opt3 = 0; - *option &= OPTION_MASK; - - if (night_flag == 1 && type == BL_PC && !map[bl->m].flag.indoors && // by [Yor] - !map[bl->m].flag.indoors && battle_config.night_darkness_level <= 0) // [celest] - *opt2 |= STATE_BLIND; - - if(!type || type&2) - clif_changeoption(bl); - - return 0; -} - -/*========================================== - * ステータス異常終了 - *------------------------------------------ - */ -int status_change_end( struct block_list* bl , int type,int tid ) -{ - struct status_change* sc_data; - int opt_flag=0, calc_flag = 0; - short *sc_count, *option, *opt1, *opt2, *opt3; - int type2 = type; - - nullpo_retr(0, bl); - if(bl->type!=BL_PC && bl->type!=BL_MOB) { - if(battle_config.error_log) - printf("status_change_end: neither MOB nor PC !\n"); - return 0; - } - nullpo_retr(0, sc_data = status_get_sc_data(bl)); - nullpo_retr(0, sc_count = status_get_sc_count(bl)); - nullpo_retr(0, option = status_get_option(bl)); - nullpo_retr(0, opt1 = status_get_opt1(bl)); - nullpo_retr(0, opt2 = status_get_opt2(bl)); - nullpo_retr(0, opt3 = status_get_opt3(bl)); - - if ((*sc_count) > 0 && sc_data[type].timer != -1 && (sc_data[type].timer == tid || tid == -1)) { - - if (tid == -1) // タイマから呼ばれていないならタイマ削除をする - delete_timer(sc_data[type].timer,status_change_timer); - - /* 該?の異常を正常に?す */ - sc_data[type].timer=-1; - (*sc_count)--; - - switch(type){ /* 異常の種類ごとの?理 */ - case SC_PROVOKE: /* プロボック */ - case SC_ENDURE: // celest - case SC_CONCENTRATE: /* 集中力向上 */ - case SC_BLESSING: /* ブレッシング */ - case SC_ANGELUS: /* アンゼルス */ - case SC_INCREASEAGI: /* 速度上昇 */ - case SC_DECREASEAGI: /* 速度減少 */ - case SC_SIGNUMCRUCIS: /* シグナムクルシス */ - case SC_HIDING: - case SC_TWOHANDQUICKEN: /* 2HQ */ - case SC_ADRENALINE: /* アドレナリンラッシュ */ - case SC_ENCPOISON: /* エンチャントポイズン */ - case SC_IMPOSITIO: /* インポシティオマヌス */ - case SC_GLORIA: /* グロリア */ - case SC_LOUD: /* ラウドボイス */ - case SC_QUAGMIRE: /* クァグマイア */ - case SC_PROVIDENCE: /* プロヴィデンス */ - case SC_SPEARSQUICKEN: /* スピアクイッケン */ - case SC_VOLCANO: - case SC_DELUGE: - case SC_VIOLENTGALE: - case SC_ETERNALCHAOS: /* エタ?ナルカオス */ - case SC_DRUMBATTLE: /* ?太鼓の響き */ - case SC_NIBELUNGEN: /* ニ?ベルングの指輪 */ - case SC_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - case SC_WHISTLE: /* 口笛 */ - case SC_ASSNCROS: /* 夕陽のアサシンクロス */ - case SC_HUMMING: /* ハミング */ - case SC_DONTFORGETME: /* 私を忘れないで */ - case SC_FORTUNE: /* 幸運のキス */ - case SC_SERVICE4U: /* サ?ビスフォ?ユ? */ - case SC_EXPLOSIONSPIRITS: // 爆裂波動 - case SC_STEELBODY: // 金剛 - case SC_DEFENDER: - case SC_SPEEDPOTION0: /* ?速ポ?ション */ - case SC_SPEEDPOTION1: - case SC_SPEEDPOTION2: - case SC_SPEEDPOTION3: - case SC_APPLEIDUN: /* イドゥンの林檎 */ - case SC_RIDING: - case SC_BLADESTOP_WAIT: - case SC_CONCENTRATION: /* コンセントレ?ション */ - case SC_ASSUMPTIO: /* アシャンプティオ */ - case SC_WINDWALK: /* ウインドウォ?ク */ - case SC_TRUESIGHT: /* トゥル?サイト */ - case SC_SPIDERWEB: /* スパイダ?ウェッブ */ - case SC_MAGICPOWER: /* 魔法力?幅 */ - case SC_CHASEWALK: - case SC_ATKPOT: /* attack potion [Valaris] */ - case SC_MATKPOT: /* magic attack potion [Valaris] */ - case SC_WEDDING: //結婚用(結婚衣裳になって?くのが?いとか) - case SC_MELTDOWN: /* メルトダウン */ - case SC_MINDBREAKER: /* マインドブレーカー */ - // Celest - case SC_EDP: - case SC_SLOWDOWN: - case SC_SPEEDUP0: - case SC_BATTLEORDERS: - case SC_REGENERATION: - case SC_GUILDAURA: - calc_flag = 1; - break; - case SC_AUTOBERSERK: - if (sc_data[SC_PROVOKE].timer != -1) - status_change_end(bl,SC_PROVOKE,-1); - break; - case SC_BERSERK: /* バ?サ?ク */ - calc_flag = 1; - clif_status_change(bl,SC_INCREASEAGI,0); /* アイコン消去 */ - break; - case SC_DEVOTION: /* ディボ?ション */ - { - struct map_session_data *md = map_id2sd(sc_data[type].val1); - sc_data[type].val1=sc_data[type].val2=0; - skill_devotion(md,bl->id); - calc_flag = 1; - } - break; - case SC_BLADESTOP: - { - struct status_change *t_sc_data = status_get_sc_data((struct block_list *)sc_data[type].val4); - //片方が切れたので相手の白刃?態が切れてないのなら解除 - if(t_sc_data && t_sc_data[SC_BLADESTOP].timer!=-1) - status_change_end((struct block_list *)sc_data[type].val4,SC_BLADESTOP,-1); - - if(sc_data[type].val2==2) - clif_bladestop((struct block_list *)sc_data[type].val3,(struct block_list *)sc_data[type].val4,0); - } - break; - case SC_DANCING: - { - struct map_session_data *dsd; - struct status_change *d_sc_data; - if(sc_data[type].val4 && (dsd=map_id2sd(sc_data[type].val4))){ - d_sc_data = dsd->sc_data; - //合奏で相手がいる場合相手のval4を0にする - if(d_sc_data && d_sc_data[type].timer!=-1) - d_sc_data[type].val4=0; - } - } - calc_flag = 1; - break; - case SC_NOCHAT: //チャット禁止?態 - { - struct map_session_data *sd=NULL; - if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){ - if (sd->status.manner >= 0) // weeee ^^ [celest] - sd->status.manner = 0; - clif_updatestatus(sd,SP_MANNER); - } - } - break; - case SC_SPLASHER: /* ベナムスプラッシャ? */ - { - struct block_list *src=map_id2bl(sc_data[type].val3); - if(src && tid!=-1){ - //自分にダメ?ジ&周?3*3にダメ?ジ - skill_castend_damage_id(src, bl,sc_data[type].val2,sc_data[type].val1,gettick(),0 ); - } - } - break; - case SC_SELFDESTRUCTION: /* 自爆 */ - { - //自分のダメ?ジは0にして - struct mob_data *md=NULL; - if(bl->type == BL_MOB && (md=(struct mob_data*)bl)) - skill_castend_damage_id(bl, bl,sc_data[type].val2,sc_data[type].val1,gettick(),0 ); - } - break; - /* option1 */ - case SC_FREEZE: - sc_data[type].val3 = 0; - break; - - /* option2 */ - case SC_POISON: /* 毒 */ - case SC_BLIND: /* 暗? */ - case SC_CURSE: - calc_flag = 1; - break; - - // celest - case SC_CONFUSION: - { - struct map_session_data *sd=NULL; - if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){ - sd->next_walktime = -1; - } - } - break; - - case SC_MARIONETTE: /* マリオネットコントロ?ル */ - case SC_MARIONETTE2: /// Marionette target - { - // check for partner and end their marionette status as well - int type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE; - struct block_list *pbl = map_id2bl(sc_data[type].val3); - if (pbl) { - struct status_change* sc_data; - if (*status_get_sc_count(pbl) > 0 && - (sc_data = status_get_sc_data(pbl)) && - sc_data[type2].timer != -1) - status_change_end(pbl, type2, -1); - } - calc_flag = 1; - } - break; - - case SC_BABY: - type2 = _SC_BABY; - break; - } - - if(bl->type==BL_PC && - (type<SC_SENDMAX || type==SC_PRESERVE || type==SC_BATTLEORDERS || type==SC_BABY)) - clif_status_change(bl,type2,0); /* アイコン消去 */ - - switch(type){ /* 正常に?るときなにか?理が必要 */ - case SC_STONE: - case SC_FREEZE: - case SC_STAN: - case SC_SLEEP: - *opt1 = 0; - opt_flag = 1; - break; - - case SC_POISON: - if (sc_data[SC_DPOISON].timer != -1) // - break; // DPOISON用のオプション - *opt2 &= ~1; // が?用に用意された場合には - opt_flag = 1; // ここは削除する - break; // - case SC_CURSE: - case SC_SILENCE: - case SC_BLIND: - *opt2 &= ~(1<<(type-SC_POISON)); - opt_flag = 1; - break; - case SC_DPOISON: - if (sc_data[SC_POISON].timer != -1) // DPOISON用のオプションが - break; // 用意されたら削除 - *opt2 &= ~1; // 毒?態解除 - opt_flag = 1; - break; - case SC_SIGNUMCRUCIS: - *opt2 &= ~0x40; - opt_flag = 1; - break; - - case SC_HIDING: - case SC_CLOAKING: - *option &= ~((type == SC_HIDING) ? 2 : 4); - calc_flag = 1; // orn - opt_flag = 1 ; - break; - - case SC_CHASEWALK: - *option &= ~16388; - opt_flag = 1 ; - break; - - case SC_SIGHT: - *option &= ~1; - opt_flag = 1; - break; - case SC_WEDDING: //結婚用(結婚衣裳になって?くのが?いとか) - *option &= ~4096; - opt_flag = 1; - break; - case SC_RUWACH: - *option &= ~8192; - opt_flag = 1; - break; - - //opt3 - case SC_TWOHANDQUICKEN: /* 2HQ */ - case SC_SPEARSQUICKEN: /* スピアクイッケン */ - case SC_CONCENTRATION: /* コンセントレ?ション */ - *opt3 &= ~1; - break; - case SC_OVERTHRUST: /* オ?バ?スラスト */ - *opt3 &= ~2; - break; - case SC_ENERGYCOAT: /* エナジ?コ?ト */ - *opt3 &= ~4; - break; - case SC_EXPLOSIONSPIRITS: // 爆裂波動 - *opt3 &= ~8; - break; - case SC_STEELBODY: // 金剛 - *opt3 &= ~16; - break; - case SC_BLADESTOP: /* 白刃取り */ - *opt3 &= ~32; - break; - case SC_BERSERK: /* バ?サ?ク */ - *opt3 &= ~128; - break; - case SC_MARIONETTE: /* マリオネットコントロ?ル */ - case SC_MARIONETTE2: - *opt3 &= ~1024; - break; - case SC_ASSUMPTIO: /* アスムプティオ */ - *opt3 &= ~2048; - break; - } - - if (night_flag == 1 && (*opt2 & STATE_BLIND) == 0 && bl->type == BL_PC && // by [Yor] - !map[bl->m].flag.indoors && battle_config.night_darkness_level <= 0) { // [celest] - *opt2 |= STATE_BLIND; - opt_flag = 1; - } - - if(opt_flag) /* optionの?更を?える */ - clif_changeoption(bl); - - if (bl->type == BL_PC && calc_flag) - status_calc_pc((struct map_session_data *)bl,0); /* ステ?タス再計算 */ - } - - return 0; -} - - -/*========================================== - * ステータス異常終了タイマー - *------------------------------------------ - */ -int status_change_timer(int tid, unsigned int tick, int id, int data) -{ - int type = data; - struct block_list *bl; - struct map_session_data *sd=NULL; - struct status_change *sc_data; - //short *sc_count; //使ってない? - -// security system to prevent forgetting timer removal - int temp_timerid; - - bl=map_id2bl(id); -#ifndef _WIN32 - nullpo_retr_f(0, bl, "id=%d data=%d",id,data); -#endif - nullpo_retr(0, sc_data=status_get_sc_data(bl)); - - if(bl->type==BL_PC) - nullpo_retr(0, sd=(struct map_session_data *)bl); - - //sc_count=status_get_sc_count(bl); //使ってない? - - if(sc_data[type].timer != tid) { - if(battle_config.error_log) - printf("status_change_timer %d != %d\n",tid,sc_data[type].timer); - return 0; - } - - // security system to prevent forgetting timer removal - // you shouldn't be that careless inside the switch here - temp_timerid = sc_data[type].timer; - sc_data[type].timer = -1; - - switch(type){ /* 特殊な?理になる場合 */ - case SC_MAXIMIZEPOWER: /* マキシマイズパワ? */ - case SC_CLOAKING: - if(sd){ - if( sd->status.sp > 0 ){ /* SP切れるまで持? */ - sd->status.sp--; - clif_updatestatus(sd,SP_SP); - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - sc_data[type].val2+tick, status_change_timer, bl->id, data); - return 0; - } - } - break; - - case SC_CHASEWALK: - if(sd){ - int sp = 10+sc_data[SC_CHASEWALK].val1*2; - if (map[sd->bl.m].flag.gvg) sp *= 5; - if( sd->status.sp > sp){ - sd->status.sp -= sp; // update sp cost [Celest] - clif_updatestatus(sd,SP_SP); - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - sc_data[type].val2+tick, status_change_timer, bl->id, data); - sc_data[SC_CHASEWALK].val4++; - if (sc_data[SC_CHASEWALK].val4 > 3) - sc_data[SC_CHASEWALK].val4 = 0; - status_calc_pc (sd, 0); - return 0; - } - } - break; - - case SC_HIDING: /* ハイディング */ - if(sd){ /* SPがあって、時間制限の間は持? */ - if( sd->status.sp > 0 && (--sc_data[type].val2)>0 ){ - if(sc_data[type].val2 % (sc_data[type].val1+3) ==0 ){ - sd->status.sp--; - clif_updatestatus(sd,SP_SP); - } - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 1000+tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - - case SC_SIGHT: /* サイト */ - case SC_RUWACH: /* ルアフ */ - { - int range = 5; - if ( type == SC_SIGHT ) range = 7; - map_foreachinarea( status_change_timer_sub, - bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0, - bl,type,tick); - - if( (--sc_data[type].val2)>0 ){ - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 250+tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - - case SC_SIGNUMCRUCIS: /* シグナムクルシス */ - { - int race = status_get_race(bl); - if(race == 6 || battle_check_undead(race,status_get_elem_type(bl))) { - sc_data[type].timer=add_timer(1000*600+tick,status_change_timer, bl->id, data ); - return 0; - } - } - break; - - case SC_PROVOKE: /* プロボック/オ?トバ?サ?ク */ - if(sc_data[type].val2!=0){ /* オ?トバ?サ?ク(1秒ごとにHPチェック) */ - if(sd && sd->status.hp>sd->status.max_hp>>2) /* 停止 */ - break; - sc_data[type].timer=add_timer( 1000+tick,status_change_timer, bl->id, data ); - return 0; - } - break; - - case SC_ENDURE: /* インデュア */ - case SC_AUTOBERSERK: // Celest - if(sd && sd->special_state.infinite_endure) { -#ifdef TWILIGHT - sc_data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data ); -#else - sc_data[type].timer=add_timer( 1000*60+tick,status_change_timer, bl->id, data ); -#endif - //sc_data[type].val2=1; - return 0; - } - break; - - case SC_DISSONANCE: /* 不協和音 */ - if( (--sc_data[type].val2)>0){ - struct skill_unit *unit= - (struct skill_unit *)sc_data[type].val4; - struct block_list *src; - /*if(!unit || !unit->group) - break; - src=map_id2bl(unit->group->src_id); - if(!src) - break;*/ - nullpo_retb(unit); - nullpo_retb(unit->group); - nullpo_retb(src=map_id2bl(unit->group->src_id)); - skill_attack(BF_MISC,src,&unit->bl,bl,unit->group->skill_id,sc_data[type].val1,tick,0); - if( (bl->type==BL_MOB) && (MS_DEAD==((struct mob_data *)bl)->state.state) ) - break; - sc_data[type].timer=add_timer(skill_get_time2(unit->group->skill_id,unit->group->skill_lv)+tick, - status_change_timer, bl->id, data ); - return 0; - } - break; - - case SC_LULLABY: /* 子守唄 */ - if( (--sc_data[type].val2)>0){ - struct skill_unit *unit= - (struct skill_unit *)sc_data[type].val4; - nullpo_retb(unit); - nullpo_retb(unit->group); - if(unit->group->src_id == bl->id) - break; - skill_additional_effect(bl,bl,unit->group->skill_id,sc_data[type].val1,BF_LONG|BF_SKILL|BF_MISC,tick); - if (unit->group != 0) - { - sc_data[type].timer=add_timer(skill_get_time(unit->group->skill_id,unit->group->skill_lv)/10+tick, - status_change_timer, bl->id, data ); - return 0; - }// dont forget the brackets - } - break; - - case SC_STONE: - if(sc_data[type].val2 != 0) { - short *opt1 = status_get_opt1(bl); - sc_data[type].val2 = 0; - sc_data[type].val4 = 0; - battle_stopwalking(bl,1); - if(opt1) { - *opt1 = 1; - clif_changeoption(bl); - } - sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data ); - return 0; - } - else if( (--sc_data[type].val3) > 0) { - int hp = status_get_max_hp(bl); - if((++sc_data[type].val4)%5 == 0 && status_get_hp(bl) > hp>>2) { - hp = hp/100; - if(hp < 1) hp = 1; - if(sd) - pc_heal(sd,-hp,0); - else if(bl->type == BL_MOB){ - struct mob_data *md; - if((md=((struct mob_data *)bl)) == NULL) - break; - md->hp -= hp; - } - } - sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data ); - return 0; - } - break; - - case SC_POISON: - case SC_DPOISON: - if (sc_data[SC_SLOWPOISON].timer == -1 && (--sc_data[type].val3) > 0) { - int hp = status_get_max_hp(bl); - if (type == SC_POISON && status_get_hp(bl) < hp>>2) - break; - if(sd) { - hp = (type == SC_DPOISON) ? 3 + hp/50 : 3 + hp*3/200; - pc_heal(sd, -hp, 0); - } else if (bl->type == BL_MOB) { - struct mob_data *md; - nullpo_retr(0, md=(struct mob_data *)bl); - hp = (type == SC_DPOISON) ? 3 + hp/100 : 3 + hp/200; - md->hp -= hp; - } - } - if (sc_data[type].val3 > 0) - { - sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data ); - // hmm setting up a timer and breaking then to call status_change_end just right away? - // I think you're missing brackets and a: - return 0; - } - break; - - case SC_TENSIONRELAX: /* テンションリラックス */ - if(sd){ /* SPがあって、HPが?タンでなければ?? */ - if( sd->status.sp > 12 && sd->status.max_hp > sd->status.hp ){ -/* if(sc_data[type].val2 % (sc_data[type].val1+3) ==0 ){ - sd->status.sp -= 12; - clif_updatestatus(sd,SP_SP); - } */ - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 10000+tick, status_change_timer, - bl->id, data); - return 0; - } - if(sd->status.max_hp <= sd->status.hp) - { - status_change_end(&sd->bl,SC_TENSIONRELAX,-1); - // calling status_change_end then break and call it again might not be that what is necessary - // or am I wrong? - // so I just add brackets and a: - return 0; - } - } - break; - case SC_BLEEDING: // [celest] - // i hope i haven't interpreted it wrong.. which i might ^^; - // Source: - // - 10ゥェエェネェヒHPェャハ盒 - // - ェホェ゙ェ゙ォオ?ォミケヤムェ茘ォォーェキェニェ?ヘェマ眈ェィェハェ、 - if((sc_data[type].val3 -= 1000) > 0) { - if((sc_data[type].val4 -= 1000) > 0) { - int hp = rand()%300+400; - if(sd) { - pc_heal(sd,-hp,0); - sd->canmove_tick = tick+1000; - } - else if(bl->type == BL_MOB) { - struct mob_data *md; - nullpo_retr(0, md=(struct mob_data *)bl); - md->hp -= hp; - } - } - if (sd) { - sd->canact_tick = tick+1000; - } - - sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data ); - // hmm setting up a timer and breaking then to call status_change_end just right away? - // I think you're missing a: - return 0; - } - break; - - /* 時間切れ無し?? */ - case SC_AETERNA: - case SC_TRICKDEAD: - case SC_RIDING: - case SC_FALCON: - case SC_WEIGHT50: - case SC_WEIGHT90: - case SC_MAGICPOWER: /* 魔法力?幅 */ - case SC_REJECTSWORD: /* リジェクトソ?ド */ - case SC_MEMORIZE: /* メモライズ */ - case SC_BROKNWEAPON: - case SC_BROKNARMOR: - case SC_SACRIFICE: - sc_data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data ); - return 0; - - case SC_DANCING: //ダンススキルの時間SP消費 - { - int s=0; - if(sd){ - if(sd->status.sp > 0 && (--sc_data[type].val3)>0){ - switch(sc_data[type].val1){ - case BD_RICHMANKIM: /* ニヨルドの宴 3秒にSP1 */ - case BD_DRUMBATTLEFIELD: /* ?太鼓の響き 3秒にSP1 */ - case BD_RINGNIBELUNGEN: /* ニ?ベルングの指輪 3秒にSP1 */ - case BD_SIEGFRIED: /* 不死身のジ?クフリ?ド 3秒にSP1 */ - case BA_DISSONANCE: /* 不協和音 3秒でSP1 */ - case BA_ASSASSINCROSS: /* 夕陽のアサシンクロス 3秒でSP1 */ - case DC_UGLYDANCE: /* 自分勝手なダンス 3秒でSP1 */ - s=3; - break; - case BD_LULLABY: /* 子守歌 4秒にSP1 */ - case BD_ETERNALCHAOS: /* 永遠の混沌 4秒にSP1 */ - case BD_ROKISWEIL: /* ロキの叫び 4秒にSP1 */ - case DC_FORTUNEKISS: /* 幸運のキス 4秒でSP1 */ - s=4; - break; - case BD_INTOABYSS: /* 深淵の中に 5秒にSP1 */ - case BA_WHISTLE: /* 口笛 5秒でSP1 */ - case DC_HUMMING: /* ハミング 5秒でSP1 */ - case BA_POEMBRAGI: /* ブラギの詩 5秒でSP1 */ - case DC_SERVICEFORYOU: /* サ?ビスフォ?ユ? 5秒でSP1 */ - s=5; - break; - case BA_APPLEIDUN: /* イドゥンの林檎 6秒でSP1 */ - s=6; - break; - case DC_DONTFORGETME: /* 私を忘れないで… 10秒でSP1 */ - case CG_MOONLIT: /* 月明りの泉に落ちる花びら 10秒でSP1? */ - s=10; - break; - } - if(s && ((sc_data[type].val3 % s) == 0)){ - sd->status.sp--; - clif_updatestatus(sd,SP_SP); - } - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 1000+tick, status_change_timer, - bl->id, data); - return 0; - } - } - } - break; - case SC_BERSERK: /* バ?サ?ク */ - if(sd){ /* HPが100以上なら?? */ - if( (sd->status.hp - sd->status.max_hp*5/100) > 100 ){ // 5% every 10 seconds [DracoRPG] - sd->status.hp -= sd->status.max_hp*5/100; // changed to max hp [celest] - clif_updatestatus(sd,SP_HP); - sc_data[type].timer = add_timer( /* タイマ?再設定 */ - 10000+tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - case SC_WEDDING: //結婚用(結婚衣裳になって?くのが?いとか) - if(sd){ - time_t timer; - if(time(&timer) < ((sc_data[type].val2) + 3600)){ //1時間たっていないので?? - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 10000+tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - case SC_NOCHAT: //チャット禁止?態 - if(sd && battle_config.muting_players){ - time_t timer; - if((++sd->status.manner) && time(&timer) < ((sc_data[type].val2) + 60*(0-sd->status.manner))){ //開始からstatus.manner分?ってないので?? - clif_updatestatus(sd,SP_MANNER); - sc_data[type].timer=add_timer( /* タイマ?再設定(60秒) */ - 60000+tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - case SC_SELFDESTRUCTION: /* 自爆 */ - if(--sc_data[type].val3>0){ - struct mob_data *md; - if(bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->speed > 250){ - md->speed -= 250; - md->next_walktime=tick; - } - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 1000+tick, status_change_timer, - bl->id, data); - return 0; - } - break; - - case SC_SPLASHER: - if (sc_data[type].val4 % 1000 == 0) { - char timer[2]; - sprintf (timer, "%d", sc_data[type].val4/1000); - clif_message(bl, timer); - } - if((sc_data[type].val4 -= 500) > 0) { - sc_data[type].timer = add_timer( - 500 + tick, status_change_timer, - bl->id, data); - return 0; - } - break; - - case SC_MARIONETTE: /* マリオネットコントロ?ル */ - case SC_MARIONETTE2: - { - struct block_list *pbl = map_id2bl(sc_data[type].val3); - if (pbl && battle_check_range(bl, pbl, 7) && - (sc_data[type].val2 -= 1000)>0) { - sc_data[type].timer = add_timer( - 1000 + tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - - // Celest - case SC_CONFUSION: - { - int i = 3000; - //struct mob_data *md; - if (sd) { - pc_randomwalk (sd, gettick()); - sd->next_walktime = tick + (i=1000 + rand()%1000); - } /*else if (bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->mode&1 && mob_can_move(md)) { - md->state.state=MS_WALK; - if( DIFF_TICK(md->next_walktime,tick) > + 7000 && - (md->walkpath.path_len==0 || md->walkpath.path_pos>=md->walkpath.path_len) ) - md->next_walktime = tick + 3000*rand()%2000; - mob_randomwalk(md,tick); - }*/ - if ((sc_data[type].val2 -= 1000) > 0) { - sc_data[type].timer = add_timer( - i + tick, status_change_timer, - bl->id, data); - return 0; - } - } - break; - - case SC_GOSPEL: - { - int calc_flag = 0; - if (sc_data[type].val3 > 0) { - sc_data[type].val3 = 0; - calc_flag = 1; - } - if(sd && sc_data[type].val4 == BCT_SELF){ - int hp, sp; - hp = (sc_data[type].val1 > 5) ? 45 : 30; - sp = (sc_data[type].val1 > 5) ? 35 : 20; - if(sd->status.hp - hp > 0 && - sd->status.sp - sp > 0){ - sd->status.hp -= hp; - sd->status.sp -= sp; - clif_updatestatus(sd,SP_HP); - clif_updatestatus(sd,SP_SP); - if ((sc_data[type].val2 -= 10000) > 0) { - sc_data[type].timer = add_timer( - 10000+tick, status_change_timer, - bl->id, data); - return 0; - } - } - } else if (sd && sc_data[type].val4 == BCT_PARTY) { - int i; - switch ((i = rand() % 12)) { - case 1: // heal between 100-1000 - { - struct block_list tbl; - int heal = rand() % 900 + 100; - tbl.id = 0; - tbl.m = bl->m; - tbl.x = bl->x; - tbl.y = bl->y; - clif_skill_nodamage(&tbl,bl,AL_HEAL,heal,1); - battle_heal(NULL,bl,heal,0,0); - } - break; - case 2: // end negative status - { - int j; - for (j=0; j<4; j++) - if(sc_data[i + SC_POISON].timer!=-1) { - status_change_end(bl,j,-1); - break; - } - } - break; - case 3: // +25% resistance to negative status - case 4: // +25% max hp - case 5: // +25% max sp - case 6: // +2 to all stats - case 11: // +25% armor and vit def - case 12: // +8% atk - case 13: // +5% flee - case 14: // +5% hit - sc_data[type].val3 = i; - if (i == 6 || - (i >= 11 && i <= 14)) - calc_flag = 1; - break; - case 7: // level 5 bless - { - struct block_list tbl; - tbl.id = 0; - tbl.m = bl->m; - tbl.x = bl->x; - tbl.y = bl->y; - clif_skill_nodamage(&tbl,bl,AL_BLESSING,5,1); - status_change_start(bl,SkillStatusChangeTable[AL_BLESSING],5,0,0,0,10000,0 ); - } - break; - case 8: // level 5 increase agility - { - struct block_list tbl; - tbl.id = 0; - tbl.m = bl->m; - tbl.x = bl->x; - tbl.y = bl->y; - clif_skill_nodamage(&tbl,bl,AL_INCAGI,5,1); - status_change_start(bl,SkillStatusChangeTable[AL_INCAGI],5,0,0,0,10000,0 ); - } - break; - case 9: // holy element to weapon - { - struct block_list tbl; - tbl.id = 0; - tbl.m = bl->m; - tbl.x = bl->x; - tbl.y = bl->y; - clif_skill_nodamage(&tbl,bl,PR_ASPERSIO,1,1); - status_change_start(bl,SkillStatusChangeTable[PR_ASPERSIO],1,0,0,0,10000,0 ); - } - break; - case 10: // holy element to armour - { - struct block_list tbl; - tbl.id = 0; - tbl.m = bl->m; - tbl.x = bl->x; - tbl.y = bl->y; - clif_skill_nodamage(&tbl,bl,PR_BENEDICTIO,1,1); - status_change_start(bl,SkillStatusChangeTable[PR_BENEDICTIO],1,0,0,0,10000,0 ); - } - break; - default: - break; - } - } else if (sc_data[type].val4 == BCT_ENEMY) { - int i; - switch ((i = rand() % 8)) { - case 1: // damage between 300-800 - case 2: // damage between 150-550 (ignore def) - battle_damage(NULL, bl, rand() % 500,0); // temporary damage - break; - case 3: // random status effect - { - int effect[3] = { - SC_CURSE, - SC_BLIND, - SC_POISON }; - status_change_start(bl,effect[rand()%3],1,0,0,0,10000,0 ); - } - break; - case 4: // level 10 provoke - { - struct block_list tbl; - tbl.id = 0; - tbl.m = bl->m; - tbl.x = bl->x; - tbl.y = bl->y; - clif_skill_nodamage(&tbl,bl,SM_PROVOKE,1,1); - status_change_start(bl,SkillStatusChangeTable[SM_PROVOKE],10,0,0,0,10000,0 ); - } - break; - case 5: // 0 def - case 6: // 0 atk - case 7: // 0 flee - case 8: // -75% move speed and aspd - sc_data[type].val3 = i; - calc_flag = 1; - break; - default: - break; - } - } - if (sd && calc_flag) - status_calc_pc (sd, 0); - } - break; - - case SC_GUILDAURA: - { - struct block_list *tbl = map_id2bl(sc_data[type].val2); - - if (tbl && battle_check_range(bl, tbl, 2)){ - sc_data[type].timer = add_timer( - 1000 + tick, status_change_timer, - bl->id, data); - return 0; - }// ugh, don't forget the brackets - } - break; - } - - // default for all non-handled control paths - // security system to prevent forgetting timer removal - - // if we reach this point we need the timer for the next call, - // so restore it to have status_change_end handle a valid timer - sc_data[type].timer = temp_timerid; - - return status_change_end( bl,type,tid ); -} - -/*========================================== - * ステータス異常タイマー範囲処理 - *------------------------------------------ - */ -int status_change_timer_sub(struct block_list *bl, va_list ap ) -{ - struct block_list *src; - int type; - unsigned int tick; - - nullpo_retr(0, bl); - nullpo_retr(0, ap); - nullpo_retr(0, src=va_arg(ap,struct block_list*)); - type=va_arg(ap,int); - tick=va_arg(ap,unsigned int); - - if(bl->type!=BL_PC && bl->type!=BL_MOB) - return 0; - - switch( type ){ - case SC_SIGHT: /* サイト */ - case SC_CONCENTRATE: - if( (*status_get_option(bl))&6 ){ - status_change_end( bl, SC_HIDING, -1); - status_change_end( bl, SC_CLOAKING, -1); - } - break; - case SC_RUWACH: /* ルアフ */ - if( (*status_get_option(bl))&6 ){ - struct status_change *sc_data = status_get_sc_data(bl); // check whether the target is hiding/cloaking [celest] - if (sc_data && (sc_data[SC_HIDING].timer != -1 || // if the target is using a special hiding, i.e not using normal hiding/cloaking, don't bother - sc_data[SC_CLOAKING].timer != -1)) { - status_change_end( bl, SC_HIDING, -1); - status_change_end( bl, SC_CLOAKING, -1); - } - if(battle_check_target( src,bl, BCT_ENEMY ) > 0) - skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,sc_data[type].val1,tick,0); - } - break; - } - return 0; -} - - -static int status_calc_sigma(void) -{ - int i,j,k; - - for(i=0;i<MAX_PC_CLASS;i++) { - memset(hp_sigma_val[i],0,sizeof(hp_sigma_val[i])); - for(k=0,j=2;j<=MAX_LEVEL;j++) { - k += hp_coefficient[i]*j + 50; - k -= k%100; - hp_sigma_val[i][j-1] = k; - } - } - return 0; -} - -int status_readdb(void) { - int i,j,k; - FILE *fp; - char line[1024],*p; - - // JOB補正?値1 - fp=fopen("db/job_db1.txt","r"); - if(fp==NULL){ - printf("can't read db/job_db1.txt\n"); - return 1; - } - i=0; - while(fgets(line, sizeof(line)-1, fp)){ - char *split[50]; - if(line[0]=='/' && line[1]=='/') - continue; - for(j=0,p=line;j<21 && p;j++){ - split[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if(j<21) - continue; - max_weight_base[i]=atoi(split[0]); - hp_coefficient[i]=atoi(split[1]); - hp_coefficient2[i]=atoi(split[2]); - sp_coefficient[i]=atoi(split[3]); - for(j=0;j<17;j++) - aspd_base[i][j]=atoi(split[j+4]); - i++; -// -- moonsoul (below two lines added to accommodate high numbered new class ids) - if(i==24) - i=4001; - if(i==MAX_PC_CLASS) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db1.txt"); - ShowStatus(tmp_output); - - // JOBボ?ナス - memset(job_bonus,0,sizeof(job_bonus)); - fp=fopen("db/job_db2.txt","r"); - if(fp==NULL){ - printf("can't read db/job_db2.txt\n"); - return 1; - } - i=0; - while(fgets(line, sizeof(line)-1, fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - for(j=0,p=line;j<MAX_LEVEL && p;j++){ - if(sscanf(p,"%d",&k)==0) - break; - job_bonus[0][i][j]=k; - job_bonus[2][i][j]=k; //養子職のボ?ナスは分からないので? - p=strchr(p,','); - if(p) p++; - } - i++; -// -- moonsoul (below two lines added to accommodate high numbered new class ids) - if(i==24) - i=4001; - if(i==MAX_PC_CLASS) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db2.txt"); - ShowStatus(tmp_output); - - // JOBボ?ナス2 ?生職用 - fp=fopen("db/job_db2-2.txt","r"); - if(fp==NULL){ - printf("can't read db/job_db2-2.txt\n"); - return 1; - } - i=0; - while(fgets(line, sizeof(line)-1, fp)){ - if(line[0]=='/' && line[1]=='/') - continue; - for(j=0,p=line;j<MAX_LEVEL && p;j++){ - if(sscanf(p,"%d",&k)==0) - break; - job_bonus[1][i][j]=k; - p=strchr(p,','); - if(p) p++; - } - i++; - if(i==MAX_PC_CLASS) - break; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db2-2.txt"); - ShowStatus(tmp_output); - - // サイズ補正テ?ブル - for(i=0;i<3;i++) - for(j=0;j<20;j++) - atkmods[i][j]=100; - fp=fopen("db/size_fix.txt","r"); - if(fp==NULL){ - printf("can't read db/size_fix.txt\n"); - return 1; - } - i=0; - while(fgets(line, sizeof(line)-1, fp)){ - char *split[20]; - if(line[0]=='/' && line[1]=='/') - continue; - if(atoi(line)<=0) - continue; - memset(split,0,sizeof(split)); - for(j=0,p=line;j<20 && p;j++){ - split[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - for(j=0;j<20 && split[j];j++) - atkmods[i][j]=atoi(split[j]); - i++; - } - fclose(fp); - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/size_fix.txt"); - ShowStatus(tmp_output); - - // 精?デ?タテ?ブル - for(i=0;i<5;i++){ - for(j=0;j<10;j++) - percentrefinery[i][j]=100; - refinebonus[i][0]=0; - refinebonus[i][1]=0; - refinebonus[i][2]=10; - } - fp=fopen("db/refine_db.txt","r"); - if(fp==NULL){ - printf("can't read db/refine_db.txt\n"); - return 1; - } - i=0; - while(fgets(line, sizeof(line)-1, fp)){ - char *split[16]; - if(line[0]=='/' && line[1]=='/') - continue; - if(atoi(line)<=0) - continue; - memset(split,0,sizeof(split)); - for(j=0,p=line;j<16 && p;j++){ - split[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - refinebonus[i][0]=atoi(split[0]); // 精?ボ?ナス - refinebonus[i][1]=atoi(split[1]); // 過?精?ボ?ナス - refinebonus[i][2]=atoi(split[2]); // 安全精?限界 - for(j=0;j<10 && split[j];j++) - percentrefinery[i][j]=atoi(split[j+3]); - i++; - } - fclose(fp); //Lupus. close this file!!! - sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/refine_db.txt"); - ShowStatus(tmp_output); - - return 0; -} - -/*========================================== - * スキル関係初期化処理 - *------------------------------------------ - */ -int do_init_status(void) -{ - add_timer_func_list(status_change_timer,"status_change_timer"); - status_readdb(); - status_calc_sigma(); - return 0; -} diff --git a/src/map/status.h b/src/map/status.h deleted file mode 100644 index a07c47153..000000000 --- a/src/map/status.h +++ /dev/null @@ -1,271 +0,0 @@ -#ifndef _STATUS_H_ -#define _STATUS_H_ - -enum { // struct map_session_data の status_changeの番?テ?ブル -// SC_SENDMAX未?はクライアントへの通知あり。 -// 2-2次職の値はなんかめちゃくちゃっぽいので暫定。たぶん?更されます。 - SC_SENDMAX = 128, // note: max is now 182, but we'll need to do alot of moving around - SC_PROVOKE = 0, - SC_ENDURE = 1, - SC_TWOHANDQUICKEN = 2, - SC_CONCENTRATE = 3, - SC_HIDING = 4, - SC_CLOAKING = 5, - SC_ENCPOISON = 6, - SC_POISONREACT = 7, - SC_QUAGMIRE = 8, - SC_ANGELUS = 9, - SC_BLESSING = 10, - SC_SIGNUMCRUCIS = 11, - SC_INCREASEAGI = 12, - SC_DECREASEAGI = 13, - SC_SLOWPOISON = 14, - SC_IMPOSITIO = 15, - SC_SUFFRAGIUM = 16, - SC_ASPERSIO = 17, - SC_BENEDICTIO = 18, - SC_KYRIE = 19, - SC_MAGNIFICAT = 20, - SC_GLORIA = 21, - SC_AETERNA = 22, - SC_ADRENALINE = 23, - SC_WEAPONPERFECTION = 24, - SC_OVERTHRUST = 25, - SC_MAXIMIZEPOWER = 26, - SC_RIDING = 27, - SC_FALCON = 28, - SC_TRICKDEAD = 29, - SC_LOUD = 30, - SC_ENERGYCOAT = 31, - SC_BROKNARMOR = 32, - SC_BROKNWEAPON = 33, - SC_HALLUCINATION = 34, - SC_WEIGHT50 = 35, - SC_WEIGHT90 = 36, - SC_SPEEDPOTION0 = 37, - SC_SPEEDPOTION1 = 38, - SC_SPEEDPOTION2 = 39, - SC_SPEEDPOTION3 = 40, - SC_SPEEDUP0 = 41, // for skill speedup - SC_SPEEDUP1 = 42, // for skill speedup -//-- 43-50 - SC_STRIPWEAPON = 50, - SC_STRIPSHIELD = 51, - SC_STRIPARMOR = 52, - SC_STRIPHELM = 53, - SC_CP_WEAPON = 54, - SC_CP_SHIELD = 55, - SC_CP_ARMOR = 56, - SC_CP_HELM = 57, - SC_AUTOGUARD = 58, - SC_REFLECTSHIELD = 59, - SC_DEVOTION = 60, - SC_PROVIDENCE = 61, - SC_DEFENDER = 62, - SC_AUTOSPELL = 65, - SC_SPEARSQUICKEN = 68, -//-- 69-85 - SC_EXPLOSIONSPIRITS = 86, - SC_STEELBODY = 87, - SC_COMBO = 89, - SC_FLAMELAUNCHER = 90, - SC_FROSTWEAPON = 91, - SC_LIGHTNINGLOADER = 92, - SC_SEISMICWEAPON = 93, -//-- 94-102 - SC_AURABLADE = 103, /* オ?ラブレ?ド */ - SC_PARRYING = 104, /* パリイング */ - SC_CONCENTRATION = 105, /* コンセントレ?ション */ - SC_TENSIONRELAX = 106, /* テンションリラックス */ - SC_BERSERK = 107, /* バ?サ?ク */ -//-- 108, 109 - SC_ASSUMPTIO = 110, /* アシャンプティオ */ -//-- 111, 112 - SC_MAGICPOWER = 113, /* 魔法力?幅 */ - SC_EDP = 114, /* エフェクトが判明したら移動 */ - SC_TRUESIGHT = 115, /* トゥル?サイト */ - SC_WINDWALK = 116, /* ウインドウォ?ク */ - SC_MELTDOWN = 117, /* メルトダウン */ - SC_CARTBOOST = 118, /* カ?トブ?スト */ -//-- 119 - SC_REJECTSWORD = 120, /* リジェクトソ?ド */ - SC_MARIONETTE = 121, /* マリオネットコントロ?ル */ - SC_MARIONETTE2 = 122, // Marionette target -//-- 123 - SC_BLEEDING = 124, /* ヘッドクラッシュ */ - SC_JOINTBEAT = 125, /* ジョイントビ?ト */ -//-- 126, 127 - - SC_STONE = 128, - SC_FREEZE = 129, -// <-- 130 = a baby skill status? - SC_STAN = 130, - SC_SLEEP = 131, -// <-- 132 = another baby skill? - SC_POISON = 132, - SC_CURSE = 133, - SC_SILENCE = 134, - SC_CONFUSION = 135, - SC_BLIND = 136, - SC_DIVINA = SC_SILENCE, -//-- 137-139 - SC_SAFETYWALL = 140, - SC_PNEUMA = 141, -//-- 142 - SC_ANKLE = 143, - SC_DANCING = 144, - SC_KEEPING = 145, - SC_BARRIER = 146, -//-- 147,148 - SC_MAGICROD = 149, - SC_SIGHT = 150, - SC_RUWACH = 151, - SC_AUTOCOUNTER = 152, - SC_VOLCANO = 153, - SC_DELUGE = 154, - SC_VIOLENTGALE = 155, - SC_BLADESTOP_WAIT = 156, - SC_BLADESTOP = 157, - SC_EXTREMITYFIST = 158, -//-- 159 - SC_LULLABY =160, - SC_RICHMANKIM =161, - SC_ETERNALCHAOS =162, - SC_DRUMBATTLE =163, - SC_NIBELUNGEN =164, - SC_ROKISWEIL =165, - SC_INTOABYSS =166, - SC_SIEGFRIED =167, - SC_DISSONANCE =168, - SC_WHISTLE =169, - SC_ASSNCROS =170, - SC_POEMBRAGI =171, - SC_APPLEIDUN =172, - SC_UGLYDANCE =173, - SC_HUMMING =174, - SC_DONTFORGETME =175, - SC_FORTUNE =176, - SC_SERVICE4U =177, - SC_SPIDERWEB =180, /* スパイダ?ウェッブ */ -// <-- 181 = unknown status -// <-- 182 = unknown status - SC_SACRIFICE =184, /* サクリファイス */ - SC_WEDDING =187, //結婚用(結婚衣裳になって?くのが?いとか) - SC_NOCHAT =188, //赤エモ?態 - SC_SPLASHER =189, /* ベナムスプラッシャ? */ - SC_SELFDESTRUCTION =190, /* 自爆 */ - SC_MEMORIZE =197, /* メモライズ */ // changed from 181 to 192 - SC_DPOISON =198, /* 猛毒 */ - -// Used by English Team - SC_SLOWDOWN =45, // for skill slowdown - SC_AUTOBERSERK =46, - SC_SIGHTTRASHER =73, - SC_BASILICA =102, // temporarily use this before an actual id is found [celest] - - SC_ENSEMBLE =159, - SC_FOGWALL =178, - SC_GOSPEL =179, - SC_PRESERVE =181, - SC_BATTLEORDERS =182, - SC_MOONLIT =183, - SC_ATKPOT =185, // [Valaris] - SC_MATKPOT =186, // [Valaris] - SC_MINDBREAKER =191, - SC_SPELLBREAKER =192, - SC_LANDPROTECTOR =193, - SC_ADAPTATION =194, - SC_CHASEWALK =195, - SC_REGENERATION =196, - SC_GUILDAURA =199, - SC_BABY =200, - -// Icons - _SC_BABY =200 -}; -extern int SkillStatusChangeTable[]; - -extern int current_equip_item_index; - -// パラメータ所得系 battle.c より移動 -int status_get_class(struct block_list *bl); -int status_get_dir(struct block_list *bl); -int status_get_lv(struct block_list *bl); -int status_get_range(struct block_list *bl); -int status_get_hp(struct block_list *bl); -int status_get_max_hp(struct block_list *bl); -int status_get_str(struct block_list *bl); -int status_get_agi(struct block_list *bl); -int status_get_vit(struct block_list *bl); -int status_get_int(struct block_list *bl); -int status_get_dex(struct block_list *bl); -int status_get_luk(struct block_list *bl); -int status_get_hit(struct block_list *bl); -int status_get_flee(struct block_list *bl); -int status_get_def(struct block_list *bl); -int status_get_mdef(struct block_list *bl); -int status_get_flee2(struct block_list *bl); -int status_get_def2(struct block_list *bl); -int status_get_mdef2(struct block_list *bl); -int status_get_baseatk(struct block_list *bl); -int status_get_atk(struct block_list *bl); -int status_get_atk2(struct block_list *bl); -int status_get_speed(struct block_list *bl); -int status_get_adelay(struct block_list *bl); -int status_get_amotion(struct block_list *bl); -int status_get_dmotion(struct block_list *bl); -int status_get_element(struct block_list *bl); -int status_get_attack_element(struct block_list *bl); -int status_get_attack_element2(struct block_list *bl); //左手武器属性取得 -#define status_get_elem_type(bl) (status_get_element(bl)%10) -#define status_get_elem_level(bl) (status_get_element(bl)/10/2) -int status_get_party_id(struct block_list *bl); -int status_get_guild_id(struct block_list *bl); -int status_get_race(struct block_list *bl); -int status_get_size(struct block_list *bl); -int status_get_mode(struct block_list *bl); -int status_get_mexp(struct block_list *bl); -int status_get_race2(struct block_list *bl); - -struct status_change *status_get_sc_data(struct block_list *bl); -short *status_get_sc_count(struct block_list *bl); -short *status_get_opt1(struct block_list *bl); -short *status_get_opt2(struct block_list *bl); -short *status_get_opt3(struct block_list *bl); -short *status_get_option(struct block_list *bl); - -int status_get_matk1(struct block_list *bl); -int status_get_matk2(struct block_list *bl); -int status_get_critical(struct block_list *bl); -int status_get_atk_(struct block_list *bl); -int status_get_atk_2(struct block_list *bl); -int status_get_atk2(struct block_list *bl); - -int status_isdead(struct block_list *bl); - -int status_get_sc_def(struct block_list *bl, int type); -#define status_get_sc_def_mdef(bl) (status_get_sc_def(bl, SP_MDEF1)) -#define status_get_sc_def_vit(bl) (status_get_sc_def(bl, SP_DEF2)) -#define status_get_sc_def_int(bl) (status_get_sc_def(bl, SP_MDEF2)) -#define status_get_sc_def_luk(bl) (status_get_sc_def(bl, SP_LUK)) - -// 状態異常関連 skill.c より移動 -int status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag); -int status_change_end( struct block_list* bl , int type,int tid ); -int status_change_timer(int tid, unsigned int tick, int id, int data); -int status_change_timer_sub(struct block_list *bl, va_list ap ); -int status_change_clear(struct block_list *bl,int type); - -// ステータス計算 pc.c から分離 -// pc_calcstatus -int status_calc_pc(struct map_session_data* sd,int first); -int status_calc_speed(struct map_session_data*); // [Celest] -// int status_calc_skilltree(struct map_session_data *sd); -int status_getrefinebonus(int lv,int type); -int status_percentrefinery(struct map_session_data *sd,struct item *item); -extern int percentrefinery[5][10]; - -int status_readdb(void); -int do_init_status(void); - -#endif diff --git a/src/map/storage.c b/src/map/storage.c deleted file mode 100644 index 82ecd9321..000000000 --- a/src/map/storage.c +++ /dev/null @@ -1,624 +0,0 @@ -// $Id: storage.c,v 1.3 2004/09/25 02:05:22 MouseJstr Exp $ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../common/db.h" -#include "../common/nullpo.h" -#include "../common/malloc.h" - -#include "itemdb.h" -#include "clif.h" -#include "intif.h" -#include "pc.h" -#include "storage.h" -#include "guild.h" -#include "battle.h" -#include "atcommand.h" - -#ifdef MEMWATCH -#include "memwatch.h" -#endif - -static struct dbt *storage_db; -static struct dbt *guild_storage_db; - -/*========================================== - * 倉庫内アイテムソート - *------------------------------------------ - */ -int storage_comp_item(const void *_i1, const void *_i2){ -struct item *i1=(struct item *)_i1; -struct item *i2=(struct item *)_i2; - - if (i1->nameid == i2->nameid) { - return 0; - } else if (!(i1->nameid) || !(i1->amount)){ - return 1; - } else if (!(i2->nameid) || !(i2->amount)){ - return -1; - } else { - return i1->nameid - i2->nameid; - } -} - - -void sortage_sortitem(struct storage* stor){ - nullpo_retv(stor); - - qsort(stor->storage_, MAX_STORAGE, sizeof(struct item), storage_comp_item); -} - -void sortage_gsortitem(struct guild_storage* gstor){ - nullpo_retv(gstor); - - qsort(gstor->storage_, MAX_GUILD_STORAGE, sizeof(struct item), storage_comp_item); -} - -/*========================================== - * 初期化とか - *------------------------------------------ - */ -int do_init_storage(void) // map.c::do_init()から呼ばれる -{ - storage_db=numdb_init(); - guild_storage_db=numdb_init(); - return 1; -} -static int guild_storage_db_final(void *key,void *data,va_list ap) -{ - struct guild_storage *gstor=(struct guild_storage *) data; - aFree(gstor); - return 0; -} -static int storage_db_final(void *key,void *data,va_list ap) -{ - struct storage *stor=(struct storage *) data; - aFree(stor); - return 0; -} -void do_final_storage(void) // by [MC Cameri] -{ - if (storage_db) - numdb_final(storage_db,storage_db_final); - if (guild_storage_db) - numdb_final(guild_storage_db,guild_storage_db_final); -} - -struct storage *account2storage(int account_id) -{ - struct storage *stor; - stor=(struct storage *) numdb_search(storage_db,account_id); - if(stor == NULL) { - stor = (struct storage *) aCallocA(sizeof(struct storage), 1); - if(stor == NULL){ - printf("storage: out of memory!\n"); - exit(0); - } - memset(stor,0,sizeof(struct storage)); - stor->account_id=account_id; - numdb_insert(storage_db,stor->account_id,stor); - } - return stor; -} - -// Just to ask storage, without creation -struct storage *account2storage2(int account_id) { - return (struct storage *) numdb_search(storage_db, account_id); -} - -int storage_delete(int account_id) -{ - struct storage *stor = (struct storage *) numdb_search(storage_db,account_id); - if(stor) { - numdb_erase(storage_db,account_id); - aFree(stor); - } - return 0; -} - -/*========================================== - * カプラ倉庫を開く - *------------------------------------------ - */ -int storage_storageopen(struct map_session_data *sd) -{ - struct storage *stor; - - nullpo_retr(0, sd); - - if(pc_isGM(sd) && pc_isGM(sd) < battle_config.gm_can_drop_lv) { - clif_displaymessage(sd->fd, msg_txt(246)); - return 1; - } - if((stor = (struct storage *) numdb_search(storage_db,sd->status.account_id)) != NULL) { - if (stor->storage_status == 0) { - stor->storage_status = 1; - sd->state.storage_flag = 0; - clif_storageitemlist(sd,stor); - clif_storageequiplist(sd,stor); - clif_updatestorageamount(sd,stor); - return 0; - } - } else - intif_request_storage(sd->status.account_id); - - return 1; -} - -/*========================================== - * カプラ倉庫へアイテム追加 - *------------------------------------------ - */ -int storage_additem(struct map_session_data *sd,struct storage *stor,struct item *item_data,int amount) -{ - struct item_data *data; - int i; - - nullpo_retr(1, sd); - nullpo_retr(1, stor); - nullpo_retr(1, item_data); - - stor->dirty = 1; - - if(item_data->nameid <= 0 || amount <= 0) - return 1; - nullpo_retr(1, data = itemdb_search(item_data->nameid)); - - i=MAX_STORAGE; - if(!itemdb_isequip2(data)){ - // 装備品ではないので、既所有品なら個数のみ変化させる - for(i=0;i<MAX_STORAGE;i++){ - if( compare_item (&stor->storage_[i], item_data)) { - if(stor->storage_[i].amount+amount > MAX_AMOUNT) - return 1; - stor->storage_[i].amount+=amount; - clif_storageitemadded(sd,stor,i,amount); - break; - } - } - } - if(i>=MAX_STORAGE){ - // 装備品か未所有品だったので空き欄へ追加 - for(i=0;i<MAX_STORAGE;i++){ - if(stor->storage_[i].nameid==0){ - memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0])); - stor->storage_[i].amount=amount; - stor->storage_amount++; - clif_storageitemadded(sd,stor,i,amount); - clif_updatestorageamount(sd,stor); - break; - } - } - if(i>=MAX_STORAGE) - return 1; - } - - return 0; -} -/*========================================== - * カプラ倉庫アイテムを減らす - *------------------------------------------ - */ -int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount) -{ - nullpo_retr(1, sd); - nullpo_retr(1, stor); - - if(stor->storage_[n].nameid==0 || stor->storage_[n].amount<amount) - return 1; - - stor->storage_[n].amount-=amount; - if(stor->storage_[n].amount==0){ - memset(&stor->storage_[n],0,sizeof(stor->storage_[0])); - stor->storage_amount--; - clif_updatestorageamount(sd,stor); - } - clif_storageitemremoved(sd,n,amount); - - stor->dirty = 1; - - return 0; -} -/*========================================== - * カプラ倉庫へ入れる - *------------------------------------------ - */ -int storage_storageadd(struct map_session_data *sd,int index,int amount) -{ - struct storage *stor; - - nullpo_retr(0, sd); - nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - - if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && index<MAX_INVENTORY) { // valid index - if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount -// log_tostorage(sd, index, 0); - if(storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) - // remove item from inventory - pc_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open - - return 0; -} - -/*========================================== - * カプラ倉庫から出す - *------------------------------------------ - */ -int storage_storageget(struct map_session_data *sd,int index,int amount) -{ - struct storage *stor; - int flag; - - nullpo_retr(0, sd); - nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - - if(stor->storage_status == 1) { // storage open - if(index>=0 && index<MAX_STORAGE) { // valid index - if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount - if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) - storage_delitem(sd,stor,index,amount); - else - clif_additem(sd,0,0,flag); -// log_fromstorage(sd, index, 0); - } // valid amount - }// valid index - }// storage open - - return 0; -} -/*========================================== - * カプラ倉庫へカートから入れる - *------------------------------------------ - */ -int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount) -{ - struct storage *stor; - - nullpo_retr(0, sd); - nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - - if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && index<MAX_INVENTORY) { // valid index - if( (amount <= sd->status.cart[index].amount) && (amount > 0) ) { //valid amount - if(storage_additem(sd,stor,&sd->status.cart[index],amount)==0) - pc_cart_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open - - return 0; -} - -/*========================================== - * カプラ倉庫からカートへ出す - *------------------------------------------ - */ -int storage_storagegettocart(struct map_session_data *sd,int index,int amount) -{ - struct storage *stor; - - nullpo_retr(0, sd); - nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - - if(stor->storage_status == 1) { // storage open - if(index>=0 && index<MAX_STORAGE) { // valid index - if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount - if(pc_cart_additem(sd,&stor->storage_[index],amount)==0){ - storage_delitem(sd,stor,index,amount); - } - } // valid amount - }// valid index - }// storage open - - return 0; -} - - -/*========================================== - * カプラ倉庫を閉じる - *------------------------------------------ - */ -int storage_storageclose(struct map_session_data *sd) -{ - struct storage *stor; - - nullpo_retr(0, sd); - nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - - stor->storage_status=0; - sd->state.storage_flag = 0; - clif_storageclose(sd); - - storage_storage_save(sd); - - sortage_sortitem(stor); - return 0; -} - -/*========================================== - * ログアウト時開いているカプラ倉庫の保存 - *------------------------------------------ - */ -int storage_storage_quit(struct map_session_data *sd) -{ - struct storage *stor; - - nullpo_retr(0, sd); - - stor = (struct storage *) numdb_search(storage_db,sd->status.account_id); - if(stor) { - stor->storage_status = 0; - storage_storage_save(sd); - } - - return 0; -} - -void storage_storage_dirty(struct map_session_data *sd) -{ - struct storage *stor; - - stor=(struct storage *) numdb_search(storage_db,sd->status.account_id); - - if(stor) - stor->dirty = 1; -} - -int storage_storage_save(struct map_session_data *sd) -{ - struct storage *stor; - - nullpo_retr(0, sd); - - stor=(struct storage *) numdb_search(storage_db,sd->status.account_id); - if(stor && stor->dirty) { - intif_send_storage(stor); - stor->dirty = 0; - } - - return 0; -} - -struct guild_storage *guild2storage(int guild_id) -{ - struct guild_storage *gs = NULL; - if(guild_search(guild_id) != NULL) { - gs=(struct guild_storage *) numdb_search(guild_storage_db,guild_id); - if(gs == NULL) { - gs = (struct guild_storage *) aCallocA(sizeof(struct guild_storage), 1); - if(gs==NULL){ - printf("storage: out of memory!\n"); - exit(0); - } - gs->guild_id=guild_id; - numdb_insert(guild_storage_db,gs->guild_id,gs); - } - } - return gs; -} - -int guild_storage_delete(int guild_id) -{ - struct guild_storage *gstor = (struct guild_storage *) numdb_search(guild_storage_db,guild_id); - if(gstor) { - numdb_erase(guild_storage_db,guild_id); - aFree(gstor); - } - return 0; -} - -int storage_guild_storageopen(struct map_session_data *sd) -{ - struct guild_storage *gstor; - - nullpo_retr(0, sd); - - if(sd->status.guild_id <= 0) - return 2; - if((gstor = (struct guild_storage *) numdb_search(guild_storage_db,sd->status.guild_id)) != NULL) { - if(gstor->storage_status) - return 1; - gstor->storage_status = 1; - sd->state.storage_flag = 1; - clif_guildstorageitemlist(sd,gstor); - clif_guildstorageequiplist(sd,gstor); - clif_updateguildstorageamount(sd,gstor); - return 0; - } - else { - gstor = guild2storage(sd->status.guild_id); - gstor->storage_status = 1; - intif_request_guild_storage(sd->status.account_id,sd->status.guild_id); - } - - return 0; -} - -int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount) -{ - struct item_data *data; - int i; - - nullpo_retr(1, sd); - nullpo_retr(1, stor); - nullpo_retr(1, item_data); - nullpo_retr(1, data = itemdb_search(item_data->nameid)); - - if(item_data->nameid <= 0 || amount <= 0) - return 1; - - i=MAX_GUILD_STORAGE; - if(!itemdb_isequip2(data)){ - // 装備品ではないので、既所有品なら個数のみ変化させる - for(i=0;i<MAX_GUILD_STORAGE;i++){ - if(compare_item(&stor->storage_[i], item_data)) { - if(stor->storage_[i].amount+amount > MAX_AMOUNT) - return 1; - stor->storage_[i].amount+=amount; - clif_guildstorageitemadded(sd,stor,i,amount); - break; - } - } - } - if(i>=MAX_GUILD_STORAGE){ - // 装備品か未所有品だったので空き欄へ追加 - for(i=0;i<MAX_GUILD_STORAGE;i++){ - if(stor->storage_[i].nameid==0){ - memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0])); - stor->storage_[i].amount=amount; - stor->storage_amount++; - clif_guildstorageitemadded(sd,stor,i,amount); - clif_updateguildstorageamount(sd,stor); - break; - } - } - if(i>=MAX_GUILD_STORAGE) - return 1; - } - return 0; -} - -int guild_storage_delitem(struct map_session_data *sd,struct guild_storage *stor,int n,int amount) -{ - nullpo_retr(1, sd); - nullpo_retr(1, stor); - - if(stor->storage_[n].nameid==0 || stor->storage_[n].amount<amount) - return 1; - - stor->storage_[n].amount-=amount; - if(stor->storage_[n].amount==0){ - memset(&stor->storage_[n],0,sizeof(stor->storage_[0])); - stor->storage_amount--; - clif_updateguildstorageamount(sd,stor); - } - clif_storageitemremoved(sd,n,amount); - - return 0; -} - -int storage_guild_storageadd(struct map_session_data *sd,int index,int amount) -{ - struct guild_storage *stor; - - nullpo_retr(0, sd); - - if((stor=guild2storage(sd->status.guild_id)) != NULL) { - if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && index<MAX_INVENTORY) { // valid index - if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount -// log_tostorage(sd, index, 1); - if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) - // remove item from inventory - pc_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open - } - - return 0; -} - -int storage_guild_storageget(struct map_session_data *sd,int index,int amount) -{ - struct guild_storage *stor; - int flag; - - nullpo_retr(0, sd); - - if((stor=guild2storage(sd->status.guild_id)) != NULL) { - if(stor->storage_status == 1) { // storage open - if(index>=0 && index<MAX_GUILD_STORAGE) { // valid index - if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount - if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) - guild_storage_delitem(sd,stor,index,amount); - else - clif_additem(sd,0,0,flag); -// log_fromstorage(sd, index, 1); - } // valid amount - }// valid index - }// storage open - } - - return 0; -} - -int storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int amount) -{ - struct guild_storage *stor; - - nullpo_retr(0, sd); - - if((stor=guild2storage(sd->status.guild_id)) != NULL) { - if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && index<MAX_INVENTORY) { // valid index - if( (amount <= sd->status.cart[index].amount) && (amount > 0) ) { //valid amount - if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0) - pc_cart_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open - } - - return 0; -} - -int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount) -{ - struct guild_storage *stor; - - nullpo_retr(0, sd); - - if((stor=guild2storage(sd->status.guild_id)) != NULL) { - if(stor->storage_status == 1) { // storage open - if(index>=0 && index<MAX_GUILD_STORAGE) { // valid index - if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount - if(pc_cart_additem(sd,&stor->storage_[index],amount)==0){ - guild_storage_delitem(sd,stor,index,amount); - } - } // valid amount - }// valid index - }// storage open - } - - return 0; -} - -int storage_guild_storageclose(struct map_session_data *sd) -{ - struct guild_storage *stor; - - nullpo_retr(0, sd); - - if((stor=guild2storage(sd->status.guild_id)) != NULL) { - intif_send_guild_storage(sd->status.account_id,stor); - stor->storage_status = 0; - sd->state.storage_flag = 0; - sortage_gsortitem(stor); - } - clif_storageclose(sd); - - return 0; -} - -int storage_guild_storage_quit(struct map_session_data *sd,int flag) -{ - struct guild_storage *stor; - - nullpo_retr(0, sd); - - stor = (struct guild_storage *) numdb_search(guild_storage_db,sd->status.guild_id); - if(stor) { - if(!flag) - intif_send_guild_storage(sd->status.account_id,stor); - stor->storage_status = 0; - sd->state.storage_flag = 0; - } - - return 0; -} diff --git a/src/map/storage.h b/src/map/storage.h deleted file mode 100644 index 7b2ac2cbe..000000000 --- a/src/map/storage.h +++ /dev/null @@ -1,39 +0,0 @@ -// $Id: storage.h,v 1.3 2004/09/25 05:32:19 MouseJstr Exp $ -#ifndef _STORAGE_H_ -#define _STORAGE_H_ - -#include "mmo.h" - -int storage_storageopen(struct map_session_data *sd); -int storage_storageadd(struct map_session_data *sd,int index,int amount); -int storage_storageget(struct map_session_data *sd,int index,int amount); -int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount); -int storage_storagegettocart(struct map_session_data *sd,int index,int amount); -int storage_storageclose(struct map_session_data *sd); -int do_init_storage(void); -void do_final_storage(void); -struct storage *account2storage(int account_id); -struct storage *account2storage2(int account_id); -int storage_delete(int account_id); -int storage_storage_quit(struct map_session_data *sd); -int storage_storage_save(struct map_session_data *sd); -void storage_storage_dirty(struct map_session_data *sd); - -struct guild_storage *guild2storage(int guild_id); -int guild_storage_delete(int guild_id); -int storage_guild_storageopen(struct map_session_data *sd); -int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount); -int guild_storage_delitem(struct map_session_data *sd,struct guild_storage *stor,int n,int amount); -int storage_guild_storageadd(struct map_session_data *sd,int index,int amount); -int storage_guild_storageget(struct map_session_data *sd,int index,int amount); -int storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int amount); -int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount); -int storage_guild_storageclose(struct map_session_data *sd); -int storage_guild_storage_quit(struct map_session_data *sd,int flag); - -int storage_comp_item(const void *_i1, const void *_i2); -//int storage_comp_item(const struct item* i1, const struct item* i2); -void sortage_sortitem(struct storage* stor); -void sortage_gsortitem(struct guild_storage* gstor); - -#endif diff --git a/src/map/trade.c b/src/map/trade.c deleted file mode 100644 index eb1d45ba2..000000000 --- a/src/map/trade.c +++ /dev/null @@ -1,389 +0,0 @@ -// $Id: trade.c 375 2005-03-04 21:33:31Z Yor $ -//#include <config.h> - -#include <stdio.h> -#include <string.h> - -#include "../common/nullpo.h" -#include "clif.h" -#include "itemdb.h" -#include "map.h" -#include "trade.h" -#include "pc.h" -#include "npc.h" -#include "battle.h" -#include "chrif.h" -#include "storage.h" -#include "intif.h" -#include "atcommand.h" -#include "log.h" - -/*========================================== - * 取引要請を相手に送る - *------------------------------------------ - */ -void trade_traderequest(struct map_session_data *sd, int target_id) { - struct map_session_data *target_sd; - - nullpo_retv(sd); - - if ((target_sd = map_id2sd(target_id)) != NULL) { - if (!battle_config.invite_request_check) { - if (target_sd->guild_invite > 0 || target_sd->party_invite > 0) { - clif_tradestart(sd, 2); // 相手はPT要請中かGuild要請中 - return; - } - } - if(pc_isGM(sd) && pc_isGM(target_sd) < battle_config.gm_can_drop_lv) { - clif_displaymessage(sd->fd, msg_txt(246)); - trade_tradecancel(sd); // GM is not allowed to trade - } else if ((target_sd->trade_partner != 0) || (sd->trade_partner != 0)) { - trade_tradecancel(sd); // person is in another trade - } else { - if (!pc_isGM(sd) && (sd->bl.m != target_sd->bl.m || - (sd->bl.x - target_sd->bl.x <= -5 || sd->bl.x - target_sd->bl.x >= 5) || - (sd->bl.y - target_sd->bl.y <= -5 || sd->bl.y - target_sd->bl.y >= 5))) { - clif_tradestart(sd, 0); // too far - } else if (sd != target_sd) { - target_sd->trade_partner = sd->status.account_id; - sd->trade_partner = target_sd->status.account_id; - clif_traderequest(target_sd, sd->status.name); - } - } - } else { - clif_tradestart(sd, 1); // character does not exist - } -} - -/*========================================== - * 取引要請 - *------------------------------------------ - */ -void trade_tradeack(struct map_session_data *sd, int type) { - struct map_session_data *target_sd; - struct storage *stor; - nullpo_retv(sd); - - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) { - clif_tradestart(target_sd, type); - clif_tradestart(sd, type); - if (type == 4) { // Cancel - sd->deal_locked = 0; - sd->trade_partner = 0; - target_sd->deal_locked = 0; - target_sd->trade_partner = 0; - } - if (sd->npc_id != 0) - npc_event_dequeue(sd); - if (target_sd->npc_id != 0) - npc_event_dequeue(target_sd); - - //close STORAGE window if it's open. It protects from spooffing packets [Lupus] - stor=account2storage2(sd->status.account_id); - if(stor!=NULL && stor->storage_status == 1) { - if (sd->state.storage_flag) //is it Guild Storage or Common - storage_guild_storageclose(sd); - else - storage_storageclose(sd); - }//END OF STORAGE CLOSE - } -} - -/*========================================== - * Check here hacker for duplicate item in trade - * normal client refuse to have 2 same types of item (except equipment) in same trade window - * normal client authorise only no equiped item and only from inventory - *------------------------------------------ - */ -int impossible_trade_check(struct map_session_data *sd) { - struct item inventory[MAX_INVENTORY]; - char message_to_gm[200]; - int i, index; - - nullpo_retr(0, sd); - - // get inventory of player - memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY); - -/* remove this part: arrows can be trade and equiped - // remove equiped items (they can not be trade) - for (i = 0; i < MAX_INVENTORY; i++) - if (inventory[i].nameid > 0 && inventory[i].equip) - memset(&inventory[i], 0, sizeof(struct item)); -*/ - - // check items in player inventory - for(i = 0; i < 10; i++) - if (sd->deal_item_amount[i] < 0) { // negativ? -> hack -// printf("Negativ amount in trade, by hack!\n"); // normal client send cancel when we type negativ amount - return -1; - } else if (sd->deal_item_amount[i] > 0) { - index = sd->deal_item_index[i] - 2; - inventory[index].amount -= sd->deal_item_amount[i]; // remove item from inventory -// printf("%d items left\n", inventory[index].amount); - if (inventory[index].amount < 0) { // if more than the player have -> hack -// printf("A player try to trade more items that he has: hack!\n"); - sprintf(message_to_gm, msg_txt(538), sd->status.name, sd->status.account_id); // Hack on trade: character '%s' (account: %d) try to trade more items that he has. - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm); - sprintf(message_to_gm, msg_txt(539), sd->status.inventory[index].amount, sd->status.inventory[index].nameid, sd->status.inventory[index].amount - inventory[index].amount); // This player has %d of a kind of item (id: %d), and try to trade %d of them. - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm); - // if we block people - if (battle_config.ban_hack_trade < 0) { - chrif_char_ask_name(-1, sd->status.name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block - clif_setwaitclose(sd->fd); // forced to disconnect because of the hack - // message about the ban - sprintf(message_to_gm, msg_txt(540), battle_config.ban_spoof_namer); // This player has been definitivly blocked. - // if we ban people - } else if (battle_config.ban_hack_trade > 0) { - chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_hack_trade, 0); // type: 2 - ban (year, month, day, hour, minute, second) - clif_setwaitclose(sd->fd); // forced to disconnect because of the hack - // message about the ban - sprintf(message_to_gm, msg_txt(507), battle_config.ban_spoof_namer); // This player has been banned for %d minute(s). - } else { - // message about the ban - sprintf(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled). - } - intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm); - return 1; - } - } - - return 0; -} - -/*========================================== - * アイテム追加 - *------------------------------------------ - */ -void trade_tradeadditem(struct map_session_data *sd, int index, int amount) { - struct map_session_data *target_sd; - int trade_i; - int trade_weight = 0; - int c; - - nullpo_retv(sd); - - if (((target_sd = map_id2sd(sd->trade_partner)) != NULL) && (sd->deal_locked < 1)){ - if (index < 2 || index >= MAX_INVENTORY + 2) { - if (index == 0) { - if (amount > 0 && amount <= MAX_ZENY && amount <= sd->status.zeny && // check amount - (target_sd->status.zeny + amount) <= MAX_ZENY) { // fix positiv overflow - sd->deal_zeny = amount; - clif_tradeadditem(sd, target_sd, 0, amount); - } else { - if (amount != 0) { - trade_tradecancel(sd); - return; - } - } - } - } else if (amount > 0 && amount <= sd->status.inventory[index-2].amount) { - for(trade_i = 0; trade_i < 10; trade_i++) { - if (sd->deal_item_amount[trade_i] == 0) { - trade_weight += sd->inventory_data[index-2]->weight * amount; - if (target_sd->weight + trade_weight > target_sd->max_weight){ - clif_tradeitemok(sd, index, 1); // fail to add item -- the player was over weighted. - amount = 0; - } else { - for(c = 0; c == trade_i - 1; c++) { // re-deal exploit protection [Valaris] - if (sd->deal_item_index[c] == index) { - trade_tradecancel(sd); - return; - } - } - sd->deal_item_index[trade_i] = index; - sd->deal_item_amount[trade_i] += amount; - if (impossible_trade_check(sd)) { // check exploit (trade more items that you have) - trade_tradecancel(sd); - return; - } - clif_tradeitemok(sd, index, 0); // success to add item - clif_tradeadditem(sd, target_sd, index, amount); - } - break; - } else { - trade_weight += sd->inventory_data[sd->deal_item_index[trade_i]-2]->weight * sd->deal_item_amount[trade_i]; - } - } - } - } -} - -/*========================================== - * アイテム追加完了(ok押し) - *------------------------------------------ - */ -void trade_tradeok(struct map_session_data *sd) { - struct map_session_data *target_sd; - int trade_i; - - nullpo_retv(sd); - - // check items - for(trade_i = 0; trade_i < 10; trade_i++) { - if ((((sd->deal_item_index[trade_i]-2) >= 0) && - (sd->deal_item_amount[trade_i] > sd->status.inventory[sd->deal_item_index[trade_i]-2].amount)) || - (sd->deal_item_amount[trade_i] < 0)) { - trade_tradecancel(sd); - return; - } - } - - // check exploit (trade more items that you have) - if (impossible_trade_check(sd)) { - trade_tradecancel(sd); - return; - } - - // check zeny - if (sd->deal_zeny < 0 || sd->deal_zeny > MAX_ZENY || sd->deal_zeny > sd->status.zeny) { // check amount - trade_tradecancel(sd); - return; - } - - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) { - sd->deal_locked = 1; - clif_tradeitemok(sd, 0, 0); - clif_tradedeal_lock(sd, 0); - clif_tradedeal_lock(target_sd, 1); - } -} - -/*========================================== - * 取引キャンセル - *------------------------------------------ - */ -void trade_tradecancel(struct map_session_data *sd) { - struct map_session_data *target_sd; - int trade_i; - - nullpo_retv(sd); - - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) { - for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual) - if (sd->deal_item_amount[trade_i] != 0) { - clif_additem(sd, sd->deal_item_index[trade_i] - 2, sd->deal_item_amount[trade_i], 0); - sd->deal_item_index[trade_i] = 0; - sd->deal_item_amount[trade_i] = 0; - } - if (target_sd->deal_item_amount[trade_i] != 0) { - clif_additem(target_sd, target_sd->deal_item_index[trade_i] - 2, target_sd->deal_item_amount[trade_i], 0); - target_sd->deal_item_index[trade_i] = 0; - target_sd->deal_item_amount[trade_i] = 0; - } - } - if (sd->deal_zeny) { - clif_updatestatus(sd, SP_ZENY); - sd->deal_zeny = 0; - } - if (target_sd->deal_zeny) { - clif_updatestatus(target_sd, SP_ZENY); - target_sd->deal_zeny = 0; - } - sd->deal_locked = 0; - sd->trade_partner = 0; - target_sd->deal_locked = 0; - target_sd->trade_partner = 0; - clif_tradecancelled(sd); - clif_tradecancelled(target_sd); - } -} - -/*========================================== - * 取引許諾(trade押し) - *------------------------------------------ - */ -void trade_tradecommit(struct map_session_data *sd) { - struct map_session_data *target_sd; - int trade_i; - int flag; - - nullpo_retv(sd); - - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) { - if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1)) { // both have pressed 'ok' - if (sd->deal_locked < 2) { // set locked to 2 - sd->deal_locked = 2; - } - if (target_sd->deal_locked == 2) { // the other one pressed 'trade' too - // check exploit (trade more items that you have) - if (impossible_trade_check(sd)) { - trade_tradecancel(sd); - return; - } - // check exploit (trade more items that you have) - if (impossible_trade_check(target_sd)) { - trade_tradecancel(target_sd); - return; - } - // check zenys value against hackers - if (sd->deal_zeny >= 0 && sd->deal_zeny <= MAX_ZENY && sd->deal_zeny <= sd->status.zeny && // check amount - (target_sd->status.zeny + sd->deal_zeny) <= MAX_ZENY && // fix positiv overflow - target_sd->deal_zeny >= 0 && target_sd->deal_zeny <= MAX_ZENY && target_sd->deal_zeny <= target_sd->status.zeny && // check amount - (sd->status.zeny + target_sd->deal_zeny) <= MAX_ZENY) { // fix positiv overflow - - // trade is accepted - for(trade_i = 0; trade_i < 10; trade_i++) { - if (sd->deal_item_amount[trade_i] != 0) { - int n = sd->deal_item_index[trade_i] - 2; - - if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i]) - sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount; - log_trade(sd, target_sd, n, sd->deal_item_amount[trade_i]); - - flag = pc_additem(target_sd, &sd->status.inventory[n], sd->deal_item_amount[trade_i]); - if (flag == 0) - pc_delitem(sd, n, sd->deal_item_amount[trade_i], 1); - else - clif_additem(sd, n, sd->deal_item_amount[trade_i], 0); - sd->deal_item_index[trade_i] = 0; - sd->deal_item_amount[trade_i] = 0; - - } - if (target_sd->deal_item_amount[trade_i] != 0) { - int n = target_sd->deal_item_index[trade_i] - 2; - - if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i]) - target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount; - - log_trade(target_sd, sd, n, target_sd->deal_item_amount[trade_i]); - flag = pc_additem(sd, &target_sd->status.inventory[n], target_sd->deal_item_amount[trade_i]); - if (flag == 0) - pc_delitem(target_sd, n, target_sd->deal_item_amount[trade_i], 1); - else - clif_additem(target_sd, n, target_sd->deal_item_amount[trade_i], 0); - target_sd->deal_item_index[trade_i] = 0; - target_sd->deal_item_amount[trade_i] = 0; - } - } - if (sd->deal_zeny) { - sd->status.zeny -= sd->deal_zeny; - target_sd->status.zeny += sd->deal_zeny; - } - if (target_sd->deal_zeny) { - target_sd->status.zeny -= target_sd->deal_zeny; - sd->status.zeny += target_sd->deal_zeny; - } - if (sd->deal_zeny || target_sd->deal_zeny) { - clif_updatestatus(sd, SP_ZENY); - sd->deal_zeny = 0; - clif_updatestatus(target_sd, SP_ZENY); - target_sd->deal_zeny = 0; - } - sd->deal_locked = 0; - sd->trade_partner = 0; - target_sd->deal_locked = 0; - target_sd->trade_partner = 0; - clif_tradecompleted(sd, 0); - clif_tradecompleted(target_sd, 0); - // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players - chrif_save(sd); // do pc_makesavestatus and save storage too - chrif_save(target_sd); // do pc_makesavestatus and save storage too - // zeny value was modified!!!! hacker with packet modified - } else { - trade_tradecancel(sd); - } - } - } - } -} diff --git a/src/map/trade.h b/src/map/trade.h deleted file mode 100644 index 01cbce7eb..000000000 --- a/src/map/trade.h +++ /dev/null @@ -1,13 +0,0 @@ -// $Id: trade.h,v 1.2 2004/09/25 05:32:19 MouseJstr Exp $ -#ifndef _TRADE_H_ -#define _TRADE_H_ - -#include "map.h" -void trade_traderequest(struct map_session_data *sd,int target_id); -void trade_tradeack(struct map_session_data *sd,int type); -void trade_tradeadditem(struct map_session_data *sd,int index,int amount); -void trade_tradeok(struct map_session_data *sd); -void trade_tradecancel(struct map_session_data *sd); -void trade_tradecommit(struct map_session_data *sd); - -#endif // _TRADE_H_ diff --git a/src/map/vending.c b/src/map/vending.c deleted file mode 100644 index 2d3790596..000000000 --- a/src/map/vending.c +++ /dev/null @@ -1,175 +0,0 @@ -// $Id: vending.c,v 1.2 2004/09/25 05:32:19 MouseJstr Exp $ -#include <stdio.h> -#include <string.h> - -#include "clif.h" -#include "itemdb.h" -#include "map.h" -#include "vending.h" -#include "pc.h" -#include "skill.h" -#include "battle.h" -#include "nullpo.h" -#include "log.h" - -/*========================================== - * 露店閉鎖 - *------------------------------------------ -*/ -void vending_closevending(struct map_session_data *sd) -{ - - nullpo_retv(sd); - - sd->vender_id=0; - clif_closevendingboard(&sd->bl,0); -} - -/*========================================== - * 露店アイテムリスト要求 - *------------------------------------------ - */ -void vending_vendinglistreq(struct map_session_data *sd,int id) -{ - struct map_session_data *vsd; - - nullpo_retv(sd); - - if( (vsd=map_id2sd(id)) == NULL ) - return; - if(vsd->vender_id==0) - return; - clif_vendinglist(sd,id,vsd->vending); -} - -/*========================================== - * 露店アイテム購入 - *------------------------------------------ - */ -void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned char *p) -{ - int i, j, w, z, new_ = 0, blank, vend_list[12]; - short amount, index; - struct map_session_data *vsd = map_id2sd(id); - - nullpo_retv(sd); - - blank = pc_inventoryblank(sd); - - if (vsd == NULL) - return; - if (vsd->vender_id == 0) - return; - if (vsd->vender_id == sd->bl.id) - return; - for(i = 0, w = z = 0; 8 + 4 * i < len; i++) { - amount = *(short*)(p + 4 * i); - index = *(short*)(p + 2 + 4 * i) - 2; - - if (amount < 0) return; // exploit -/* for(j = 0; j < vsd->vend_num; j++) - if (0 < vsd->vending[j].amount && amount <= vsd->vending[j].amount && vsd->vending[j].index == index) - break; -*/ -//ADD_start - for(j = 0; j < vsd->vend_num; j++) { - if (0 < vsd->vending[j].amount && vsd->vending[j].index == index) { - if (amount > vsd->vending[j].amount || amount <= 0) { - clif_buyvending(sd,index,vsd->vending[j].amount, 4); - return; - } - if (amount <= vsd->vending[j].amount) break; - } - } -//ADD_end - if (j == vsd->vend_num) - return; // 売り切れ - vend_list[i] = j; - z += vsd->vending[j].value * amount; - if (z > sd->status.zeny){ - clif_buyvending(sd, index, amount, 1); - return; // zeny不足 - } - w += itemdb_weight(vsd->status.cart[index].nameid) * amount; - if (w + sd->weight > sd->max_weight) { - clif_buyvending(sd, index, amount, 2); - return; // 重量超過 - } - switch(pc_checkadditem(sd, vsd->status.cart[index].nameid, amount)) { - case ADDITEM_EXIST: - break; - case ADDITEM_NEW: - new_++; - if (new_ > blank) - return; // 種類数超過 - break; - case ADDITEM_OVERAMOUNT: - return; // アイテム数超過 - } - } - if (z < 0 || z > MAX_ZENY) { // Zeny Bug Fixed by Darkchild - clif_tradecancelled(sd); - clif_tradecancelled(vsd); - return; - } - - pc_payzeny(sd, z); - pc_getzeny(vsd, z); - for(i = 0; 8 + 4 * i < len; i++) { - amount = *(short*)(p + 4 *i); - index = *(short*)(p + 2 + 4 * i) - 2; - //if (amount < 0) break; // tested at start of the function - pc_additem(sd,&vsd->status.cart[index],amount); - vsd->vending[vend_list[i]].amount -= amount; - pc_cart_delitem(vsd, index, amount, 0); - clif_vendingreport(vsd, index, amount); - - //log added by Lupus - if(log_config.vend > 0) { - log_vend(sd,vsd, index, amount, z); // for Item + Zeny. log. - //we log ZENY only with the 1st item. Then zero it for the rest items 8). - z = 0; - } - } -} - -/*========================================== - * 露店開設 - *------------------------------------------ - */ -void vending_openvending(struct map_session_data *sd,int len,char *message,int flag,unsigned char *p) -{ - int i; - - nullpo_retv(sd); - - if(!pc_checkskill(sd,MC_VENDING) || !pc_iscarton(sd)) { // cart skill and cart check [Valaris] - clif_skill_fail(sd,MC_VENDING,0,0); - return; - } - - if (flag) { - for(i = 0; (85 + 8 * i < len) && (i < MAX_VENDING); i++) { - sd->vending[i].index = *(short*)(p+8*i)-2; - sd->vending[i].amount = *(short*)(p+2+8*i); - sd->vending[i].value = *(int*)(p+4+8*i); - if(sd->vending[i].value > battle_config.vending_max_value) - sd->vending[i].value=battle_config.vending_max_value; - else if(sd->vending[i].value == 0) - sd->vending[i].value = 1000000; // auto set to 1 million [celest] - // カート内のアイテム数と販売するアイテム数に相違があったら中止 - if(pc_cartitem_amount(sd, sd->vending[i].index, sd->vending[i].amount) < 0 || sd->vending[i].value < 0) { // fixes by Valaris and fritz - clif_skill_fail(sd, MC_VENDING, 0, 0); - return; - } - } - sd->vender_id = sd->bl.id; - sd->vend_num = i; - strcpy(sd->message,message); - if (clif_openvending(sd,sd->vender_id,sd->vending) > 0) - clif_showvendingboard(&sd->bl,message,0); - else - sd->vender_id = 0; - } -} - diff --git a/src/map/vending.h b/src/map/vending.h deleted file mode 100644 index 41aa731bb..000000000 --- a/src/map/vending.h +++ /dev/null @@ -1,12 +0,0 @@ -// $Id: vending.h,v 1.2 2004/09/25 05:32:19 MouseJstr Exp $ -#ifndef _VENDING_H_ -#define _VENDING_H_ - -#include "map.h" - -void vending_closevending(struct map_session_data *sd); -void vending_openvending(struct map_session_data *sd,int len,char *message,int flag,unsigned char *p); -void vending_vendinglistreq(struct map_session_data *sd,int id); -void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned char *p); - -#endif // _VENDING_H_ |