From f56cd8a8b05817d725e44143654d2256e440b236 Mon Sep 17 00:00:00 2001 From: Fate Date: Thu, 17 Sep 2009 16:12:21 +0000 Subject: MRAND now wraps its modulo parameter in parentheses to avoid misassociation --- src/common/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/utils.h b/src/common/utils.h index 0b006c3..88d1027 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -38,5 +38,5 @@ * MRAND(10), returns 0-9. * MPRAND(5,10) returns 5-14. */ -#define MRAND(mod) (int) (mt_random() % mod) +#define MRAND(mod) (int) (mt_random() % (mod)) #define MPRAND(add, mod) add + MRAND(mod) -- cgit v1.2.3-70-g09d2 From b3939b91deda8081c5b144109829599b05e81272 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 17 Sep 2009 11:21:23 -0600 Subject: Prevent trading with other players who are shoping --- src/map/trade.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/trade.c b/src/map/trade.c index 31f29ce..9e99ef1 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -28,7 +28,7 @@ void trade_traderequest(struct map_session_data *sd,int target_id) return; } } - if (target_sd->npc_id) + if (target_sd->npc_id || target_sd->npc_shopid) { //Trade fails if you are using an NPC. clif_tradestart(sd, 2); -- cgit v1.2.3-70-g09d2 From 41075d30353cd42588975cfbc8a21a69911ad4cc Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Fri, 18 Sep 2009 15:49:51 -0600 Subject: Replace basic skill with three new skills We want to handle skills differently that eAthena was made too. All new skills are leveled by NPCs instead of using the job sysetm. Also fixes some bugs. --- src/map/clif.c | 38 ++++++++++++++++---------------------- src/map/party.c | 10 ++++++++-- src/map/pc.c | 14 ++++++++------ src/map/skill.c | 4 +++- src/map/skill.h | 9 ++++----- 5 files changed, 39 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 401f6cc..6457e9b 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3741,7 +3741,7 @@ int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int 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) ) + if(skill_get_inf2(id)&0x01) WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_get_max(id) && sd->status.skill[skillid].flag ==0 )? 1:0; else WFIFOB(fd,38) = 0; @@ -3765,8 +3765,7 @@ int clif_skillinfoblock(struct map_session_data *sd) WFIFOW(fd,0)=0x10f; for ( i = c = 0; i < MAX_SKILL; i++){ if( (id=sd->status.skill[i].id)!=0 - && (sd->tmw_version >= 1 // [Fate] Version 1 and later don't crash because of bad skill IDs anymore - || !QUEST_SKILL(i))){ // [Fate] Hack: Prevent killing the client + && (sd->tmw_version >= 1)){ // [Fate] Version 1 and later don't crash because of bad skill IDs anymore WFIFOW(fd,len ) = id; WFIFOW(fd,len+2) = skill_get_inf(id); WFIFOW(fd,len+4) = 0; @@ -3777,7 +3776,7 @@ int clif_skillinfoblock(struct map_session_data *sd) range = battle_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) ) + if(skill_get_inf2(id)&0x01) WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max(id) && sd->status.skill[i].flag ==0 )? 1:0; else WFIFOB(fd,len+36) = 0; @@ -6648,7 +6647,7 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd) { nullpo_retv(sd); - if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) { + if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_EMOTE) >= 1) { WBUFW(buf,0) = 0xc0; WBUFL(buf,2) = sd->bl.id; WBUFB(buf,6) = RFIFOB(fd,2); @@ -6715,15 +6714,12 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd) { 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) { - if (tmw_CheckSitSpam(sd)) - break; - pc_stop_walking(sd, 1); - skill_gangsterparadise(sd, 1); // �M�����O�X�^�[�p���_�C�X�ݒ� - pc_setsit(sd); - clif_sitting(fd, sd); - } else - clif_skill_fail(sd, 1, 0, 2); + if (tmw_CheckSitSpam(sd)) + break; + pc_stop_walking(sd, 1); + skill_gangsterparadise(sd, 1); // �M�����O�X�^�[�p���_�C�X�ݒ� + pc_setsit(sd); + clif_sitting(fd, sd); break; case 0x03: // standup skill_gangsterparadise(sd, 0); // �M�����O�X�^�[�p���_�C�X���� @@ -7072,10 +7068,7 @@ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd) */ 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),RFIFOP(fd,7),RFIFOP(fd,15),RFIFOW(fd,2)-15); - } else - clif_skill_fail(sd,1,0,3); + chat_createchat(sd,RFIFOW(fd,4),RFIFOB(fd,6),RFIFOP(fd,7),RFIFOP(fd,15),RFIFOW(fd,2)-15); } /*========================================== @@ -7131,7 +7124,7 @@ 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){ + if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_TRADE) >= 1){ if (tmw_CheckTradeSpam(sd)) return; trade_traderequest(sd,RFIFOL(sd->fd,2)); @@ -7664,7 +7657,7 @@ void clif_parse_CloseKafra(int fd, struct map_session_data *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) { + if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_PARTY) >= 2) { party_create(sd,RFIFOP(fd,2)); } else clif_skill_fail(sd,1,0,4); @@ -7675,7 +7668,7 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd) { *------------------------------------------ */ void clif_parse_CreateParty2(int fd, struct map_session_data *sd) { - if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7){ + if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_PARTY) >= 2){ party_create(sd, RFIFOP(fd,2)); } else clif_skill_fail(sd, 1, 0, 4); @@ -7686,6 +7679,7 @@ void clif_parse_CreateParty2(int fd, struct map_session_data *sd) { *------------------------------------------ */ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { + printf("Party Invite!\n"); party_invite(sd, RFIFOL(fd,2)); } @@ -7694,7 +7688,7 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { *------------------------------------------ */ void clif_parse_ReplyPartyInvite(int fd,struct map_session_data *sd) { - if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 5){ + if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_PARTY) >= 1){ party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6)); } else { party_reply_invite(sd,RFIFOL(fd,2),-1); diff --git a/src/map/party.c b/src/map/party.c index feacc25..62b30d8 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -14,6 +14,7 @@ #include "battle.h" #include "intif.h" #include "clif.h" +#include "skill.h" #ifdef MEMWATCH #include "memwatch.h" @@ -203,23 +204,28 @@ int party_invite(struct map_session_data *sd,int account_id) if(tsd==NULL || p==NULL) return 0; + + printf("\tA\n"); + if(!battle_config.invite_request_check) { - if (tsd->guild_invite>0 || tsd->trade_partner) { // 肪ǂ + if (tsd->guild_invite>0 || tsd->trade_partner || tsd->npc_id || tsd->npc_shopid || pc_checkskill(tsd,NV_PARTY) < 1) { clif_party_inviteack(sd,tsd->status.name,0); return 0; } } + printf("\tB\n"); if( tsd->status.party_id>0 || tsd->party_invite>0 ){ // ̏mF clif_party_inviteack(sd,tsd->status.name,0); return 0; } + printf("\tC\n"); for(i=0;imember[i].account_id==account_id){ clif_party_inviteack(sd,tsd->status.name,0); return 0; } } - + printf("\tD\n"); tsd->party_invite=sd->status.party_id; tsd->party_invite_account=sd->status.account_id; diff --git a/src/map/pc.c b/src/map/pc.c index acec322..7d083d1 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -881,7 +881,7 @@ static int pc_calc_skillpoint(struct map_session_data* sd) for(i=1;i 0) { - if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) { + if(skill_get_inf2(i)&0x01) { if(!sd->status.skill[i].flag) skill_point += skill; else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) { @@ -997,6 +997,7 @@ int pc_calc_skilltree(struct map_session_data *sd) } } + /*Comment this out for now, as we manage skills differently for(i=0;i TMW_MAGIC_END){ // [Fate] This hack gets TMW magic working and persisted without bothering about the skill tree. if (sd->status.skill[i].flag != 13) sd->status.skill[i].id=0; @@ -1005,6 +1006,7 @@ int pc_calc_skilltree(struct map_session_data *sd) sd->status.skill[i].flag=0; // flag��0�ɂ��Ă��� } } + */ if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){ // �S�ẴX�L�� @@ -4761,8 +4763,8 @@ int pc_skillup(struct map_session_data *sd,int skill_num) if( sd->status.skill_point>0 && sd->status.skill[skill_num].id!=0 && - sd->status.skill[skill_num].lv < skill_get_max(skill_num) - && (skill_num < TMW_MAGIC || skill_num > TMW_MAGIC_END)) // [Fate] Hack: Prevent exploit for raising magic levels + sd->status.skill[skill_num].lv < skill_get_max(skill_num) && + skill_get_inf2(skill_num) & 0x01) { sd->status.skill[skill_num].lv++; sd->status.skill_point--; @@ -4811,7 +4813,7 @@ int pc_allskillup(struct map_session_data *sd) } 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) ) + if(sd->status.skill[id].id==0 && skill_get_inf2(id)&0x01 ) sd->status.skill[id].lv=skill_get_max(id); } } @@ -4969,8 +4971,8 @@ int pc_resetskill(struct map_session_data* sd) for(i=1;i 0) { - if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) { - if(!sd->status.skill[i].flag && !QUEST_SKILL(i)) + if(skill_get_inf2(i)&0x01) { + 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); diff --git a/src/map/skill.c b/src/map/skill.c index 778acea..22b8dcf 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -524,7 +524,9 @@ struct skill_name_db skill_names[] = { { NPC_TRANSFORMATION, "TRANSFORMATION", "NPC_TRANSFORMATION" } , { NPC_WATERATTACK, "WATERATTACK", "NPC_WATERATTACK" } , { NPC_WINDATTACK, "WINDATTACK", "NPC_WINDATTACK" } , - { NV_BASIC, "BASIC", "Basic_Skill" } , + { NV_EMOTE, "EMOTE", "Emote_Skill" } , + { NV_TRADE, "TRADE", "Trade_Skill" } , + { NV_PARTY, "PARTY", "Party_Skill" } , { NV_FIRSTAID, "FIRSTAID", "First Aid" } , { NV_TRICKDEAD, "TRICKDEAD", "Play_Dead" } , { PA_GOSPEL, "GOSPEL", "Gospel" } , diff --git a/src/map/skill.h b/src/map/skill.h index fdbe799..d0486f5 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -10,9 +10,6 @@ #define MAX_SKILL_ARROW_DB 150 #define MAX_SKILL_ABRA_DB 350 -#define QUEST_SKILL(i) ((i) >= TMW_MAGIC && (i) < TMW_MAGIC_END) -// [Fate] A `quest skill' is a skill handled via quests, i.e., one that can't be modified via skill points. - // XLf[^x[X struct skill_db { int range[MAX_SKILL_LEVEL],hit,inf,pl,nk,max; @@ -323,7 +320,9 @@ enum { // struct map_session_data extern int SkillStatusChangeTable[]; enum { - NV_BASIC = 1, + NV_EMOTE = 1, + NV_TRADE, + NV_PARTY, SM_SWORD, SM_TWOHAND, @@ -677,7 +676,7 @@ enum { DC_FORTUNEKISS, DC_SERVICEFORYOU, - NPC_SELFDESTRUCTION2 = 331, + NPC_SELFDESTRUCTION2 = 333, WE_MALE = 334, WE_FEMALE, -- cgit v1.2.3-70-g09d2 From 162c84a85c288bcb97df44d08e0c0ff271ec102b Mon Sep 17 00:00:00 2001 From: Fate Date: Sat, 19 Sep 2009 19:02:47 +0000 Subject: When zipping server logs, zip with -f to overwrite --- src/map/map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/map.c b/src/map/map.c index 31f269d..abb750f 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1668,7 +1668,7 @@ map_close_logfile() { if (map_logfile) { char *filenameop_buf = malloc(strlen(map_logfile_name) + 50); - sprintf(filenameop_buf, "gzip %s.%ld", map_logfile_name, map_logfile_index); + sprintf(filenameop_buf, "gzip -f %s.%ld", map_logfile_name, map_logfile_index); fclose(map_logfile); -- cgit v1.2.3-70-g09d2 From 264bf4fd6dfb501643cf9178e5471e9e0e55152b Mon Sep 17 00:00:00 2001 From: Fate Date: Sun, 20 Sep 2009 00:30:15 +0000 Subject: Initial support for skill pools --- doc/script_ref.txt | 22 +++++++++++ src/map/Makefile | 3 +- src/map/battle.c | 15 ++++++++ src/map/battle.h | 1 + src/map/clif.c | 2 +- src/map/pc.c | 16 +++----- src/map/script.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/skill.c | 62 +++++++++++++++++++++++++++---- src/map/skill.h | 28 +++++++++++++- 9 files changed, 235 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/doc/script_ref.txt b/doc/script_ref.txt index 6c9f3f9..c24ac57 100644 --- a/doc/script_ref.txt +++ b/doc/script_ref.txt @@ -1257,6 +1257,28 @@ AthenaNPCScript misceffect Shows the effect with id on name. if name is omitted show on NPC. + + getskilllist + Computes the set of all skills that the player has access to. + Results are written into @skilllist_id[], @skilllist_lv[], @skilllist_flag[], + which have a total of @skilllist_count entries. + + getpoolskilllist + Same as getskilllist, but only list pool skills, and also set set + @skilllist_name$[] to the skills' names. + Note that flag & 1 here indicates that the spell is activated. + + getactivatedpoolskilllist + Same as getpoolskilllist, but only list activated pool skills. + + poolskill (skill_nr) + Moves the specified skill into the skill pool, if possible + + unpoolskill (skill_nr) + Moves the specified skill out of the skill pool, if possible + + checkpoolskill (skill_nr) + Checks whether the specified skill is in the skill pool (returns nonzero if so) *定数ラベル -ラベル diff --git a/src/map/Makefile b/src/map/Makefile index 7fe6876..5e80410 100644 --- a/src/map/Makefile +++ b/src/map/Makefile @@ -11,7 +11,7 @@ obj: 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/mt_rand.o LIBS = -lz -lm -map-server: obj/tmw.o obj/magic-interpreter-lexer.o obj/magic-interpreter-parser.o obj/magic-interpreter-base.o obj/magic-expr.o obj/magic-stmt.o obj/magic.o obj/map.o obj/chrif.o obj/clif.o obj/pc.o obj/npc.o obj/chat.o obj/path.o obj/itemdb.o obj/mob.o obj/script.o obj/storage.o obj/skill.o obj/atcommand.o obj/battle.o obj/intif.o obj/trade.o obj/party.o obj/guild.o $(COMMON_OBJ) +map-server: obj/tmw.o obj/magic-interpreter-lexer.o obj/magic-interpreter-parser.o obj/magic-interpreter-base.o obj/magic-expr.o obj/magic-stmt.o obj/magic.o obj/map.o obj/chrif.o obj/clif.o obj/pc.o obj/npc.o obj/chat.o obj/path.o obj/itemdb.o obj/mob.o obj/script.o obj/storage.o obj/skill.o obj/skill-pools.o obj/atcommand.o obj/battle.o obj/intif.o obj/trade.o obj/party.o obj/guild.o $(COMMON_OBJ) $(CC) -o ../../$@ $> $(LIBS) obj/%.o: %.c @@ -41,6 +41,7 @@ obj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h obj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h battle.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h obj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h obj/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 +obj/skill-pools.o: skill-pools.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h ../common/timer.h ../common/mmo.h obj/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 ../common/socket.h ../common/timer.h ../common/mmo.h obj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h guild.h ../common/timer.h ../common/mmo.h obj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h ../common/socket.h ../common/mmo.h diff --git a/src/map/battle.c b/src/map/battle.c index ebc395d..507defd 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1134,6 +1134,21 @@ int battle_get_mexp(struct block_list *bl) return 0; } +int battle_get_stat(int stat_id /* SP_VIT or similar */, struct block_list *bl) +{ + switch (stat_id) { + case SP_STR: return battle_get_str(bl); + case SP_AGI: return battle_get_agi(bl); + case SP_DEX: return battle_get_dex(bl); + case SP_VIT: return battle_get_vit(bl); + case SP_INT: return battle_get_int(bl); + case SP_LUK: return battle_get_luk(bl); + default: + return 0; + } +} + + // StatusChangen̏ struct status_change *battle_get_sc_data(struct block_list *bl) { diff --git a/src/map/battle.h b/src/map/battle.h index b58e80c..6ff45d0 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -100,6 +100,7 @@ int battle_get_race(struct block_list *bl); int battle_get_size(struct block_list *bl); int battle_get_mode(struct block_list *bl); int battle_get_mexp(struct block_list *bl); +int battle_get_stat(int stat_id /* SP_VIT or similar */, struct block_list *bl); struct status_change *battle_get_sc_data(struct block_list *bl); short *battle_get_sc_count(struct block_list *bl); diff --git a/src/map/clif.c b/src/map/clif.c index 6457e9b..ce86cff 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3768,7 +3768,7 @@ int clif_skillinfoblock(struct map_session_data *sd) && (sd->tmw_version >= 1)){ // [Fate] Version 1 and later don't crash because of bad skill IDs anymore WFIFOW(fd,len ) = id; WFIFOW(fd,len+2) = skill_get_inf(id); - WFIFOW(fd,len+4) = 0; + WFIFOW(fd,len+4) = skill_db[i].poolflags | (sd->status.skill[i].flag & (SKILL_POOL_ACTIVATED)); 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); diff --git a/src/map/pc.c b/src/map/pc.c index 7d083d1..51165ea 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4756,18 +4756,12 @@ int pc_skillup(struct map_session_data *sd,int skill_num) { nullpo_retr(0, sd); - if( skill_num>=10000 ){ - guild_skillup(sd,skill_num); - 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) && - skill_get_inf2(skill_num) & 0x01) - { + if (sd->status.skill[skill_num].id !=0 + && sd->status.skill_point > sd->status.skill[skill_num].lv + && sd->status.skill[skill_num].lv < skill_db[skill_num].max_raise) { sd->status.skill[skill_num].lv++; - sd->status.skill_point--; + sd->status.skill_point -= sd->status.skill[skill_num].lv; + pc_calcstatus(sd,0); clif_skillup(sd,skill_num); clif_updatestatus(sd,SP_SKILLPOINT); diff --git a/src/map/script.c b/src/map/script.c index 40fcd62..87336a2 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -255,6 +255,13 @@ int buildin_getanchorinvocation(struct script_state *st); // [Fate] int buildin_getexp(struct script_state *st); int buildin_getinventorylist(struct script_state *st); int buildin_getskilllist(struct script_state *st); +int buildin_get_pool_skills(struct script_state *st); // [fate] +int buildin_get_activated_pool_skills(struct script_state *st); // [fate] +int buildin_activate_pool_skill(struct script_state *st); // [fate] +int buildin_deactivate_pool_skill(struct script_state *st); // [fate] +int buildin_check_pool_skill(struct script_state *st); // [fate] +int buildin_getskilllist(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); @@ -464,6 +471,11 @@ struct { {buildin_getexp,"getexp","ii"}, {buildin_getinventorylist,"getinventorylist",""}, {buildin_getskilllist,"getskilllist",""}, + {buildin_get_activated_pool_skills,"getpoolskilllist",""}, + {buildin_get_pool_skills,"getactivatedpoolskilllist",""}, + {buildin_activate_pool_skill,"poolskill","i"}, + {buildin_deactivate_pool_skill,"unpoolskill","i"}, + {buildin_check_pool_skill,"checkpoolskill","i"}, {buildin_clearitem,"clearitem",""}, {buildin_classchange,"classchange","ii"}, {buildin_misceffect,"misceffect","i*"}, @@ -5520,6 +5532,101 @@ int buildin_getskilllist(struct script_state *st) return 0; } + + +int +buildin_get_activated_pool_skills(struct script_state *st) +{ + struct map_session_data *sd=script_rid2sd(st); + int pool_skills[MAX_SKILL_POOL]; + int skill_pool_size = skill_pool(sd, pool_skills); + int i, count = 0; + + if (!sd) + return 0; + + for (i = 0; i < skill_pool_size; i++) { + int skill_id = pool_skills[i]; + + if (sd->status.skill[skill_id].id == skill_id) { + pc_setreg(sd,add_str("@skilllist_id")+(count<<24),sd->status.skill[skill_id].id); + pc_setreg(sd,add_str("@skilllist_lv")+(count<<24),sd->status.skill[skill_id].lv); + pc_setreg(sd,add_str("@skilllist_flag")+(count<<24),sd->status.skill[skill_id].flag); + pc_setregstr(sd, add_str("@skilllist_name$")+(count<<24), skill_name(skill_id)); + ++count; + } + } + pc_setreg(sd,add_str("@skilllist_count"),count); + + return 0; +} + +extern int skill_pool_skills[]; +extern int skill_pool_skills_size; + +int +buildin_get_pool_skills(struct script_state *st) +{ + struct map_session_data *sd=script_rid2sd(st); + int i, count = 0; + + if (!sd) + return 0; + + for (i = 0; i < skill_pool_skills_size; i++) { + int skill_id = skill_pool_skills[i]; + + if (sd->status.skill[skill_id].id == skill_id) { + pc_setreg(sd,add_str("@skilllist_id")+(count<<24),sd->status.skill[skill_id].id); + pc_setreg(sd,add_str("@skilllist_lv")+(count<<24),sd->status.skill[skill_id].lv); + pc_setreg(sd,add_str("@skilllist_flag")+(count<<24),sd->status.skill[skill_id].flag); + pc_setregstr(sd, add_str("@skilllist_name$")+(count<<24), skill_name(skill_id)); + ++count; + } + } + pc_setreg(sd,add_str("@skilllist_count"),count); + + return 0; +} + +int +buildin_activate_pool_skill(struct script_state *st) +{ + struct map_session_data *sd=script_rid2sd(st); + int skill_id = conv_num(st,& (st->stack->stack_data[st->start+2])); + + skill_pool_activate(sd, skill_id); + clif_skillinfoblock(sd); + + return 0; +} + + +int +buildin_deactivate_pool_skill(struct script_state *st) +{ + struct map_session_data *sd=script_rid2sd(st); + int skill_id = conv_num(st,& (st->stack->stack_data[st->start+2])); + + skill_pool_deactivate(sd, skill_id); + clif_skillinfoblock(sd); + + return 0; +} + + +int +buildin_check_pool_skill(struct script_state *st) +{ + struct map_session_data *sd=script_rid2sd(st); + int skill_id = conv_num(st,& (st->stack->stack_data[st->start+2])); + + push_val(st->stack, C_INT, skill_pool_is_activated(sd, skill_id)); + + return 0; +} + + int buildin_clearitem(struct script_state *st) { struct map_session_data *sd=script_rid2sd(st); diff --git a/src/map/skill.c b/src/map/skill.c index 22b8dcf..9e7d1d3 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1569,6 +1569,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds if(MRAND(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)){ struct map_session_data *tsd = (struct map_session_data *)bl; nullpo_retr(0, tsd); @@ -1589,6 +1590,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds clif_skillinfoblock(tsd); } } +*/ /* _[WȂljʔ */ if(bl->prev != NULL){ struct map_session_data *sd = (struct map_session_data *)bl; @@ -9879,6 +9881,31 @@ int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int * n */ +static int +scan_stat(char *statname) +{ + if (!strcmpi(statname, "str")) + return SP_STR; + if (!strcmpi(statname, "dex")) + return SP_DEX; + if (!strcmpi(statname, "agi")) + return SP_AGI; + if (!strcmpi(statname, "vit")) + return SP_VIT; + if (!strcmpi(statname, "int")) + return SP_INT; + if (!strcmpi(statname, "luk")) + return SP_LUK; + if (!strcmpi(statname, "none")) + return 0; + + else fprintf(stderr, "Unknown stat `%s'\n", statname); + return 0; +} + +extern void +skill_pool_register(int id); // [Fate] Remember that a certain skill ID belongs to a pool skill + /*========================================== * XL֌Wt@Cǂݍ * skill_db.txt XLf[^ @@ -9902,14 +9929,16 @@ int skill_readdb(void) char *split[50], *split2[MAX_SKILL_LEVEL]; if(line[0]=='/' && line[1]=='/') continue; - for(j=0,p=line;j<14 && p;j++){ + for(j=0,p=line;j<18 && p;j++){ while (*p == '\t' || *p == ' ') p++; split[j]=p; p=strchr(p,','); if(p) *p++=0; } - if(split[13]==NULL || j<14) + if(split[17]==NULL || j<18) { + fprintf(stderr, "Incomplete skill db data online (%d entries)\n", j); continue; + } i=atoi(split[0]); if(i<0 || i>MAX_SKILL_DB) @@ -9927,10 +9956,11 @@ int skill_readdb(void) 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_db[i].max_raise=atoi(split[6]); + skill_db[i].max=atoi(split[7]); memset(split2,0,sizeof(split2)); - for(j=0,p=split[7];j Date: Tue, 22 Sep 2009 23:53:13 +0000 Subject: @listnearby lists all nearby player names --- src/map/atcommand.c | 33 +++++++++++++++++++++++++++++++++ src/map/atcommand.h | 1 + 2 files changed, 34 insertions(+) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index ed213b2..23f1aa8 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -201,6 +201,7 @@ ATCOMMAND_FUNC(log); // [Fate] ATCOMMAND_FUNC(tee); // [Fate] ATCOMMAND_FUNC(invisible); // [Fate] ATCOMMAND_FUNC(visible); // [Fate] +ATCOMMAND_FUNC(list_nearby); // [Fate] ATCOMMAND_FUNC(iterate_forward_over_players); // [Fate] ATCOMMAND_FUNC(iterate_backwards_over_players); // [Fate] ATCOMMAND_FUNC(wgm); @@ -334,6 +335,7 @@ static AtCommandInfo atcommand_info[] = { { AtCommand_Disablenpc, "@disablenpc", 80, atcommand_disablenpc }, // [] { AtCommand_ServerTime, "@servertime", 0, atcommand_servertime }, // by Yor { AtCommand_CharDelItem, "@chardelitem", 60, atcommand_chardelitem }, // by Yor + { AtCommand_ListNearby, "@listnearby", 40, atcommand_list_nearby }, // by Yor { AtCommand_Jail, "@jail", 60, atcommand_jail }, // by Yor { AtCommand_UnJail, "@unjail", 60, atcommand_unjail }, // by Yor { AtCommand_Disguise, "@disguise", 20, atcommand_disguise }, // [Valaris] @@ -2606,6 +2608,37 @@ int atcommand_killmonster( return 0; } + +/*========================================== + * + *------------------------------------------ + */ +static int atlist_nearby_sub(struct block_list *bl, va_list ap) { + char buf[32]; + int fd = va_arg(ap, int); + nullpo_retr(0, bl); + + sprintf (buf, " - \"%s\"", ((struct map_session_data *)bl)->status.name); + clif_displaymessage(fd, buf); + + return 0; +} + +/*========================================== + * + *------------------------------------------ + */ +int atcommand_list_nearby( + const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + clif_displaymessage(fd, "Nearby players:"); + map_foreachinarea(atlist_nearby_sub, sd->bl.m, sd->bl.x-1, sd->bl.y-1, sd->bl.x+1, sd->bl.x+1, BL_PC, fd); + + return 0; +} + + /*========================================== * *------------------------------------------ diff --git a/src/map/atcommand.h b/src/map/atcommand.h index df996b6..5e72b1f 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -182,6 +182,7 @@ enum AtCommandType { AtCommand_IterateForward, AtCommand_IterateBackward, AtCommand_Wgm, + AtCommand_ListNearby, // [fate] // end AtCommand_Unknown, AtCommand_MAX -- cgit v1.2.3-70-g09d2 From 2df9559b94ce9acb7e8439e1c39bce4eb87e35ee Mon Sep 17 00:00:00 2001 From: Fate Date: Tue, 22 Sep 2009 23:57:56 +0000 Subject: Spellcasting disallowed while @hide is active --- src/map/magic.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/map/magic.c b/src/map/magic.c index 674da89..7567691 100644 --- a/src/map/magic.c +++ b/src/map/magic.c @@ -92,6 +92,8 @@ magic_message(character_t *caster, #ifdef DEBUG fprintf(stderr, "Found spell `%s', triggered = %d\n", spell_, effects != NULL); #endif + if (caster->status.option & OPTION_HIDE) + return 0; // No spellcasting while hidden MAP_LOG("PC%d %d:%d,%d CAST %s %s", caster->status.char_id, caster->bl.m, caster->bl.x, caster->bl.y, -- cgit v1.2.3-70-g09d2 From f9f63203fb461e69a9a422d160986daa78eecc51 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Tue, 22 Sep 2009 18:03:32 -0600 Subject: Prevent attacking while hidden --- src/map/clif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index ce86cff..083a246 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -6699,7 +6699,7 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd) { switch(action_type) { case 0x00: // once attack case 0x07: // continuous attack - if(sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class==22) + if(sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class==22 || sd->status.option & OPTION_HIDE) return; if (!battle_config.sdelay_attack_enable && pc_checkskill(sd, SA_FREECAST) <= 0) { if (DIFF_TICK(tick, sd->canact_tick) < 0) { -- cgit v1.2.3-70-g09d2 From 3ef2cb492970da40f82df9643c4cfc570bc3aa62 Mon Sep 17 00:00:00 2001 From: Fate Date: Sat, 26 Sep 2009 18:08:42 +0000 Subject: Initial support for skill pools (available via at commands and untested scripting commands.) These changes also affect the format of the skill_db.txt file. --- doc/mapserver-logging | 67 ++++++++++++++++++++ src/char/char.c | 23 ++----- src/common/mmo.h | 2 +- src/map/atcommand.c | 130 +++++++++++++++++++++++++++++++++++++-- src/map/battle.c | 48 ++++++++++++--- src/map/battle.h | 1 + src/map/chrif.c | 17 +----- src/map/clif.c | 14 ++--- src/map/magic-stmt.c | 27 +++++++-- src/map/magic.c | 8 +-- src/map/map.c | 11 +--- src/map/map.h | 8 +++ src/map/npc.c | 4 -- src/map/pc.c | 72 +++++++++------------- src/map/script.c | 7 +-- src/map/skill-pools.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/skill.c | 7 +++ src/map/skill.h | 31 +++++++--- 18 files changed, 505 insertions(+), 137 deletions(-) create mode 100644 doc/mapserver-logging create mode 100644 src/map/skill-pools.c (limited to 'src') diff --git a/doc/mapserver-logging b/doc/mapserver-logging new file mode 100644 index 0000000..e7088eb --- /dev/null +++ b/doc/mapserver-logging @@ -0,0 +1,67 @@ +Log format: + +LOGLINE ::= int'.'int + +MESSAGE ::= 'log-start' + | 'log-start v2' + | 'log-start v3' + | + | + +COORD ::= int':'int','int + +PC ::= 'PC'int + +MOB ::= 'MOB'int + +TARGET ::= | + +SPELLRESULT ::= 'SUCCESS' | 'FAILURE' + +STATPLACE ::= 'LOGIN' | 'STATUP' | 'STATUP2' | 'STATRESET' + +XPPLACE ::= 'LOGIN' | 'LEVELUP' + +XPREASON ::= 'SCRIPTXP' 'HEALXP' 'KILLXP' + +ZEROTARGET ::= 'null' | + +MOB-MESSAGE ::= 'DEAD' + +PC-MESSAGE ::= 'WPNDMG' int 'FOR' int WPN int # "WPNDMG MOB01 type FOR damage WPN weapon-item" + | 'WPNINJURY' int 'FOR' int + | 'SPELLHEAL-INSTA' FOR int + | 'SPELLDMG' FOR int BY spell-id + | 'CAST' spell-id + | 'STAT' int int int int int int # str agi vit int dex luk + | 'XP' int int ZENY int '+' int # level xp zeny bank-zeny + | 'MAGIC' int int int int int int 'EXP' int int 'LOGIN' # magic life war transmute nature ether magic-xp healer-xp + | 'SKILL-ACTIVATE' int int int # skillid skilllvl skillpower + | 'SKILL-UP' int int int # skillid skilllvl skillpower + | 'SKILL-DEACTIVATE' int + | 'MAGIC-ABSORB-DMG' int + | 'GAINXP' int + | 'PICKUP' int int # item-id count + | 'INJURED-BY' 'FOR' int + | 'DEAD' + | 'LOGOUT' + | 'TRADECOMMIT' 'WITH' int 'GIVE' int 'GET' int # pc-id give-zeny get-zeny + | 'TRADECANCEL' + | 'TRADEOK' + + + +NOTES: +------ +1. Any PICKUP between TRADECOMMIT and TRADEOK is part of the trade. +2. TRADECOMMIT is issued for both participants in a trade. +3. INJURED-BY seems to only duplicate information we already have. + + +Illegal items + +645, 668, 659, 731, 734, 744, 745, 755, 756, 757, 747, 748, 721, 722 + +Restricted access + +725, 726, 647, 646 \ No newline at end of file diff --git a/src/char/char.c b/src/char/char.c index fbf512e..98321ec 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -269,8 +269,8 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p) { *(str_p++) = '\t'; for(i = 0; i < MAX_SKILL; i++) - if (p->skill[i].id && p->skill[i].flag != 1) { - str_p += sprintf(str_p, "%d,%d ", p->skill[i].id, (p->skill[i].flag == 0) ? p->skill[i].lv : p->skill[i].flag-2); + if (p->skill[i].id) { + str_p += sprintf(str_p, "%d,%d ", p->skill[i].id, p->skill[i].lv | (p->skill[i].flags << 16)); } *(str_p++) = '\t'; @@ -506,7 +506,8 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p) { if (sscanf(str + next, "%d,%d%n", &tmp_int[0], &tmp_int[1], &len) != 2) return -6; p->skill[tmp_int[0]].id = tmp_int[0]; - p->skill[tmp_int[0]].lv = tmp_int[1]; + p->skill[tmp_int[0]].lv = tmp_int[1] & 0xffff; + p->skill[tmp_int[0]].flags = ((tmp_int[1] >> 16) & 0xffff); next += len; if (str[next] == ' ') next++; @@ -1660,22 +1661,6 @@ int parse_tologin(int fd) { } else if (jobclass == 4042 || jobclass == 4043) { char_dat[i].class = (sex) ? 4042 : 4043; } - // remove specifical skills of classes 19, 4020 and 4042 - for(j = 315; j <= 322; j++) { - if (char_dat[i].skill[j].id > 0 && !char_dat[i].skill[j].flag) { - char_dat[i].skill_point += char_dat[i].skill[j].lv; - char_dat[i].skill[j].id = 0; - char_dat[i].skill[j].lv = 0; - } - } - // remove specifical skills of classes 20, 4021 and 4043 - for(j = 323; j <= 330; j++) { - if (char_dat[i].skill[j].id > 0 && !char_dat[i].skill[j].flag) { - char_dat[i].skill_point += char_dat[i].skill[j].lv; - char_dat[i].skill[j].id = 0; - char_dat[i].skill[j].lv = 0; - } - } } // to avoid any problem with equipment and invalid sex, equipment is unequiped. for (j = 0; j < MAX_INVENTORY; j++) { diff --git a/src/common/mmo.h b/src/common/mmo.h index e958f81..1ba3ee4 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -83,7 +83,7 @@ struct point{ }; struct skill { - unsigned short id,lv,flag; + unsigned short id,lv,flags; }; struct global_reg { diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 23f1aa8..510026b 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -204,6 +204,10 @@ ATCOMMAND_FUNC(visible); // [Fate] ATCOMMAND_FUNC(list_nearby); // [Fate] ATCOMMAND_FUNC(iterate_forward_over_players); // [Fate] ATCOMMAND_FUNC(iterate_backwards_over_players); // [Fate] +ATCOMMAND_FUNC(skillpool_info); // [Fate] +ATCOMMAND_FUNC(skillpool_focus); // [Fate] +ATCOMMAND_FUNC(skillpool_unfocus); // [Fate] +ATCOMMAND_FUNC(skill_learn); // [Fate] ATCOMMAND_FUNC(wgm); /*========================================== @@ -393,6 +397,10 @@ static AtCommandInfo atcommand_info[] = { { AtCommand_Visible, "@visible", 60, atcommand_visible }, // [Fate] { AtCommand_IterateForward, "@hugo", 60, atcommand_iterate_forward_over_players }, // [Fate] { AtCommand_IterateBackward, "@linus", 60, atcommand_iterate_backwards_over_players }, // [Fate] + { AtCommand_IterateBackward, "@sp-info", 40, atcommand_skillpool_info }, // [Fate] + { AtCommand_IterateBackward, "@sp-focus", 80, atcommand_skillpool_focus }, // [Fate] + { AtCommand_IterateBackward, "@sp-unfocus", 80, atcommand_skillpool_unfocus }, // [Fate] + { AtCommand_IterateBackward, "@skill-learn", 80, atcommand_skill_learn }, // [Fate] { AtCommand_Wgm, "@wgm", 0, atcommand_wgm }, // add new commands before this line @@ -4088,7 +4096,7 @@ int atcommand_lostskill( 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; + sd->status.skill[skill_id].flags = 0; clif_skillinfoblock(sd); clif_displaymessage(fd, msg_table[71]); // You have forgotten the skill. } else { @@ -4131,7 +4139,7 @@ int atcommand_charlostskill( if ((pl_sd = map_nick2sd(character)) != 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; + pl_sd->status.skill[skill_id].flags = 0; clif_skillinfoblock(pl_sd); clif_displaymessage(fd, msg_table[202]); // This player has forgotten the skill. } else { @@ -7002,7 +7010,7 @@ atcommand_magic_info(const int fd, struct map_session_data* sd, memset(character, '\0', sizeof(character)); - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) { + if (!message || !*message || sscanf(message, "%99s", character) < 1) { clif_displaymessage(fd, "Usage: @magicinfo "); return -1; } @@ -7031,7 +7039,6 @@ set_skill(struct map_session_data* sd, int i, int level) { sd->status.skill[i].id = level? i : 0; sd->status.skill[i].lv = level; - sd->status.skill[i].flag = 0; } int @@ -7194,3 +7201,118 @@ int atcommand_wgm( return 0; } + +int atcommand_skillpool_info( + const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + char character[100]; + struct map_session_data *pl_sd; + + if (!message || !*message || sscanf(message, "%99s", character) < 1) { + clif_displaymessage(fd, "Usage: @sp-info "); + return -1; + } + + if ((pl_sd = map_nick2sd(character)) != NULL) { + char buf[200]; + int pool_skills[MAX_SKILL_POOL]; + int pool_skills_nr = skill_pool(pl_sd, pool_skills); + int i; + + sprintf(buf, "Active skills %d out of %d for %s:", pool_skills_nr, skill_pool_max(pl_sd), character); + clif_displaymessage(fd, buf); + for (i = 0; i < pool_skills_nr; ++i) { + sprintf(buf, " - %s [%d]: power %d", skill_name(pool_skills[i]), pool_skills[i], skill_power(pl_sd, pool_skills[i])); + clif_displaymessage(fd, buf); + } + + sprintf(buf, "Learned skills out of %d for %s:", skill_pool_skills_size, character); + clif_displaymessage(fd, buf); + + for (i = 0; i < skill_pool_skills_size; ++i) { + char *name = skill_name(skill_pool_skills[i]); + int lvl = pl_sd->status.skill[skill_pool_skills[i]].lv; + + if (lvl) { + sprintf(buf, " - %s [%d]: lvl %d", name, skill_pool_skills[i], lvl); + clif_displaymessage(fd, buf); + } + } + + } else + clif_displaymessage(fd, "Character not found."); + + + return 0; +} + +int atcommand_skillpool_focus( + const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + char character[100]; + int skill; + struct map_session_data *pl_sd; + + if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill, character) < 1) { + clif_displaymessage(fd, "Usage: @sp-focus "); + return -1; + } + + if ((pl_sd = map_nick2sd(character)) != NULL) { + if (skill_pool_activate(pl_sd, skill)) + clif_displaymessage(fd, "Activation failed."); + else + clif_displaymessage(fd, "Activation successful."); + } else + clif_displaymessage(fd, "Character not found."); + + return 0; +} + +int atcommand_skillpool_unfocus( + const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + char character[100]; + int skill; + struct map_session_data *pl_sd; + + if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill, character) < 1) { + clif_displaymessage(fd, "Usage: @sp-unfocus "); + return -1; + } + + if ((pl_sd = map_nick2sd(character)) != NULL) { + if (skill_pool_deactivate(pl_sd, skill)) + clif_displaymessage(fd, "Deactivation failed."); + else + clif_displaymessage(fd, "Deactivation successful."); + } else + clif_displaymessage(fd, "Character not found."); + + return 0; +} + +int atcommand_skill_learn( + const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + char character[100]; + int skill, level; + struct map_session_data *pl_sd; + + if (!message || !*message || sscanf(message, "%d %d %99[^\n]", &skill, &level, character) < 1) { + clif_displaymessage(fd, "Usage: @skill-learn "); + return -1; + } + + if ((pl_sd = map_nick2sd(character)) != NULL) { + set_skill(pl_sd, skill, level); + clif_skillinfoblock(pl_sd); + } else + clif_displaymessage(fd, "Character not found."); + + return 0; +} diff --git a/src/map/battle.c b/src/map/battle.c index 507defd..9b5f699 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -381,6 +381,10 @@ int battle_get_flee(struct block_list *bl) flee += flee*(sc_data[SC_WINDWALK].val2)/100; if(sc_data[SC_SPIDERWEB].timer!=-1 && bl->type != BL_PC) //XpC_[EFu flee -= flee*50/100; + + if (battle_is_unarmed(bl)) + flee += (skill_power_bl(bl, TMW_BRAWLING) >> 3); // +25 for 200 + flee += skill_power_bl(bl, TMW_SPEED) >> 3; } if(flee < 1) flee = 1; return flee; @@ -412,6 +416,9 @@ int battle_get_hit(struct block_list *bl) hit += 3*(sc_data[SC_TRUESIGHT].val1); if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //RZg[V hit += (hit*(10*(sc_data[SC_CONCENTRATION].val1)))/100; + + if (battle_is_unarmed(bl)) + hit += (skill_power_bl(bl, TMW_BRAWLING) >> 4); // +12 for 200 } if(hit < 1) hit = 1; return hit; @@ -439,6 +446,10 @@ int battle_get_flee2(struct block_list *bl) if(sc_data[SC_WHISTLE].timer!=-1 && bl->type != BL_PC) flee2 += (sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2 +(sc_data[SC_WHISTLE].val3&0xffff))*10; + + if (battle_is_unarmed(bl)) + flee2 += (skill_power_bl(bl, TMW_BRAWLING) >> 3); // +25 for 200 + flee2 += skill_power_bl(bl, TMW_SPEED) >> 3; } if(flee2 < 1) flee2 = 1; return flee2; @@ -582,6 +593,7 @@ int battle_get_atk2(struct block_list *bl) if(sc_data[SC_CONCENTRATION].timer!=-1) //RZg[V atk2 += atk2*(5*sc_data[SC_CONCENTRATION].val1)/100; } + if(atk2 < 0) atk2 = 0; return atk2; } @@ -595,8 +607,8 @@ int battle_get_atk2(struct block_list *bl) int battle_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; + if(bl->type==BL_PC) + return ((struct map_session_data*)bl)->watk_2; else return 0; } @@ -2228,6 +2240,23 @@ static struct Damage battle_calc_mob_weapon_attack( wd.dmg_lv=dmg_lv; return wd; } + + +int +battle_is_unarmed(struct block_list *bl) +{ + if (!bl) + return 0; + if (bl->type == BL_PC) { + struct map_session_data *sd = (struct map_session_data *) bl; + + return (sd->equip_index[EQUIP_SHIELD] == -1 + && sd->equip_index[EQUIP_WEAPON] == -1); + } else + return 0; +} + + /* * ========================================================================= * PC̕ɂU @@ -2325,6 +2354,7 @@ static struct Damage battle_calc_pc_weapon_attack( } } hitrate=battle_get_hit(src) - flee + 80; //vZ + battle_is_unarmed(src); { // [Fate] Reduce hit chance by distance int dx = abs(src->x - target->x); int dy = abs(src->y - target->y); @@ -3890,13 +3920,17 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, // significantly increase injuries for hasted characters if (wd.damage > 0 && (t_sc_data[SC_HASTE].timer != -1)) { - wd.damage = (wd.damage * (16 + t_sc_data[SC_HASTE].val1)) >> 4; + wd.damage = (wd.damage * (16 + t_sc_data[SC_HASTE].val1)) >> 4; } - if (t_sc_data[SC_PHYS_SHIELD].timer != -1 && target->type == BL_PC) { - wd.damage -= t_sc_data[SC_PHYS_SHIELD].val1; - if (wd.damage < 0) - wd.damage = 0; + if (wd.damage > 0 + && t_sc_data[SC_PHYS_SHIELD].timer != -1 && target->type == BL_PC) { + int reduction = t_sc_data[SC_PHYS_SHIELD].val1; + if (reduction > wd.damage) + reduction = wd.damage; + + wd.damage -= reduction; + MAP_LOG_PC(((struct map_session_data *)target), "MAGIC-ABSORB-DMG %d", reduction); } if((damage = wd.damage + wd.damage2) > 0 && src != target) { diff --git a/src/map/battle.h b/src/map/battle.h index 6ff45d0..6b4860d 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -63,6 +63,7 @@ int battle_weapon_attack( struct block_list *bl,struct block_list *target, // ep[^𓾂 int battle_counttargeted(struct block_list *bl,struct block_list *src,int target_lv); +int battle_is_unarmed(struct block_list *bl); int battle_get_class(struct block_list *bl); int battle_get_dir(struct block_list *bl); int battle_get_lv(struct block_list *bl); diff --git a/src/map/chrif.c b/src/map/chrif.c index 4318d1a..3152866 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -595,22 +595,7 @@ int chrif_changedsex(int fd) // 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) diff --git a/src/map/clif.c b/src/map/clif.c index 083a246..086c14b 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3741,10 +3741,7 @@ int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range) } else WFIFOW(fd,12)= range; memset(WFIFOP(fd,14),0,24); - if(skill_get_inf2(id)&0x01) - WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_get_max(id) && sd->status.skill[skillid].flag ==0 )? 1:0; - else - WFIFOB(fd,38) = 0; + WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_get_max_raise(id))? 1:0; WFIFOSET(fd,packet_len_table[0x147]); return 0; @@ -3768,7 +3765,7 @@ int clif_skillinfoblock(struct map_session_data *sd) && (sd->tmw_version >= 1)){ // [Fate] Version 1 and later don't crash because of bad skill IDs anymore WFIFOW(fd,len ) = id; WFIFOW(fd,len+2) = skill_get_inf(id); - WFIFOW(fd,len+4) = skill_db[i].poolflags | (sd->status.skill[i].flag & (SKILL_POOL_ACTIVATED)); + WFIFOW(fd,len+4) = skill_db[i].poolflags | (sd->status.skill[i].flags & (SKILL_POOL_ACTIVATED)); 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); @@ -3776,10 +3773,7 @@ int clif_skillinfoblock(struct map_session_data *sd) range = battle_get_range(&sd->bl) - (range + 1); WFIFOW(fd,len+10)= range; memset(WFIFOP(fd,len+12),0,24); - if(skill_get_inf2(id)&0x01) - WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max(id) && sd->status.skill[i].flag ==0 )? 1:0; - else - WFIFOB(fd,len+36) = 0; + WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max_raise(id))? 1:0; len+=37; c++; } @@ -3809,7 +3803,7 @@ int clif_skillup(struct map_session_data *sd,int skill_num) if(range < 0) range = battle_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_get_max_raise(sd->status.skill[skill_num].id)) ? 1 : 0; WFIFOSET(fd,packet_len_table[0x10e]); return 0; diff --git a/src/map/magic-stmt.c b/src/map/magic-stmt.c index 55e6133..65e0202 100644 --- a/src/map/magic-stmt.c +++ b/src/map/magic-stmt.c @@ -292,9 +292,8 @@ op_instaheal(env_t *env, int args_nr, val_t *args) if (caster->type == BL_PC && subject->type == BL_PC) { character_t *caster_pc = (character_t *) caster; character_t *subject_pc = (character_t *) subject; - MAP_LOG("PC%d %d:%d,%d SPELLHEAL-INSTA PC%d FOR %d", - caster_pc->status.char_id, caster->m, caster->x, caster->y, - subject_pc->status.char_id, ARGINT(1)); + MAP_LOG_PC(caster_pc, "SPELLHEAL-INSTA PC%d FOR %d", + subject_pc->status.char_id, ARGINT(1)); } battle_heal(caster, subject, ARGINT(1), ARGINT(2), 0); @@ -677,6 +676,22 @@ op_spawn(env_t *env, int args_nr, val_t *args) } +static char * +get_invocation_name(env_t *env) +{ + invocation_t *invocation; + + if (VAR(VAR_INVOCATION).ty != TY_INVOCATION) + return "?"; + invocation = (invocation_t *)map_id2bl(VAR(VAR_INVOCATION).v.v_int); + + if (invocation) + return invocation->spell->name; + else + return "??"; +} + + static int op_injure(env_t *env, int args_nr, val_t *args) { @@ -711,9 +726,9 @@ op_injure(env_t *env, int args_nr, val_t *args) if (target->type == BL_MOB) { struct mob_data *mob = (struct mob_data *) target; - MAP_LOG("PC%d %d:%d,%d SPELLDMG MOB%d %d FOR %d", - caster_pc->status.char_id, caster->m, caster->x, caster->y, - mob->bl.id, mob->class, damage_caused); + MAP_LOG_PC(caster_pc, "SPELLDMG MOB%d %d FOR %d BY %s", + mob->bl.id, mob->class, damage_caused, + get_invocation_name(env)); } } battle_damage(caster, target, damage_caused, mp_damage); diff --git a/src/map/magic.c b/src/map/magic.c index 7567691..f70d9a6 100644 --- a/src/map/magic.c +++ b/src/map/magic.c @@ -95,11 +95,9 @@ magic_message(character_t *caster, if (caster->status.option & OPTION_HIDE) return 0; // No spellcasting while hidden - MAP_LOG("PC%d %d:%d,%d CAST %s %s", - caster->status.char_id, caster->bl.m, caster->bl.x, caster->bl.y, - spell->name, - effects? "SUCCESS" : "FAILURE"); - + MAP_LOG_PC(caster, "CAST %s %s", + spell->name, + effects? "SUCCESS" : "FAILURE"); if (effects) { invocation_t *invocation = spell_instantiate(effects, env); diff --git a/src/map/map.c b/src/map/map.c index abb750f..f5d6d33 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -965,8 +965,6 @@ void map_addnickdb(struct map_session_data *sd) { *------------------------------------------ */ int map_quit(struct map_session_data *sd) { - int i; - nullpo_retr(0, sd); if(sd->chatID) // `bgo @@ -1012,13 +1010,6 @@ int map_quit(struct map_session_data *sd) { pc_setrestartvalue(sd,2); pc_makesavestatus(sd); //N[XLŊoXL͏ - for(i=0;istatus.skill[i].flag == 13){ - sd->status.skill[i].id=0; - sd->status.skill[i].lv=0; - sd->status.skill[i].flag=0; - } - } //The storage closing routines will save the char if needed. [Skotlex] if (!sd->state.storage_flag) @@ -1704,7 +1695,7 @@ map_set_logfile(char *filename) map_start_logfile(tv.tv_sec); atexit(map_close_logfile); - MAP_LOG("log-start v2"); + MAP_LOG("log-start v3"); } diff --git a/src/map/map.h b/src/map/map.h index 5e77d89..30c03f4 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -630,6 +630,11 @@ enum { LOOK_MISC2 }; +enum { + EQUIP_SHIELD = 8, + EQUIP_WEAPON = 9 +}; + #define LOOK_LAST LOOK_MISC2 struct chat_data { @@ -692,6 +697,9 @@ extern FILE *map_logfile; void map_write_log(char *format, ...); #define MAP_LOG(format, args...) {if (map_logfile) map_write_log(format, ##args);} +#define MAP_LOG_PC(sd, fmt, args...) MAP_LOG("PC%d %d:%d,%d " fmt, sd->status.char_id, sd->bl.m, sd->bl.x, sd->bl.y, ## args) + + // ACe֘A int map_clearflooritem_timer(int,unsigned int,int,int); #define map_clearflooritem(id) map_clearflooritem_timer(0,0,id,1) diff --git a/src/map/npc.c b/src/map/npc.c index 10d64db..1a0462f 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -996,8 +996,6 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list) 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 = (log(z * (double)skill) * (double)battle_config.shop_exp/100.); if (z < 1) @@ -1053,8 +1051,6 @@ int npc_selllist(struct map_session_data *sd,int n,unsigned short *item_list) 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 = (log(z * (double)skill) * (double)battle_config.shop_exp/100.); if (z < 1) diff --git a/src/map/pc.c b/src/map/pc.c index 51165ea..5976137 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -38,8 +38,6 @@ #define STATE_BLIND 0x10 -#define MAP_LOG_PC(sd, fmt, args...) MAP_LOG("PC%d %d:%d,%d " fmt, sd->status.char_id, sd->bl.m, sd->bl.x, sd->bl.y, ## args) - #define MAP_LOG_STATS(sd, suffix) \ MAP_LOG_PC(sd, "STAT %d %d %d %d %d %d " suffix, \ sd->status.str, sd->status.agi, sd->status.vit, sd->status.int_, sd->status.dex, sd->status.luk) @@ -853,6 +851,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, short tmw_versio strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), gmtime(&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); } + pc_calcstatus(sd,1); return 0; } @@ -875,23 +874,17 @@ int pc_authfail(int id) { static int pc_calc_skillpoint(struct map_session_data* sd) { - int i,skill,skill_point=0; + int i, skill_points = 0; nullpo_retr(0, sd); - for(i=1;i 0) { - if(skill_get_inf2(i)&0x01) { - 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); - } - } - } - } + for (i = 0; i < skill_pool_skills_size; i++) { + int lv = sd->status.skill[skill_pool_skills[i]].lv; + if (lv) + skill_points += ((lv * (lv + 1)) >> 1) - 1; + } - return skill_point; + return skill_points; } /*========================================== @@ -1381,6 +1374,13 @@ int pc_calcstatus(struct map_session_data* sd,int first) } } + if (battle_is_unarmed(&sd->bl)) { + sd->watk += skill_power(sd, TMW_BRAWLING) / 3; // +66 for 200 + sd->watk2 += skill_power(sd, TMW_BRAWLING) >> 3; // +25 for 200 + sd->watk_ += skill_power(sd, TMW_BRAWLING) / 3; // +66 for 200 + sd->watk_2 += skill_power(sd, TMW_BRAWLING) >> 3; // +25 for 200 + } + if(sd->equip_index[10] >= 0){ // �� index = sd->equip_index[10]; if(sd->inventory_data[index]){ //�܂�����������Ă��Ȃ� @@ -1471,6 +1471,10 @@ int pc_calcstatus(struct map_session_data* sd,int first) sd->paramb[5]+= 5; } } + sd->speed -= skill_power(sd, TMW_SPEED) >> 3; + sd->aspd_rate -= skill_power(sd, TMW_SPEED) / 10; + if (sd->aspd_rate < 20) + sd->aspd_rate = 20; //1�x�����łȂ�Job70�X�p�m�r��+10 if(s_class.job == 23 && sd->die_counter == 0 && sd->status.job_level >= 70){ @@ -2654,12 +2658,7 @@ int pc_skill(struct map_session_data *sd,int id,int level,int flag) clif_skillinfoblock(sd); } else if(sd->status.skill[id].lv < level){ // �o�������邪lv���������Ȃ� - if(sd->status.skill[id].id==id) - sd->status.skill[id].flag=sd->status.skill[id].lv+2; // lv���L�� - else { - sd->status.skill[id].id=id; - sd->status.skill[id].flag=1; // card�X�L���Ƃ��� - } + sd->status.skill[id].id=id; sd->status.skill[id].lv=level; } @@ -4358,6 +4357,7 @@ int pc_checkbaselevelup(struct map_session_data *sd) //���x���A�b�v�����̂Ńp�[�e�B�[�������X�V���� //(��͈̓`�F�b�N) party_send_movemap(sd); + MAP_LOG_XP(sd, "LEVELUP") return 1; } @@ -4766,6 +4766,8 @@ int pc_skillup(struct map_session_data *sd,int skill_num) clif_skillup(sd,skill_num); clif_updatestatus(sd,SP_SKILLPOINT); clif_skillinfoblock(sd); + MAP_LOG_PC(sd, "SKILLUP %d %d %d", + skill_num, sd->status.skill[skill_num].lv, skill_power(sd, skill_num)); } return 0; @@ -4788,13 +4790,8 @@ int pc_allskillup(struct map_session_data *sd) c = s_class.job; s = (s_class.upper==1) ? 1 : 0 ; //�]���ȊO�͒ʏ��̃X�L���H - for(i=0;istatus.skill[i].id=0; - if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // card�X�L���Ȃ��A - 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){ // �S�ẴX�L�� @@ -4963,23 +4960,14 @@ int pc_resetskill(struct map_session_data* sd) nullpo_retr(0, sd); - for(i=1;istatus.skill_point += pc_calc_skillpoint(sd); + + for(i=1;i 0) { - if(skill_get_inf2(i)&0x01) { - 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; - } + sd->status.skill[i].flags = 0; + } + clif_updatestatus(sd,SP_SKILLPOINT); clif_skillinfoblock(sd); pc_calcstatus(sd,0); diff --git a/src/map/script.c b/src/map/script.c index 87336a2..60ea879 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3205,7 +3205,6 @@ int buildin_setskill(struct script_state *st) sd->status.skill[id].id = level? id : 0; sd->status.skill[id].lv = level; - sd->status.skill[id].flag = 0; clif_skillinfoblock(sd); return 0; } @@ -5524,7 +5523,7 @@ int buildin_getskilllist(struct script_state *st) if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0){ pc_setreg(sd,add_str("@skilllist_id")+(j<<24),sd->status.skill[i].id); pc_setreg(sd,add_str("@skilllist_lv")+(j<<24),sd->status.skill[i].lv); - pc_setreg(sd,add_str("@skilllist_flag")+(j<<24),sd->status.skill[i].flag); + pc_setreg(sd,add_str("@skilllist_flag")+(j<<24),sd->status.skill[i].flags); j++; } } @@ -5551,7 +5550,7 @@ buildin_get_activated_pool_skills(struct script_state *st) if (sd->status.skill[skill_id].id == skill_id) { pc_setreg(sd,add_str("@skilllist_id")+(count<<24),sd->status.skill[skill_id].id); pc_setreg(sd,add_str("@skilllist_lv")+(count<<24),sd->status.skill[skill_id].lv); - pc_setreg(sd,add_str("@skilllist_flag")+(count<<24),sd->status.skill[skill_id].flag); + pc_setreg(sd,add_str("@skilllist_flag")+(count<<24),sd->status.skill[skill_id].flags); pc_setregstr(sd, add_str("@skilllist_name$")+(count<<24), skill_name(skill_id)); ++count; } @@ -5579,7 +5578,7 @@ buildin_get_pool_skills(struct script_state *st) if (sd->status.skill[skill_id].id == skill_id) { pc_setreg(sd,add_str("@skilllist_id")+(count<<24),sd->status.skill[skill_id].id); pc_setreg(sd,add_str("@skilllist_lv")+(count<<24),sd->status.skill[skill_id].lv); - pc_setreg(sd,add_str("@skilllist_flag")+(count<<24),sd->status.skill[skill_id].flag); + pc_setreg(sd,add_str("@skilllist_flag")+(count<<24),sd->status.skill[skill_id].flags); pc_setregstr(sd, add_str("@skilllist_name$")+(count<<24), skill_name(skill_id)); ++count; } diff --git a/src/map/skill-pools.c b/src/map/skill-pools.c new file mode 100644 index 0000000..de7f04b --- /dev/null +++ b/src/map/skill-pools.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include + +#include "timer.h" +#include "nullpo.h" +#include "malloc.h" +#include "magic.h" + +#include "battle.h" +#include "clif.h" +#include "intif.h" +#include "itemdb.h" +#include "map.h" +#include "mob.h" +#include "party.h" +#include "pc.h" +#include "script.h" +#include "skill.h" +#include "../common/socket.h" + +#ifdef MEMWATCH +#include "memwatch.h" +#endif + +int skill_pool_skills[MAX_POOL_SKILLS]; +int skill_pool_skills_size = 0; + +extern void +skill_pool_register(int id) +{ + if (skill_pool_skills_size + 1 >= MAX_POOL_SKILLS) { + fprintf(stderr, "Too many pool skills! Increase MAX_POOL_SKILLS and recompile."); + return; + } + + skill_pool_skills[skill_pool_skills_size++] = id; +} + + +char * +skill_name(int skill) +{ + if (skill > 0 && skill < MAX_SKILL_DB) + return skill_names[skill].desc; + else + return NULL; +} + +int +skill_pool(struct map_session_data *sd, int *skills) +{ + int i, count = 0; + + for (i = 0; count < MAX_SKILL_POOL && i < skill_pool_skills_size; i++) { + int skill_id = skill_pool_skills[i]; + if (sd->status.skill[skill_id].flags & SKILL_POOL_ACTIVATED) { + if (skills) + skills[count] = skill_id; + ++count; + } + } + + return count; +} + +void +skill_pool_empty(struct map_session_data *sd) +{ + int i; + + for (i = 0; i < skill_pool_skills_size; i++) { + int skill_id = skill_pool_skills[i]; + sd->status.skill[skill_id].flags = 0; + } +} + +int skill_pool_size(struct map_session_data *sd) +{ + return skill_pool(sd, NULL); +} + +int +skill_pool_max(struct map_session_data *sd) +{ + return sd->status.skill[TMW_SKILLPOOL].lv; +} + + +int +skill_pool_activate(struct map_session_data *sd, int skill_id) +{ + if (sd->status.skill[skill_id].flags & SKILL_POOL_ACTIVATED) + return 0; // Already there + else if (sd->status.skill[skill_id].id == skill_id // knows the skill + && (skill_pool_size(sd) < skill_pool_max(sd))) { + sd->status.skill[skill_id].flags |= SKILL_POOL_ACTIVATED; + MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d", skill_id, sd->status.skill[skill_id].lv, skill_power(sd, skill_id)); + return 0; + } + pc_calcstatus(sd, 0); + + return 1; // failed +} + +int +skill_pool_is_activated(struct map_session_data *sd, int skill_id) +{ + return sd->status.skill[skill_id].flags & SKILL_POOL_ACTIVATED; +} + +int +skill_pool_deactivate(struct map_session_data *sd, int skill_id) +{ + if (sd->status.skill[skill_id].flags & SKILL_POOL_ACTIVATED) { + sd->status.skill[skill_id].flags &= ~SKILL_POOL_ACTIVATED; + MAP_LOG_PC(sd, "SKILL-DEACTIVATE %d", skill_id); + pc_calcstatus(sd, 0); + return 0; + } + + return 1; +} + + +int +skill_stat(int skill_id) +{ + return skill_db[skill_id].stat; +} + +int +skill_power(struct map_session_data *sd, int skill_id) +{ + int stat = skill_stat(skill_id); + int stat_value, skill_value; + int result; + + if (stat == 0 + || !skill_pool_is_activated(sd, skill_id)) + return 0; + + stat_value = battle_get_stat(stat, &(sd->bl)); + skill_value = sd->status.skill[skill_id].lv; + + if ((skill_value * 10) - 1 > stat_value) + skill_value += (stat_value / 10); + else + skill_value *= 2; + + result = (skill_value * stat_value) / 10; + + return result; +} + + +int +skill_power_bl(struct block_list *bl, int skill) +{ + if (bl->type == BL_PC) + return skill_power((struct map_session_data *) bl, skill); + else + return 0; +} diff --git a/src/map/skill.c b/src/map/skill.c index 9e7d1d3..6cff936 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -722,11 +722,16 @@ static int rdamage; /* XLf[^x[X */ struct skill_db skill_db[MAX_SKILL_DB]; +#define UNARMED_PLAYER_DAMAGE_MIN(bl) (skill_power_bl((bl), TMW_BRAWLING) >> 4) // +50 for 200 +#define UNARMED_PLAYER_DAMAGE_MAX(bl) (skill_power_bl((bl), TMW_BRAWLING)) // +200 for 200 + + int skill_get_hit( int id ){ return skill_db[id].hit; } int skill_get_inf( int id ){ return skill_db[id].inf; } int skill_get_pl( int id ){ return skill_db[id].pl; } int skill_get_nk( int id ){ return skill_db[id].nk; } int skill_get_max( int id ){ return skill_db[id].max; } +int skill_get_max_raise( int id ){ return skill_db[id].max_raise; } int skill_get_range( int id , int lv ){ return (lv <= 0) ? 0:skill_db[id].range[lv-1]; } int skill_get_hp( int id ,int lv ){ return (lv <= 0) ? 0:skill_db[id].hp[lv-1]; } int skill_get_sp( int id ,int lv ){ return (lv <= 0) ? 0:skill_db[id].sp[lv-1]; } @@ -10008,6 +10013,8 @@ int skill_readdb(void) char *s = skill_names[i].desc; while ((s = strchr(s, '_'))) *s = ' '; + if ((s = strchr(skill_names[i].desc, '\t')) || (s = strchr (skill_names[i].desc, ' ')) || (s = strchr (skill_names[i].desc, '\n'))) + *s = '\000'; } } fclose_(fp); diff --git a/src/map/skill.h b/src/map/skill.h index faff9a9..0f7b369 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -50,6 +50,7 @@ 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_max_raise( 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 ); @@ -373,7 +374,7 @@ enum { MC_VENDING, MC_MAMMONITE, - AC_OWL, + AC_OWL = 45, AC_VULTURE, AC_CONCENTRATION, AC_DOUBLE, @@ -383,7 +384,7 @@ enum { TF_MISS, TF_STEAL, TF_HIDING, - TF_POISON, // 52 + TF_POISON, TF_DETOXIFY, ALL_RESURRECTION, @@ -691,12 +692,19 @@ enum { TMW_SKILLPOOL = 339, // skill pool size TMW_MAGIC = 340, - TMW_MAGIC_LIFE, - TMW_MAGIC_WAR, - TMW_MAGIC_TRANSMUTE, - TMW_MAGIC_NATURE, - TMW_MAGIC_ETHER, - TMW_MAGIC_END, + TMW_MAGIC_LIFE = 341, + TMW_MAGIC_WAR = 342, + TMW_MAGIC_TRANSMUTE = 343, + TMW_MAGIC_NATURE = 344, + TMW_MAGIC_ETHER = 345, + TMW_MAGIC_DARK = 346, + TMW_MAGIC_LIGHT = 347, + + TMW_BRAWLING = 350, + TMW_LUCKY_COUNTER = 351, + TMW_SPEED = 352, + TMW_RESIST_POISON = 353, + TMW_ASTRAL_SOUL = 354, LK_AURABLADE = 355, LK_PARRYING, @@ -832,17 +840,22 @@ enum { // Max. # of skills that may be classified as pool skills in db/skill_db.txt #define MAX_POOL_SKILLS 128 +extern int skill_pool_skills[MAX_POOL_SKILLS]; // All pool skills +extern int skill_pool_skills_size; // Number of entries in skill_pool_skills + int skill_pool(struct map_session_data *sd, int *skills); // Yields all active skills in the skill pool; no more than MAX_SKILL_POOL. Return is number of skills. int skill_pool_size(struct map_session_data *sd); int skill_pool_max(struct map_session_data *sd); // Max. number of pool skills void skill_pool_empty(struct map_session_data *sd); // Deactivate all pool skills int skill_pool_activate(struct map_session_data *sd, int skill); // Skill into skill pool. Return is zero iff okay. -int skill_pool_is_activated(struct map_session_data *sd, int skill); // Skill into skill pool. Return is nonzero when activated. +int skill_pool_is_activated(struct map_session_data *sd, int skill); // Skill into skill pool. Return is zero when activated. int skill_pool_deactivate(struct map_session_data *sd, int skill); // Skill out of skill pool. Return is zero iff okay. char *skill_name(int skill); // Yield configurable skill name int skill_stat(int skill); // Yields the stat associated with a skill. Returns zero if none, or SP_STR, SP_VIT, ... otherwise int skill_power(struct map_session_data *sd, int skill); // Yields the power of a skill. This is zero if the skill is unknown or if it's a pool skill that is outside of the skill pool, // otherwise a value from 0 to 255 (with 200 being the `normal maximum') +int skill_power_bl(struct block_list *bl, int skill); // Yields the power of a skill. This is zero if the skill is unknown or if it's a pool skill that is outside of the skill pool, + // otherwise a value from 0 to 255 (with 200 being the `normal maximum') #endif -- cgit v1.2.3-70-g09d2 From 02ce702acb0fadcaf76470a94194f1d20e4c8bc0 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Sat, 26 Sep 2009 13:06:52 -0600 Subject: Add a no player drop flag for maps --- src/map/clif.c | 2 +- src/map/map.h | 1 + src/map/npc.c | 15 +++++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 086c14b..76c38e5 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -6896,7 +6896,7 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) { clif_clearchar_area(&sd->bl, 1); return; } - if (sd->npc_id != 0 || sd->opt1 > 0 || + if (sd->npc_id != 0 || sd->opt1 > 0 || map[sd->bl.m].flag.no_player_drops || (sd->sc_data && (sd->sc_data[SC_AUTOCOUNTER].timer != -1 || //�I�[�g�J�E���^�[ sd->sc_data[SC_BLADESTOP].timer != -1 || //���n���� sd->sc_data[SC_BERSERK].timer != -1)) ) //�o�[�T�[�N diff --git a/src/map/map.h b/src/map/map.h index 30c03f4..9a6b3ef 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -546,6 +546,7 @@ struct map_data { unsigned sakura : 1; // [Valaris] unsigned leaves : 1; // [Valaris] unsigned rain : 1; // [Valaris] + unsigned no_player_drops : 1; // [Jaxad0127] } flag; struct point save; struct npc_data *npc[MAX_NPC_PER_MAP]; diff --git a/src/map/npc.c b/src/map/npc.c index 1a0462f..0c6c922 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1833,22 +1833,25 @@ static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4) } 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,"no_player_drops")==0) { // rain [Valaris] + map[m].flag.no_player_drops=1; + } return 0; } -- cgit v1.2.3-70-g09d2 From 8b59d27ee68fc3248dbf222f2ced18b57c13554a Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Sat, 26 Sep 2009 23:34:23 -0600 Subject: Fix a bug in mob exp determination --- src/map/mob.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/mob.c b/src/map/mob.c index f04ff28..a5fc159 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -267,7 +267,7 @@ mob_gen_exp(struct mob_db *mob) double mod_def = 100 - mob->def; if (mod_def == 0) mod_def = 1; double effective_hp = ((50 - mob->luk) * mob->max_hp / 50.0) + (2 * mob->luk * mob->max_hp / mod_def); - double attack_factor = (mob->atk1 + mob->atk2 + mob->str / 3.0 + mob->dex / 2.0 + mob->luk) * (1872 / mob->adelay) / 4; + double attack_factor = (mob->atk1 + mob->atk2 + mob->str / 3.0 + mob->dex / 2.0 + mob->luk) * (1872.0 / mob->adelay) / 4; double dodge_factor = pow(mob->lv + mob->agi + mob->luk / 2.0, 4.0 / 3.0); double persuit_factor = (3 + mob->range) * (mob->mode % 2) * 1000 / mob->speed; double aggression_factor = (mob->mode & 4) == 4 ? 10.0 / 9.0 : 1.0; -- cgit v1.2.3-70-g09d2 From bf27f14214997e97aad2a80b24885b8f9af30e0a Mon Sep 17 00:00:00 2001 From: Fate Date: Sun, 27 Sep 2009 15:32:58 +0000 Subject: Added "Mallard's Eye" skill (45) for ranged weapon users: increase to-hit, increase range, decrease the malus effect of distance. Also added an up to 31.25% damage bonus for hitting enemies that are farther away (only affects ranged weapons). Fixed a bug that would forget to recompute stats after changing skill focus. --- src/map/battle.c | 24 +++++++++++++++++------- src/map/pc.c | 10 ++++++---- src/map/skill-pools.c | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 9b5f699..177c63e 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2283,6 +2283,7 @@ static struct Damage battle_calc_pc_weapon_attack( int watk,watk_,cardfix,t_ele; int da=0,i,t_class,ac_flag = 0; int idef_flag=0,idef_flag_=0; + int target_distance; //returnȌ̂ŏô͕ݕύX if( src == NULL || target == NULL || sd == NULL ){ @@ -2354,27 +2355,36 @@ static struct Damage battle_calc_pc_weapon_attack( } } hitrate=battle_get_hit(src) - flee + 80; //vZ - battle_is_unarmed(src); - { // [Fate] Reduce hit chance by distance + + { // [fate] Reduce hit chance by distance int dx = abs(src->x - target->x); int dy = abs(src->y - target->y); - int dist = MAX(dx, dy); - hitrate -= (dist * (dist + 1)); - } + int malus_dist; - type=0; // normal - div_ = 1; // single attack + target_distance = MAX(dx, dy); + malus_dist = MAX(0, target_distance - (skill_power(sd, AC_OWL) / 75)); + hitrate -= (malus_dist * (malus_dist + 1)); + } dex=battle_get_dex(src); //DEX luk=battle_get_luk(src); //LUK watk = battle_get_atk(src); //ATK watk_ = battle_get_atk_(src); //ATK + type=0; // normal + div_ = 1; // single attack + if(skill_num==HW_MAGICCRASHER){ /* }WbNNbV[MATKʼn */ damage = damage2 = battle_get_matk1(src); //damega,damega2oAbase_atk̎擾 }else{ damage = damage2 = battle_get_baseatk(&sd->bl); //damega,damega2oAbase_atk̎擾 } + if (sd->attackrange > 2) { // [fate] ranged weapon? + const int range_damage_bonus = 80; // up to 31.25% bonus for long-range hit + damage = damage * (256 + ((range_damage_bonus * target_distance) / sd->attackrange)) >> 8; + damage2 = damage2 * (256 + ((range_damage_bonus * target_distance) / sd->attackrange)) >> 8; + } + atkmin = atkmin_ = dex; //ŒATKDEXŏH sd->state.arrow_atk = 0; //arrow_atk if(sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]]) diff --git a/src/map/pc.c b/src/map/pc.c index 5976137..e2f8eec 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1431,9 +1431,6 @@ int pc_calcstatus(struct map_session_data* sd,int first) if( (skill=pc_checkskill(sd,MC_INCCARRY))>0 ) // skill can be used with an item now, thanks to orn [Valaris] sd->max_weight += skill*1000; - if( (skill=pc_checkskill(sd,AC_OWL))>0 ) // �ӂ��낤�̖� - sd->paramb[4] += skill; - // �X�e�[�^�X�ω��ɂ������{�p�����[�^�␳ if(sd->sc_count){ if(sd->sc_data[SC_CONCENTRATE].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1){ // �W���͌��� @@ -1568,10 +1565,15 @@ int pc_calcstatus(struct map_session_data* sd,int first) if( (skill=pc_checkskill(sd,AC_VULTURE))>0){ // ���V�̖� sd->hit += skill; - if(sd->status.weapon == 11) + if (sd->status.weapon == 11) sd->attackrange += skill; } + if (sd->attackrange > 2) { // [fate] ranged weapon? + sd->attackrange += MIN(skill_power(sd, AC_OWL) / 60, 3); + sd->hit += skill_power(sd, AC_OWL) / 10; // 20 for 200 + } + if( (skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0) // ���팤���̖��������� sd->hit += skill*2; if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) // �g���l���h���C�u // �g���l���h���C�u diff --git a/src/map/skill-pools.c b/src/map/skill-pools.c index de7f04b..177a6a2 100644 --- a/src/map/skill-pools.c +++ b/src/map/skill-pools.c @@ -96,10 +96,10 @@ skill_pool_activate(struct map_session_data *sd, int skill_id) else if (sd->status.skill[skill_id].id == skill_id // knows the skill && (skill_pool_size(sd) < skill_pool_max(sd))) { sd->status.skill[skill_id].flags |= SKILL_POOL_ACTIVATED; + pc_calcstatus(sd, 0); MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d", skill_id, sd->status.skill[skill_id].lv, skill_power(sd, skill_id)); return 0; } - pc_calcstatus(sd, 0); return 1; // failed } -- cgit v1.2.3-70-g09d2 From b6054caba250ed1af333604fb483d51d28a7aa90 Mon Sep 17 00:00:00 2001 From: Fate Date: Sun, 27 Sep 2009 16:21:11 +0000 Subject: Added resist-poison skill that reduces the amount of time spent poisoned --- src/map/skill.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/map/skill.c b/src/map/skill.c index 6cff936..5f0092a 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -8029,6 +8029,10 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data) break; case SC_POISON: if(sc_data[SC_SLOWPOISON].timer == -1) { + const int resist_poison = skill_power_bl(bl, TMW_RESIST_POISON) >> 3; + if (resist_poison) + sc_data[type].val1 -= MRAND(resist_poison + 1); + if( (--sc_data[type].val1) > 0) { int hp = battle_get_max_hp(bl); -- cgit v1.2.3-70-g09d2 From 48d96bc41a4791b6cb0bc2cf514a6cc1f06c4dd8 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 28 Sep 2009 13:05:53 -0600 Subject: Revert "Prevent trading with other players who are shoping" This reverts commit b3939b91deda8081c5b144109829599b05e81272. --- src/map/trade.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/trade.c b/src/map/trade.c index 9e99ef1..31f29ce 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -28,7 +28,7 @@ void trade_traderequest(struct map_session_data *sd,int target_id) return; } } - if (target_sd->npc_id || target_sd->npc_shopid) + if (target_sd->npc_id) { //Trade fails if you are using an NPC. clif_tradestart(sd, 2); -- cgit v1.2.3-70-g09d2