diff options
author | Fate <fate-tmw@googlemail.com> | 2009-09-20 00:30:15 +0000 |
---|---|---|
committer | Fate <fate-tmw@googlemail.com> | 2009-09-20 00:30:15 +0000 |
commit | 264bf4fd6dfb501643cf9178e5471e9e0e55152b (patch) | |
tree | 3ac7e832801590219bd62e8c45ccca2ccf86d2dd | |
parent | 162c84a85c288bcb97df44d08e0c0ff271ec102b (diff) | |
download | tmwa-264bf4fd6dfb501643cf9178e5471e9e0e55152b.tar.gz tmwa-264bf4fd6dfb501643cf9178e5471e9e0e55152b.tar.bz2 tmwa-264bf4fd6dfb501643cf9178e5471e9e0e55152b.tar.xz tmwa-264bf4fd6dfb501643cf9178e5471e9e0e55152b.zip |
Initial support for skill pools
-rw-r--r-- | doc/script_ref.txt | 22 | ||||
-rw-r--r-- | src/map/Makefile | 3 | ||||
-rw-r--r-- | src/map/battle.c | 15 | ||||
-rw-r--r-- | src/map/battle.h | 1 | ||||
-rw-r--r-- | src/map/clif.c | 2 | ||||
-rw-r--r-- | src/map/pc.c | 16 | ||||
-rw-r--r-- | src/map/script.c | 107 | ||||
-rw-r--r-- | src/map/skill.c | 62 | ||||
-rw-r--r-- | src/map/skill.h | 28 |
9 files changed, 235 insertions, 21 deletions
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 <id> <name> 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 + /*========================================== * XLWt@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<MAX_SKILL_LEVEL && p;j++){ + for(j=0,p=split[8];j<MAX_SKILL_LEVEL && p;j++){ split2[j]=p; p=strchr(p,':'); if(p) *p++=0; @@ -9938,14 +9968,14 @@ int skill_readdb(void) for(k=0;k<MAX_SKILL_LEVEL;k++) skill_db[i].num[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]); - if(strcmpi(split[8],"yes") == 0) + if(strcmpi(split[9],"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) + if(strcmpi(split[13],"weapon") == 0) skill_db[i].skill_type=BF_WEAPON; else if(strcmpi(split[12],"magic") == 0) skill_db[i].skill_type=BF_MAGIC; @@ -9954,13 +9984,31 @@ int skill_readdb(void) else skill_db[i].skill_type=0; memset(split2,0,sizeof(split2)); - for(j=0,p=split[13];j<MAX_SKILL_LEVEL && p;j++){ + for(j=0,p=split[14];j<MAX_SKILL_LEVEL && p;j++){ split2[j]=p; p=strchr(p,':'); if(p) *p++=0; } for(k=0;k<MAX_SKILL_LEVEL;k++) skill_db[i].blewcount[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]); + + if (!strcmpi(split[15], "passive")) { + skill_pool_register(i); + skill_db[i].poolflags = SKILL_POOL_FLAG; + } else if (!strcmpi(split[15], "active")) { + skill_pool_register(i); + skill_db[i].poolflags = SKILL_POOL_FLAG | SKILL_POOL_ACTIVE; + } else + skill_db[i].poolflags = 0; + + skill_db[i].stat = scan_stat(split[16]); + + skill_names[i].desc = strdup(split[17]); + { // replace "_" by " " + char *s = skill_names[i].desc; + while ((s = strchr(s, '_'))) + *s = ' '; + } } fclose_(fp); printf("read db/skill_db.txt done\n"); diff --git a/src/map/skill.h b/src/map/skill.h index d0486f5..faff9a9 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -10,9 +10,13 @@ #define MAX_SKILL_ARROW_DB 150 #define MAX_SKILL_ABRA_DB 350 +#define SKILL_POOL_FLAG 0x1 // is a pool skill +#define SKILL_POOL_ACTIVE 0x2 // is an active pool skill +#define SKILL_POOL_ACTIVATED 0x4 // pool skill has been activated (used for clif) + // XLf[^x[X struct skill_db { - int range[MAX_SKILL_LEVEL],hit,inf,pl,nk,max; + int range[MAX_SKILL_LEVEL],hit,inf,pl,nk,max, stat, poolflags, max_raise; // `max' is the global max, `max_raise' is the maximum attainable via skill-ups 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]; @@ -684,6 +688,8 @@ enum { NPC_DARKCROSS = 338, + TMW_SKILLPOOL = 339, // skill pool size + TMW_MAGIC = 340, TMW_MAGIC_LIFE, TMW_MAGIC_WAR, @@ -818,5 +824,25 @@ enum { GD_EXTENSION, }; + +// [Fate] Skill pools API + +// Max. # of active entries in the skill pool +#define MAX_SKILL_POOL 3 +// Max. # of skills that may be classified as pool skills in db/skill_db.txt +#define MAX_POOL_SKILLS 128 + +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_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') + #endif |