summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-02-06 18:38:51 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-02-06 18:38:51 +0000
commite7096ca70629c5fd5f824cec8e2d4307e8578913 (patch)
treeae574e1de73431050206ac7d01f3f04caaec7c41
parent86914c88410c49b2b84084f2165fc9b581f2986e (diff)
downloadhercules-e7096ca70629c5fd5f824cec8e2d4307e8578913.tar.gz
hercules-e7096ca70629c5fd5f824cec8e2d4307e8578913.tar.bz2
hercules-e7096ca70629c5fd5f824cec8e2d4307e8578913.tar.xz
hercules-e7096ca70629c5fd5f824cec8e2d4307e8578913.zip
- Added define clif_deadsit to send the dead state into player packets if the player is in trick dead state.
- Venom Splasher always hits (but splash damage targets can still avoid it) - Using autoloot with no arguments now toggles it between @autoloot 0 and @autoloot 100% - Falcon Assault now takes Blitz Beat lv5 as base damage. - Fixed pc_makesavestatus not updating status.option correctly. - Corrected Waterball so that higher levels can do insane amount of hits. - Altered slave behaviour. No more random walking, will stay within 2 cells of their master. - Reverted the Summon Slave behaviour to not adjust level based on number of current slaves. - Coma no longer sends SP to 1. - Updated Meteor so that when level 11 or more is casted, the area over which meteors fall is tripled. - Dark elemental characters are now inmune to Curse. - Fixed sc_data saving to sql buffer building method. Thanks to its_sparky. - Changed the map zone reading from using pow to a bit shift. - Experience has now been changed to unsigned int, and is read as such from the dbs. - Increased HT_DETECTING seek range to 7x7 - Added function map_foreachinrange which actually checks distance of nearing objects (unlike for each in area which uses a square area), may come handy for future code. - Corrected Venom Splasher: Being hit does not cancels it, works at 75% or less of target's HP, being hit normally while under the count has a chance of causing poison. Damage is +400% + 50*lv% git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5204 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r--Changelog-Trunk.txt25
-rw-r--r--src/char_sql/char.c7
-rw-r--r--src/common/core.h8
-rw-r--r--src/common/mmo.h3
-rw-r--r--src/map/atcommand.c21
-rw-r--r--src/map/battle.c9
-rw-r--r--src/map/charcommand.c4
-rw-r--r--src/map/charsave.c7
-rw-r--r--src/map/clif.c7
-rw-r--r--src/map/irc.c4
-rw-r--r--src/map/irc.h4
-rw-r--r--src/map/map.c73
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/mob.c23
-rw-r--r--src/map/npc.c3
-rw-r--r--src/map/pc.c55
-rw-r--r--src/map/pc.h14
-rw-r--r--src/map/skill.c47
-rw-r--r--src/map/status.c7
19 files changed, 222 insertions, 101 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 111297ed4..f6dceae4e 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,31 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EVERYTHING ELSE
GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
+2006/02/06
+ * Venom Splasher update: [Skotlex]
+ - always hits (but splash damage targets can still avoid it)
+ - Being hit does not cancels it,
+ - works at 75% or less of target's HP
+ - being hit normally while under the count has a chance of causing poison.
+ - Damage is +400% + 50*lv%
+ * Using autoloot with no arguments now toggles it between @autoloot 0 and
+ @autoloot 100% [Skotlex]
+ * Falcon Assault now takes Blitz Beat lv5 as base damage. [Skotlex]
+ * Fixed pc_makesavestatus not updating status.option correctly. [Skotlex]
+ * Corrected Waterball so that higher levels can do insane amount of hits. [Skotlex]
+ * Altered slave behaviour. No more random walking, will stay within 2 cells
+ of their master. [Skotlex]
+ * Reverted the Summon Slave behaviour to not adjust level based on number
+ of current slaves. [Skotlex]
+ * Coma no longer sends SP to 1. [Skotlex]
+ * Updated Meteor so that when level 11 or more is casted, the area over
+ which meteors fall is tripled. [Skotlex]
+ * Dark elemental characters are now inmune to Curse. [Skotlex]
+ * Fixed sc_data saving to sql buffer building method. Thanks to its_sparky. [Skotlex]
+ * Changed the map zone reading from using pow to a bit shift. [Skotlex]
+ * Experience has now been changed to unsigned int, and is read as such from
+ the dbs. [Skotlex]
+ * Increased HT_DETECTING seek range to 7x7 [Skotlex]
2006/02/05
* Added some of eAIRC bot code, written by me and LittleWolf.
It is disabled and has no configuration options yet, as it is not finished. [Valaris]
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index d1a1a6a46..e08e6a07a 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -2901,22 +2901,23 @@ int parse_frommap(int fd) {
#ifdef ENABLE_SC_SAVING
int count, aid, cid, i;
struct status_change_data data;
+ char *p = tmp_sql;
aid = RFIFOL(fd, 4);
cid = RFIFOL(fd, 8);
count = RFIFOW(fd, 12);
- sprintf(tmp_sql, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", scdata_db);
+ p+ = sprintf(p, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", scdata_db);
for (i = 0; i < count; i++)
{
memcpy (&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data));
- sprintf (tmp_sql, "%s ('%d','%d','%hu','%d','%d','%d','%d','%d'),", tmp_sql, aid, cid,
+ p += sprintf (p, " ('%d','%d','%hu','%d','%d','%d','%d','%d'),", aid, cid,
data.type, data.tick, data.val1, data.val2, data.val3, data.val4);
}
if (count > 0)
{
- tmp_sql[strlen(tmp_sql)-1] = '\0'; //Remove final comma.
+ *--p = '\0'; //Remove final comma.
if (mysql_query(&mysql_handle, tmp_sql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
diff --git a/src/common/core.h b/src/common/core.h
index 22f625a5d..ce57c28a6 100644
--- a/src/common/core.h
+++ b/src/common/core.h
@@ -5,14 +5,6 @@
#define _CORE_H_
//#define SQL_DEBUG //uncomment for debug_mysql_query instead of mysql_real_query
-
-/* REMOVED because these type of function defines with va_args are a GCC feature and won't compile under Windows [Skotlex]
-//Added here, so its avail in 'all' files ..
-#define eprintf(mes, args...) \
- fprintf(stderr, "%s:%d: "mes"", __FILE__, __LINE__, args);
-#define eprint(mes) \
- fprintf(stderr, "%s:%d: "mes"", __FILE__, __LINE__);
-*/
extern int arg_c;
extern char **arg_v;
diff --git a/src/common/mmo.h b/src/common/mmo.h
index d0d4685e2..04ea008bc 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -175,7 +175,8 @@ struct mmo_charstatus {
int mother;
int child;
- int base_exp,job_exp,zeny;
+ unsigned int base_exp,job_exp;
+ int zeny;
short class_;
short status_point,skill_point;
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 445c65a48..fd14b0944 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2680,7 +2680,7 @@ int atcommand_baselevelup(
clif_displaymessage(fd, msg_table[47]); /* Base level can't go any higher. */
return -1;
} /* End Addition */
- if (level > pc_maxbaselv(sd) || level > (pc_maxbaselv(sd) - sd->status.base_level)) // fix positiv overflow
+ if (level > pc_maxbaselv(sd) || level > (pc_maxbaselv(sd) - (int)sd->status.base_level)) // fix positiv overflow
level = pc_maxbaselv(sd) - sd->status.base_level;
for (i = 1; i <= level; i++)
sd->status.status_point += (sd->status.base_level + i + 14) / 5;
@@ -2739,7 +2739,7 @@ int atcommand_joblevelup(
clif_displaymessage(fd, msg_table[23]); // Job level can't go any higher.
return -1;
}
- if (level > pc_maxjoblv(sd) || level > (pc_maxjoblv(sd) - sd->status.job_level)) // fix positiv overflow
+ if (level > pc_maxjoblv(sd) || level > (pc_maxjoblv(sd) - (int)sd->status.job_level)) // fix positiv overflow
level = pc_maxjoblv(sd) - sd->status.job_level;
sd->status.job_level += level;
clif_updatestatus(sd, SP_JOBLEVEL);
@@ -7633,17 +7633,14 @@ atcommand_autoloot(
double drate;
nullpo_retr(-1, sd);
if (!message || !*message) {
- if (sd->state.autoloot) {
- sd->state.autoloot = 0;
- clif_displaymessage(fd, "Autoloot is now off.");
- return 0;
- } else {
- clif_displaymessage(fd, "Usage: autoloot <max drop-rate to loot>.");
- return -1;
- }
+ if (sd->state.autoloot)
+ rate = 0;
+ else
+ rate = 10000;
+ } else {
+ drate = atof(message);
+ rate = (int)(drate*100);
}
- drate = atof(message);
- rate = (int)(drate*100);
if (rate > 10000) rate = 10000;
else if (rate < 0) rate = 0;
diff --git a/src/map/battle.c b/src/map/battle.c
index d6614a17b..efdb444b8 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1361,6 +1361,9 @@ static struct Damage battle_calc_weapon_attack(
if (skill_num && !flag.hit)
switch(skill_num)
{
+ case AS_SPLASHER: //Reports say it always hits?
+ if (wflag) //Only if you were the one exploding.
+ break;
case NPC_GUIDEDATTACK:
case RG_BACKSTAP:
case AM_ACIDTERROR:
@@ -1775,7 +1778,7 @@ static struct Damage battle_calc_weapon_attack(
skillratio += 100+100*skill_lv;
break;
case AS_SPLASHER:
- skillratio += 100+20*skill_lv;
+ skillratio += 400+50*skill_lv;
if (sd)
skillratio += 20*pc_checkskill(sd,AS_POISONREACT);
if(wflag>1) //FIXME: Splash damage... is this the correct method? [Skotlex]
@@ -2818,7 +2821,7 @@ struct Damage battle_calc_misc_attack(
case SN_FALCONASSAULT: /* ファルコンアサルト */
if( sd==NULL || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
skill=0;
- damage=(dex/10+int_/2+skill*3+40)*2*skill_get_num(HT_BLITZBEAT, skill_lv); //Blitz Beat Damage
+ damage=(dex/10+int_/2+skill*3+40)*2*skill_get_num(HT_BLITZBEAT, 5); //Blitz Beat lv5 Damage
damage=damage*(150+70*skill_lv)/100; //Falcon Assault Modifier
if(flag > 1)
damage /= flag;
@@ -3194,8 +3197,6 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
if (tsc->data[SC_POISONREACT].val2 <= 0)
status_change_end(target, SC_POISONREACT, -1);
}
- if (tsc->data[SC_SPLASHER].timer != -1) //殴ったので対?ロのベナムスプラッシャ?[?態を解?
- status_change_end(target, SC_SPLASHER, -1);
}
//SG_FUSION hp penalty [Komurka]
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index e2d4f84c6..33beca832 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -1262,7 +1262,7 @@ int charcommand_baselevel(
clif_displaymessage(fd, msg_table[91]); // Character's base level can't go any higher.
return 0;
} // End Addition
- if (level > pc_maxbaselv(pl_sd) || level > (pc_maxbaselv(pl_sd)- pl_sd->status.base_level)) // fix positiv overflow
+ if (level > pc_maxbaselv(pl_sd) || level > (pc_maxbaselv(pl_sd)- (int)pl_sd->status.base_level)) // fix positiv overflow
level = pc_maxbaselv(pl_sd) - pl_sd->status.base_level;
for (i = 1; i <= level; i++)
pl_sd->status.status_point += (pl_sd->status.base_level + i + 14) / 5;
@@ -1333,7 +1333,7 @@ int charcommand_joblevel(
clif_displaymessage(fd, msg_table[67]); // Character's job level can't go any higher.
return -1;
}
- if (pl_sd->status.job_level + level > pc_maxjoblv(pl_sd))
+ if ((int)pl_sd->status.job_level + level > pc_maxjoblv(pl_sd))
level = pc_maxjoblv(pl_sd) - pl_sd->status.job_level;
pl_sd->status.job_level += level;
clif_updatestatus(pl_sd, SP_JOBLEVEL);
diff --git a/src/map/charsave.c b/src/map/charsave.c
index e9fc888db..c335064c5 100644
--- a/src/map/charsave.c
+++ b/src/map/charsave.c
@@ -486,8 +486,9 @@ void charsave_save_scdata(int account_id, int char_id, struct status_change* sc_
int i,count =0;
struct TimerData *timer;
unsigned int tick = gettick();
+ char *p = tmp_sql;
- sprintf(tmp_sql, "INSERT INTO `sc_data` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ");
+ p += sprintf(p, "INSERT INTO `sc_data` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ");
for(i = 0; i < max_sc; i++)
{
@@ -497,14 +498,14 @@ void charsave_save_scdata(int account_id, int char_id, struct status_change* sc_
if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
continue;
- sprintf (tmp_sql, "%s ('%d','%d','%hu','%d','%d','%d','%d','%d'),", tmp_sql, account_id, char_id,
+ p += (p, " ('%d','%d','%hu','%d','%d','%d','%d','%d'),", account_id, char_id,
i, DIFF_TICK(timer->tick,tick), sc_data->data[i].val1, sc_data->data[i].val2, sc_data->data[i].val3, sc_data->data[i].val4);
count++;
}
if (count > 0)
{
- tmp_sql[strlen(tmp_sql)-1] = '\0'; //Remove the trailing comma.
+ *--p = '\0'; //Remove the trailing comma.
if(mysql_query(&charsql_handle, tmp_sql)){
ShowSQL("DB error - %s\n",mysql_error(&charsql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
diff --git a/src/map/clif.c b/src/map/clif.c
index be213f47b..c40a0a037 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -754,6 +754,7 @@ int clif_clearchar_id(int id, int type, int fd) {
(sd->inventory_data[sd->equip_index[n]]->view_id > 0)?sd->inventory_data[sd->equip_index[n]]->view_id: \
sd->status.inventory[sd->equip_index[n]].nameid):0)
+#define clif_deadsit(sd) (((sd)->sc.count && (sd)->sc.data[SC_TRICKDEAD].timer != -1)?1:sd->state.dead_sit)
/*==========================================
*
*------------------------------------------
@@ -802,7 +803,7 @@ static int clif_set0078(struct map_session_data *sd, unsigned char *buf) {
WBUFB(buf,48)|=sd->dir&0x0f;
WBUFB(buf,49)=5;
WBUFB(buf,50)=5;
- WBUFB(buf,51)=sd->state.dead_sit;
+ WBUFB(buf,51)=clif_deadsit(sd);
WBUFW(buf,52)=clif_setlevel(sd->status.base_level);
return packet_len_table[0x78];
@@ -841,7 +842,7 @@ static int clif_set0078(struct map_session_data *sd, unsigned char *buf) {
WBUFB(buf,48)|=sd->dir & 0x0f;
WBUFB(buf,49)=5;
WBUFB(buf,50)=5;
- WBUFB(buf,51)=sd->state.dead_sit;
+ WBUFB(buf,51)=clif_deadsit(sd);
WBUFW(buf,52)=clif_setlevel(sd->status.base_level);
return packet_len_table[0x1d8];
@@ -870,7 +871,7 @@ static int clif_dis0078(struct map_session_data *sd, unsigned char *buf) {
WBUFB(buf,48)|=sd->dir&0x0f;
WBUFB(buf,49)=5;
WBUFB(buf,50)=5;
- WBUFB(buf,51)=sd->state.dead_sit;
+ WBUFB(buf,51)=clif_deadsit(sd);
WBUFW(buf,52)=0;
return packet_len_table[0x78];
diff --git a/src/map/irc.c b/src/map/irc.c
index e72af4d0d..5bc0dd633 100644
--- a/src/map/irc.c
+++ b/src/map/irc.c
@@ -247,12 +247,12 @@ int send_to_parser(int fd, char *input,char key[2])
return total_loops;
}
-void do_final_irc()
+void do_final_irc(void)
{
}
-void do_init_irc()
+void do_init_irc(void)
{
if(!use_irc)
return;
diff --git a/src/map/irc.h b/src/map/irc.h
index 575b93301..fe48c51ff 100644
--- a/src/map/irc.h
+++ b/src/map/irc.h
@@ -13,8 +13,8 @@ void irc_announce_shop(struct map_session_data *sd,int flag);
void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md);
int irc_parse(int fd);
-void do_final_irc();
-void do_init_irc();
+void do_final_irc(void);
+void do_init_irc(void);
void irc_send(char *buf);
void irc_parse_sub(int fd, char *incoming_string);
int send_to_parser(int fd, char *input,char key[2]);
diff --git a/src/map/map.c b/src/map/map.c
index f69af6d7c..3b0c59e28 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -640,6 +640,79 @@ struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,in
}
/*==========================================
+ * Adapted from foreachinarea to use real ranges around a character area. [Skotlex]
+ *------------------------------------------
+ */
+
+int map_foreachinrange(int (*func)(struct block_list*,va_list),int m,struct block_list *center, int range,int type,...) {
+ va_list ap;
+ int bx,by;
+ int returnCount =0; //total sum of returned values of func() [Skotlex]
+ struct block_list *bl=NULL;
+ int blockcount=bl_list_count,i,c;
+ int x0,x1,y0,y1;
+
+ if (m < 0)
+ return 0;
+ va_start(ap,type);
+ x0 = center->x-range;
+ x1 = center->x+range;
+ y0 = center->y-range;
+ y1 = center->y+range;
+
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 >= map[m].xs) x1 = map[m].xs-1;
+ if (y1 >= map[m].ys) y1 = map[m].ys-1;
+
+ if (type&~BL_MOB)
+ for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
+ for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+ bl = map[m].block[bx+by*map[m].bxs];
+ c = map[m].block_count[bx+by*map[m].bxs];
+ for(i=0;i<c && bl;i++,bl=bl->next){
+ if(bl && bl->type&type
+ && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
+ && check_distance_bl(center, bl, range)
+ && bl_list_count<BL_LIST_MAX)
+ bl_list[bl_list_count++]=bl;
+ }
+ }
+ }
+ if(type&BL_MOB)
+ for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){
+ for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+ bl = map[m].block_mob[bx+by*map[m].bxs];
+ c = map[m].block_mob_count[bx+by*map[m].bxs];
+ for(i=0;i<c && bl;i++,bl=bl->next){
+ if(bl
+ && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
+ && check_distance_bl(center, bl, range)
+ && bl_list_count<BL_LIST_MAX)
+ bl_list[bl_list_count++]=bl;
+ }
+ }
+ }
+
+ if(bl_list_count>=BL_LIST_MAX) {
+ if(battle_config.error_log)
+ ShowWarning("map_foreachinrange: block count too many!\n");
+ }
+
+ map_freeblock_lock(); // メモリからの解放を禁止する
+
+ for(i=blockcount;i<bl_list_count;i++)
+ if(bl_list[i]->prev) // 有?かどうかチェック
+ returnCount += func(bl_list[i],ap);
+
+ map_freeblock_unlock(); // 解放を許可する
+
+ va_end(ap);
+ bl_list_count = blockcount;
+ return returnCount; //[Skotlex]
+}
+
+/*==========================================
* map m (x0,y0)-(x1,y1)?の全objに?して
* funcを呼ぶ
* type!=0 ならその種類のみ
diff --git a/src/map/map.h b/src/map/map.h
index 960e99424..48c2b4093 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -1223,6 +1223,8 @@ int map_delblock_sub(struct block_list *, int);
#define map_addblock(bl) map_addblock_sub(bl,1)
#define map_delblock(bl) map_delblock_sub(bl,1)
int map_moveblock(struct block_list *, int, int, unsigned int);
+
+int map_foreachinrange(int (*)(struct block_list*,va_list),int,struct block_list *,int,int,...);
int map_foreachinarea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,...);
// -- moonsoul (added map_foreachincell)
int map_foreachincell(int (*)(struct block_list*,va_list),int,int,int,int,...);
diff --git a/src/map/mob.c b/src/map/mob.c
index b40c18495..c0597eff1 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -39,6 +39,7 @@
#define MOB_LAZYMOVEPERC 50 // Move probability in the negligent mode MOB (rate of 1000 minute)
#define MOB_LAZYWARPPERC 20 // Warp probability in the negligent mode MOB (rate of 1000 minute)
+#define MOB_SLAVEDISTANCE 2 //Distance that slaves should keep from their master.
//Dynamic mob database, allows saving of memory when there's big gaps in the mob_db [Skotlex]
struct mob_db *mob_db_data[MAX_MOB_DB+1];
struct mob_db *mob_dummy = NULL; //Dummy mob to be returned when a non-existant one is requested.
@@ -1424,18 +1425,23 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
if((!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mob_can_move(md) &&
md->master_dist<md->db->range3 && (md->walkpath.path_pos>=md->walkpath.path_len || md->walkpath.path_len==0)){
int i=0,dx,dy,ret;
- if(md->master_dist>AREA_SIZE/2 && DIFF_TICK(md->next_walktime,tick)<3000) { //Allow it to cut down the walk time to chase back. [Skotlex]
+ if(md->master_dist>MOB_SLAVEDISTANCE || md->master_dist == 0)
+ { //Chase back to Master's area also if standing on top of the master.
do {
if(i<=5){
dx=bl->x - md->bl.x;
dy=bl->y - md->bl.y;
- if(dx<0) dx+=(rand()%-dx)/2; //On the minimum, half the distance between slave/master. [Skotlex]
- else if(dx>0) dx-=(rand()%dx)/2;
- if(dy<0) dy+=(rand()%-dy)/2;
- else if(dy>0) dy-=(rand()%dy)/2;
+
+ if(dx<0) dx+=rand()%MOB_SLAVEDISTANCE +1;
+ else if(dx>0) dx-=rand()%MOB_SLAVEDISTANCE +1;
+
+ if(dy<0) dy+=rand()%MOB_SLAVEDISTANCE +1;
+ else if(dy>0) dy-=rand()%MOB_SLAVEDISTANCE +1;
+
}else{
- dx=bl->x - md->bl.x + rand()%11- 5;
- dy=bl->y - md->bl.y + rand()%11- 5;
+ ret = MOB_SLAVEDISTANCE*2+1;
+ dx=bl->x - md->bl.x + rand()%ret - MOB_SLAVEDISTANCE;
+ dy=bl->y - md->bl.y + rand()%ret - MOB_SLAVEDISTANCE;
}
ret=mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0);
@@ -1854,7 +1860,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
return 0;
// Nothing else to do... except random walking.
- if (mode&MD_CANMOVE && mob_can_move(md))
+ // Slaves do not random walk! [Skotlex]
+ if (mode&MD_CANMOVE && mob_can_move(md) && !md->master_id)
{
if (DIFF_TICK(md->next_walktime, tick) > 7000 &&
(md->walkpath.path_len == 0 || md->walkpath.path_pos >= md->walkpath.path_len))
diff --git a/src/map/npc.c b/src/map/npc.c
index cf0632416..e02b31741 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2600,7 +2600,8 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
else if (strcmpi(w3,"restricted")==0) { // Komurka
map[m].flag.restricted=1;
sscanf(w4, "%d", &map[m].zone);
- map[m].zone = pow(2,map[m].zone+1);
+ //map[m].zone = pow(2,map[m].zone+1);
+ map[m].zone = 1<<(map[m].zone+1);
}
return 0;
diff --git a/src/map/pc.c b/src/map/pc.c
index 59843f095..a982bab13 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -41,8 +41,8 @@
#endif
#define PVP_CALCRANK_INTERVAL 1000 // PVP順位計算の間隔
-static int exp_table[MAX_PC_CLASS][2][MAX_LEVEL];
-static int max_level[MAX_PC_CLASS][2];
+static unsigned int exp_table[MAX_PC_CLASS][2][MAX_LEVEL];
+static unsigned int max_level[MAX_PC_CLASS][2];
static short statp[MAX_LEVEL];
// h-files are for declarations, not for implementations... [Shinomori]
@@ -416,7 +416,7 @@ int pc_makesavestatus(struct map_session_data *sd)
// 死亡?態だったのでhpを1、位置をセ?ブ場所に?更
if(!sd->state.waitingdisconnect) {
- sd->sc.option = sd->sc.option;
+ sd->status.option = sd->sc.option; //Since the option saved is in
if(pc_isdead(sd)){
pc_setrestartvalue(sd,0);
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
@@ -4687,11 +4687,11 @@ int pc_checkjoblevelup(struct map_session_data *sd)
* ??値取得
*------------------------------------------
*/
-int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
+int pc_gainexp(struct map_session_data *sd,unsigned int base_exp,unsigned int job_exp)
{
char output[256];
float nextbp=0, nextjp=0;
- int nextb=0, nextj=0;
+ unsigned int nextb=0, nextj=0;
nullpo_retr(0, sd);
if(sd->bl.prev == NULL || pc_isdead(sd))
@@ -4702,14 +4702,10 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
if(sd->status.guild_id>0){ // ギルドに上納
base_exp-=guild_payexp(sd,base_exp);
- if(base_exp < 0)
- base_exp = 0;
}
if(!battle_config.multi_level_up && pc_nextbaseafter(sd) && sd->status.base_exp+base_exp >= pc_nextbaseafter(sd)) {
base_exp = pc_nextbaseafter(sd) - sd->status.base_exp;
- if (base_exp < 0)
- base_exp = 0;
}
nextb = pc_nextbaseexp(sd);
nextj = pc_nextjobexp(sd);
@@ -4719,21 +4715,16 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
nextjp = (float) job_exp / (float) nextj;
sd->status.base_exp += base_exp;
- if(sd->status.base_exp < 0)
- sd->status.base_exp = 0;
while(pc_checkbaselevelup(sd)) ;
clif_updatestatus(sd,SP_BASEEXP);
+
if(!battle_config.multi_level_up && pc_nextjobafter(sd) && sd->status.job_exp+job_exp >= pc_nextjobafter(sd)) {
job_exp = pc_nextjobafter(sd) - sd->status.job_exp;
- if (job_exp < 0)
- job_exp = 0;
}
sd->status.job_exp += job_exp;
- if(sd->status.job_exp < 0)
- sd->status.job_exp = 0;
while(pc_checkjoblevelup(sd)) ;
@@ -4741,11 +4732,11 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
if(sd->state.showexp){
sprintf(output,
- "Experienced Gained Base:%d (%.2f%%) Job:%d (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
+ "Experience Gained Base:%d (%.2f%%) Job:%d (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
clif_disp_onlyself(sd,output,strlen(output));
}
- return 0;
+ return 1;
}
/*==========================================
@@ -4753,11 +4744,11 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
*------------------------------------------
*/
-int pc_maxbaselv(struct map_session_data *sd) {
+unsigned int pc_maxbaselv(struct map_session_data *sd) {
return max_level[sd->status.class_][0];
};
-int pc_maxjoblv(struct map_session_data *sd) {
+unsigned int pc_maxjoblv(struct map_session_data *sd) {
return max_level[sd->status.class_][1];
};
@@ -4765,7 +4756,7 @@ int pc_maxjoblv(struct map_session_data *sd) {
* base level側必要??値計算
*------------------------------------------
*/
-int pc_nextbaseexp(struct map_session_data *sd)
+unsigned int pc_nextbaseexp(struct map_session_data *sd)
{
nullpo_retr(0, sd);
@@ -4779,7 +4770,7 @@ int pc_nextbaseexp(struct map_session_data *sd)
* job level側必要??値計算
*------------------------------------------
*/
-int pc_nextjobexp(struct map_session_data *sd)
+unsigned int pc_nextjobexp(struct map_session_data *sd)
{
nullpo_retr(0, sd);
@@ -4792,7 +4783,7 @@ int pc_nextjobexp(struct map_session_data *sd)
* base level after next [Valaris]
*------------------------------------------
*/
-int pc_nextbaseafter(struct map_session_data *sd)
+unsigned int pc_nextbaseafter(struct map_session_data *sd)
{
nullpo_retr(0, sd);
@@ -4806,7 +4797,7 @@ int pc_nextbaseafter(struct map_session_data *sd)
* job level after next [Valaris]
*------------------------------------------
*/
-int pc_nextjobafter(struct map_session_data *sd)
+unsigned int pc_nextjobafter(struct map_session_data *sd)
{
nullpo_retr(0, sd);
@@ -8053,6 +8044,22 @@ int pc_split_atoi(char *str,int *val, char sep, int max)
return i;
}
+int pc_split_atoui(char *str,unsigned int *val, char sep, int max)
+{
+ int i,j;
+ for (i=0; i<max; i++) {
+ if (!str) break;
+ val[i] = (unsigned int)atof(str);
+ str = strchr(str,sep);
+ if (str)
+ *str++=0;
+ }
+ //Zero up the remaining.
+ for(j=i; j < max; j++)
+ val[j] = 0;
+ return i;
+}
+
//
// 初期化物
//
@@ -8110,7 +8117,7 @@ int pc_readdb(void)
max = MAX_LEVEL;
}
//We send one less and then one more because the last entry in the exp array should hold 0.
- max_level[job][type] = pc_split_atoi(split[3], exp_table[job][type],',',max-1)+1;
+ max_level[job][type] = pc_split_atoui(split[3], exp_table[job][type],',',max-1)+1;
//Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
//The reasoning behind the -2 is this... if the max level is 5, then the array
//should look like this:
diff --git a/src/map/pc.h b/src/map/pc.h
index 4c7cb886a..11e7539f8 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -117,15 +117,15 @@ int pc_follow(struct map_session_data*, int); // [MouseJstr]
int pc_stop_following(struct map_session_data*);
-int pc_maxbaselv(struct map_session_data *sd);
-int pc_maxjoblv(struct map_session_data *sd);
+unsigned int pc_maxbaselv(struct map_session_data *sd);
+unsigned int pc_maxjoblv(struct map_session_data *sd);
int pc_checkbaselevelup(struct map_session_data *sd);
int pc_checkjoblevelup(struct map_session_data *sd);
-int pc_gainexp(struct map_session_data*,int,int);
-int pc_nextbaseexp(struct map_session_data *);
-int pc_nextbaseafter(struct map_session_data *); // [Valaris]
-int pc_nextjobexp(struct map_session_data *);
-int pc_nextjobafter(struct map_session_data *); // [Valaris]
+int pc_gainexp(struct map_session_data*,unsigned int,unsigned int);
+unsigned int pc_nextbaseexp(struct map_session_data *);
+unsigned int pc_nextbaseafter(struct map_session_data *); // [Valaris]
+unsigned int pc_nextjobexp(struct map_session_data *);
+unsigned int pc_nextjobafter(struct map_session_data *); // [Valaris]
int pc_need_status_point(struct map_session_data *,int);
int pc_statusup(struct map_session_data*,int);
int pc_statusup2(struct map_session_data*,int,int);
diff --git a/src/map/skill.c b/src/map/skill.c
index 2abf2fb76..2b4ab9394 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -901,13 +901,23 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
rand() % 100 < tsc->data[SC_EDP].val2 * sc_def_vit / 100)
status_change_start(bl,SC_DPOISON,sc->data[SC_EDP].val1,0,0,0,skill_get_time2(ASC_EDP,sc->data[SC_EDP].val1),0);
}
- if (tsc->count && tsc->data[SC_KAAHI].timer != -1) {
- if (dstsd && dstsd->status.sp < 5*tsc->data[SC_KAAHI].val1)
- ; //Not enough SP to cast
- else {
- battle_heal(bl, bl, 200*tsc->data[SC_KAAHI].val1, -5*tsc->data[SC_KAAHI].val1, 1);
- if(dstsd && dstsd->fd)
- clif_heal(dstsd->fd,SP_HP,200*tsc->data[SC_KAAHI].val1);
+ if (tsc->count) {
+ if (tsc->data[SC_SPLASHER].timer != -1 &&
+ tsc->data[SC_POISON].timer == -1 &&
+ rand()%100< (2*tsc->data[SC_SPLASHER].val1+10)*sc_def_vit/100
+ ) {
+ status_change_start(bl,SC_POISON,tsc->data[SC_SPLASHER].val1,0,0,0,
+ skill_get_time2(tsc->data[SC_SPLASHER].val2,tsc->data[SC_SPLASHER].val1),0);
+ }
+
+ if(tsc->data[SC_KAAHI].timer != -1) {
+ if (dstsd && dstsd->status.sp < 5*tsc->data[SC_KAAHI].val1)
+ ; //Not enough SP to cast
+ else {
+ battle_heal(bl, bl, 200*tsc->data[SC_KAAHI].val1, -5*tsc->data[SC_KAAHI].val1, 1);
+ if(dstsd && dstsd->fd)
+ clif_heal(dstsd->fd,SP_HP,200*tsc->data[SC_KAAHI].val1);
+ }
}
}
}
@@ -3014,10 +3024,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s
case WZ_WATERBALL: /* ウォ?タ?ボ?ル */
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
if (skilllv>1) {
- int range = skilllv > 5 ? 2 : skilllv/2;
+ int range = skilllv/2;
//Rain doesn't affect WATERBALL (Rain has been removed at kRO) [Lupus]
//int cnt = (!map[src->m].flag.rain) ? skill_count_water(src,range) - 1 : skill_get_num(skillid,skilllv) - 1;
- int cnt = (src->type==BL_PC)?skill_count_water(src,range) - 1:(skilllv>3?24:8);
+ int cnt = (src->type==BL_PC)?skill_count_water(src,range) - 1:(range*range-1);
if (cnt > 0)
skill_addtimerskill(src,tick+150,bl->id,0,0,
skillid,skilllv,cnt,flag);
@@ -5086,8 +5096,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case NPC_SUMMONSLAVE: /* 手下?「喚 */
- if (md) //Only summon remaining slaves
- skilllv = skilllv - mob_countslave(&md->bl);
case NPC_SUMMONMONSTER: /* MOB?「喚 */
if(md)
mob_summonslave(md,md->db->skill[md->skillidx].val,skilllv,skillid);
@@ -5425,7 +5433,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case AS_SPLASHER: /* ベナムスプラッシャ? */
- if(status_get_max_hp(bl)*2/3 < status_get_hp(bl)) { //HPが2/3以??っていたら失敗
+ if(status_get_max_hp(bl)*3/4 < status_get_hp(bl)) { //HPが2/3以??っていたら失敗
map_freeblock_unlock();
return 1;
}
@@ -6227,7 +6235,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
case HT_DETECTING: /* ディテクティング */
map_foreachinarea( status_change_timer_sub,
- src->m, x-1, y-1, x+1,y+1,BL_CHAR,
+ src->m, x-3, y-3, x+3,y+3,BL_CHAR,
src,status_get_sc(src),SC_SIGHT,tick);
break;
@@ -6279,14 +6287,17 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
case WZ_METEOR: //?テオスト?ム
{
- int flag=0;
+ int flag=0, area = 7;
if (sc && sc->data[SC_MAGICPOWER].timer != -1)
flag = flag|2; //Store the magic power flag for future use. [Skotlex]
+ if (skilllv > skill_get_max(skillid))
+ area = area*3; //Double range area
for(i=0;i<2+(skilllv>>1);i++) {
int j=0;
do {
- tmpx = x + (rand()%7 - 3);
- tmpy = y + (rand()%7 - 3);
+
+ tmpx = x + (rand()%area - area/2);
+ tmpy = y + (rand()%area - area/2);
if(tmpx < 0)
tmpx = 0;
else if(tmpx >= map[src->m].xs)
@@ -6648,11 +6659,11 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
range=2;
break;
case WZ_METEOR:
- if (skilllv > 10) //?L範囲?テオ
+ if (skilllv > skill_get_max(skillid)) //?L範囲?テオ
range = 10;
break;
case WZ_VERMILION:
- if (skilllv > 10) //?L範囲LOV
+ if (skilllv > skill_get_max(skillid)) //?L範囲LOV
range = 25;
break;
case WZ_QUAGMIRE: //The target changes to "all" if used in a gvg map. [Skotlex]
diff --git a/src/map/status.c b/src/map/status.c
index 2e2613a8d..1a7dbb3d6 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -3720,7 +3720,9 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val
if((type==SC_FREEZE || type==SC_STONE) && undead_flag && !(flag&1))
//I've been informed that undead chars are inmune to stone curse too. [Skotlex]
return 0;
-
+ //Dark Elementals are inmune to curse.
+ if(type==SC_CURSE && elem == 7 && !(flag&1))
+ return 0;
if (type==SC_BLESSING && (bl->type==BL_PC || (!undead_flag && race!=6))) {
if (sc->data[SC_CURSE].timer!=-1)
@@ -4451,9 +4453,8 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val
break;
}
- case SC_COMA: //Coma. Sends a char to 1HP/SP
+ case SC_COMA: //Coma. Sends a char to 1HP
battle_damage(NULL, bl, status_get_hp(bl)-1, 0);
- if (sd) pc_heal(sd,0,-sd->status.sp+1);
return 0;
case SC_CARTBOOST: /* カ?トブ?スト */