summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFate <fate-tmw@googlemail.com>2009-09-20 00:30:15 +0000
committerFate <fate-tmw@googlemail.com>2009-09-20 00:30:15 +0000
commit264bf4fd6dfb501643cf9178e5471e9e0e55152b (patch)
tree3ac7e832801590219bd62e8c45ccca2ccf86d2dd
parent162c84a85c288bcb97df44d08e0c0ff271ec102b (diff)
downloadtmwa-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.txt22
-rw-r--r--src/map/Makefile3
-rw-r--r--src/map/battle.c15
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/pc.c16
-rw-r--r--src/map/script.c107
-rw-r--r--src/map/skill.c62
-rw-r--r--src/map/skill.h28
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
+
/*==========================================
* 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<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