Poison React now activates when character is damaged only - Fixes bugreport:109
Cloaking fixed to official behaviour (Thanks helvetica for the hour of testing) - Concerning bugreport:171 Fixed instancing long map names causing crashes - Cannot save or memo on instance maps (Lemongrass) - Map channels are no longer activated on instance maps (Lemongrass) - Fixed a character save issue with instance maps (Lemongrass) - Map local channels are disabled by default, this is custom (Lemongrass) - Just thank Lemongrass overall, I gave him a hard time with this issue ~ Hercules Merge ~ Update Bloody Lust and Maelstrom to official behaviour (Credits: malufett) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17408 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
1ed6911a71
commit
81e3b03ace
@ -30,7 +30,7 @@ chsys: (
|
||||
allow_user_channel_creation: true
|
||||
|
||||
/* "map_local_channel" is an instanced channel unique to each map. */
|
||||
map_local_channel: true
|
||||
map_local_channel: false
|
||||
map_local_channel_name: "map"
|
||||
map_local_channel_color: "Yellow"
|
||||
map_local_channel_autojoin: true /* Disable autojoin in specific maps through mapflag 'nomapchannelautojoin'. */
|
||||
|
@ -399,7 +399,9 @@
|
||||
380: Item Failed. [%s] is cooling down. Wait %d seconds.
|
||||
381: Skill Failed. [%s] requires %dx %s.
|
||||
382: You're too close to a stone or emperium to use this skill.
|
||||
//383-389 free
|
||||
383: You cannot create a savepoint in an instance.
|
||||
384: You cannot create a memo in an instance.
|
||||
//385-389 free
|
||||
//NoAsk
|
||||
390: Autorejecting is activated.
|
||||
391: Autorejecting is deactivated.
|
||||
|
@ -874,7 +874,7 @@
|
||||
2300,7,6,2,0,0x1,0,3,1,yes,0,0,1,none,0, SC_DIMENSIONDOOR,Dimension Door
|
||||
2301,7,6,2,0,0x1,0,3,1,yes,0,0,0,none,0, SC_CHAOSPANIC,Chaos Panic
|
||||
2302,7,6,2,0,0x1,0,3,1,yes,0,0,0,none,0, SC_MAELSTROM,Maelstrom
|
||||
2303,7,6,2,0,0x1,0,3,1,yes,0,0,0,none,0, SC_BLOODYLUST,Bloody Lust
|
||||
2303,7,6,2,0,0x1,3,3,1,yes,0,0,1,none,0, SC_BLOODYLUST,Bloody Lust
|
||||
2304,0,6,4,-1,0,0,3,1,no,0,0,0,weapon,0, SC_FEINTBOMB,Feint Bomb
|
||||
|
||||
//****
|
||||
|
@ -729,6 +729,11 @@ ACMD_FUNC(save)
|
||||
{
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if( map[sd->bl.m].instance_id ) {
|
||||
clif_displaymessage(fd, msg_txt(sd,383)); // You cannot create a savepoint in an instance.
|
||||
return 1;
|
||||
}
|
||||
|
||||
pc_setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
|
||||
if (sd->status.pet_id > 0 && sd->pd)
|
||||
intif_save_petdata(sd->status.account_id, &sd->pd->pet);
|
||||
@ -2221,8 +2226,7 @@ ACMD_FUNC(memo)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pc_memo(sd, position);
|
||||
return 0;
|
||||
return !pc_memo( sd, position );
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
|
@ -745,6 +745,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
|
||||
if( battle_config.ksprotection && mob_ksprotected(src, bl) )
|
||||
return 0;
|
||||
|
||||
if( map_getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) && skill_get_type(skill_id) != BF_MISC
|
||||
&& skill_get_casttype(skill_id) == CAST_GROUND )
|
||||
return 0;
|
||||
|
||||
if (bl->type == BL_PC) {
|
||||
sd=(struct map_session_data *)bl;
|
||||
//Special no damage states
|
||||
@ -2739,7 +2743,7 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
skillratio += sc->data[SC_OVERTHRUST]->val3;
|
||||
if(sc->data[SC_MAXOVERTHRUST])
|
||||
skillratio += sc->data[SC_MAXOVERTHRUST]->val2;
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST])
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAYNIGHTFEVER])
|
||||
skillratio += 100;
|
||||
if(sc->data[SC_ZENKAI] && sstatus->rhw.ele == sc->data[SC_ZENKAI]->val2 )
|
||||
skillratio += sc->data[SC_ZENKAI]->val1 * 2;
|
||||
@ -6008,7 +6012,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
}
|
||||
|
||||
if (tsc) {
|
||||
if (tsc->data[SC_POISONREACT] &&
|
||||
if (damage > 0 && tsc->data[SC_POISONREACT] &&
|
||||
(rnd()%100 < tsc->data[SC_POISONREACT]->val3
|
||||
|| sstatus->def_ele == ELE_POISON) &&
|
||||
// check_distance_bl(src, target, tstatus->rhw.range+1) && Doesn't checks range! o.O;
|
||||
|
@ -304,7 +304,22 @@ int chrif_save(struct map_session_data *sd, int flag) {
|
||||
WFIFOL(char_fd,4) = sd->status.account_id;
|
||||
WFIFOL(char_fd,8) = sd->status.char_id;
|
||||
WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting.
|
||||
memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status));
|
||||
|
||||
// If the user is on a instance map, we have to fake his current position
|
||||
if( map[sd->bl.m].instance_id ){
|
||||
struct mmo_charstatus status;
|
||||
|
||||
// Copy the whole status
|
||||
memcpy( &status, &sd->status, sizeof( struct mmo_charstatus ) );
|
||||
// Change his current position to his savepoint
|
||||
memcpy( &status.last_point, &status.save_point, sizeof( struct point ) );
|
||||
// Copy the copied status into the packet
|
||||
memcpy( WFIFOP( char_fd, 13 ), &status, sizeof( struct mmo_charstatus ) );
|
||||
} else {
|
||||
// Copy the whole status into the packet
|
||||
memcpy( WFIFOP( char_fd, 13 ), &sd->status, sizeof( struct mmo_charstatus ) );
|
||||
}
|
||||
|
||||
WFIFOSET(char_fd, WFIFOW(char_fd,2));
|
||||
|
||||
if( sd->status.pet_id > 0 && sd->pd )
|
||||
|
@ -1660,7 +1660,7 @@ void clif_quitsave(int fd,struct map_session_data *sd) {
|
||||
|
||||
/// Notifies the client of a position change to coordinates on given map (ZC_NPCACK_MAPMOVE).
|
||||
/// 0091 <map name>.16B <x>.W <y>.W
|
||||
void clif_changemap(struct map_session_data *sd, short map, int x, int y)
|
||||
void clif_changemap(struct map_session_data *sd, short m, int x, int y)
|
||||
{
|
||||
int fd;
|
||||
nullpo_retv(sd);
|
||||
@ -1668,7 +1668,18 @@ void clif_changemap(struct map_session_data *sd, short map, int x, int y)
|
||||
|
||||
WFIFOHEAD(fd,packet_len(0x91));
|
||||
WFIFOW(fd,0) = 0x91;
|
||||
mapindex_getmapname_ext(mapindex_id2name(map), (char*)WFIFOP(fd,2));
|
||||
if(map[m].instance_id) { // Instance map check to send client source map name so we don't crash player
|
||||
struct instance_data *im = &instance_data[map[m].instance_id];
|
||||
int i;
|
||||
if(!im) // This shouldn't happen but if it does give them the map we intended to give
|
||||
mapindex_getmapname_ext(map[m].name, (char*)WFIFOP(fd,2));
|
||||
for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) // Loop to find the src map we want
|
||||
if(im->map[i].m == m) {
|
||||
mapindex_getmapname_ext(map[im->map[i].src_m].name, (char*)WFIFOP(fd,2));
|
||||
break;
|
||||
}
|
||||
} else
|
||||
mapindex_getmapname_ext(map[m].name, (char*)WFIFOP(fd,2));
|
||||
WFIFOW(fd,18) = x;
|
||||
WFIFOW(fd,20) = y;
|
||||
WFIFOSET(fd,packet_len(0x91));
|
||||
@ -8286,7 +8297,7 @@ void clif_refresh(struct map_session_data *sd)
|
||||
int i;
|
||||
nullpo_retv(sd);
|
||||
|
||||
clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
|
||||
clif_changemap(sd,sd->bl.m,sd->bl.x,sd->bl.y);
|
||||
clif_inventorylist(sd);
|
||||
if(pc_iscarton(sd)) {
|
||||
clif_cartlist(sd);
|
||||
@ -9139,7 +9150,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
|
||||
if (sd->state.rewarp) { //Rewarp player.
|
||||
sd->state.rewarp = 0;
|
||||
clif_changemap(sd, sd->mapindex, sd->bl.x, sd->bl.y);
|
||||
clif_changemap(sd, sd->bl.m, sd->bl.x, sd->bl.y);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9379,7 +9390,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
status_calc_pc(sd, false); // Some conditions are map-dependent so we must recalculate
|
||||
sd->state.changemap = false;
|
||||
|
||||
if( Channel_Config.map_enable && Channel_Config.map_autojoin && !map[sd->bl.m].flag.chmautojoin) {
|
||||
// Instances do not need their own channels
|
||||
if( Channel_Config.map_enable && Channel_Config.map_autojoin && !map[sd->bl.m].flag.chmautojoin && !map[sd->bl.m].instance_id ) {
|
||||
channel_mjoin(sd); //join new map
|
||||
}
|
||||
}
|
||||
@ -9567,6 +9579,11 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
|
||||
if(sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH])
|
||||
return;
|
||||
|
||||
// Cloaking wall check is actually updated when you click to process next movement
|
||||
// not when you move each cell. This is official behaviour.
|
||||
if (sd->sc.data[SC_CLOAKING])
|
||||
skill_check_cloaking(&sd->bl, sd->sc.data[SC_CLOAKING]);
|
||||
|
||||
pc_delinvincibletimer(sd);
|
||||
|
||||
RFIFOPOS(fd, packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0], &x, &y, NULL);
|
||||
|
@ -345,7 +345,7 @@ void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int t
|
||||
int clif_spawn(struct block_list *bl); //area
|
||||
void clif_walkok(struct map_session_data *sd); // self
|
||||
void clif_move(struct unit_data *ud); //area
|
||||
void clif_changemap(struct map_session_data *sd, short map, int x, int y); //self
|
||||
void clif_changemap(struct map_session_data *sd, short m, int x, int y); //self
|
||||
void clif_changemapserver(struct map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port); //self
|
||||
void clif_blown(struct block_list *bl); // area
|
||||
void clif_slide(struct block_list *bl, int x, int y); // area
|
||||
|
@ -369,7 +369,7 @@ int instance_mapname2mapid(const char *name, short instance_id)
|
||||
{
|
||||
struct instance_data *im;
|
||||
int m = map_mapname2mapid(name);
|
||||
char iname[12];
|
||||
char iname[MAP_NAME_LENGTH];
|
||||
int i;
|
||||
|
||||
if(m < 0) {
|
||||
@ -377,6 +377,8 @@ int instance_mapname2mapid(const char *name, short instance_id)
|
||||
return m;
|
||||
}
|
||||
|
||||
strcpy(iname,name);
|
||||
|
||||
if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
|
||||
return m;
|
||||
|
||||
@ -386,8 +388,13 @@ int instance_mapname2mapid(const char *name, short instance_id)
|
||||
|
||||
for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
|
||||
if(im->map[i].src_m == m) {
|
||||
snprintf(iname, sizeof(iname), ((strchr(name,'@') == NULL)?"%.3d#%s":"%.3d%s"), instance_id, name);
|
||||
return mapindex_name2id(iname);
|
||||
char alt_name[MAP_NAME_LENGTH];
|
||||
if((strchr(iname,'@') == NULL) && strlen(iname) > 8) {
|
||||
memmove(iname, iname+(strlen(iname)-9), strlen(iname));
|
||||
snprintf(alt_name, sizeof(alt_name),"%d#%s", instance_id, iname);
|
||||
} else
|
||||
snprintf(alt_name, sizeof(alt_name),"%.3d%s", instance_id, iname);
|
||||
return map_mapname2mapid(alt_name);
|
||||
}
|
||||
|
||||
return m;
|
||||
@ -515,7 +522,7 @@ int instance_enter(struct map_session_data *sd, const char *name)
|
||||
if((m = instance_mapname2mapid(db->enter.mapname, p->instance_id)) < 0)
|
||||
return 3;
|
||||
|
||||
if(pc_setpos(sd, m, db->enter.x, db->enter.y, 0))
|
||||
if(pc_setpos(sd, map_id2index(m), db->enter.x, db->enter.y, 0))
|
||||
return 3;
|
||||
|
||||
// If there was an idle timer, let's stop it
|
||||
|
@ -425,8 +425,6 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
|
||||
if (sc->data[SC_DANCING])
|
||||
skill_unit_move_unit_group(skill_id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0);
|
||||
else {
|
||||
if (sc->data[SC_CLOAKING])
|
||||
skill_check_cloaking(bl, sc->data[SC_CLOAKING]);
|
||||
if (sc->data[SC_WARM])
|
||||
skill_unit_move_unit_group(skill_id2group(sc->data[SC_WARM]->val4), bl->m, x1-x0, y1-y0);
|
||||
if (sc->data[SC_BANDING])
|
||||
@ -2181,6 +2179,7 @@ int map_addinstancemap(const char *name, int id)
|
||||
{
|
||||
int src_m = map_mapname2mapid(name);
|
||||
int dst_m = -1, i;
|
||||
char iname[MAP_NAME_LENGTH];
|
||||
size_t size;
|
||||
|
||||
if(src_m < 0)
|
||||
@ -2209,8 +2208,16 @@ int map_addinstancemap(const char *name, int id)
|
||||
// Copy the map
|
||||
memcpy(&map[dst_m], &map[src_m], sizeof(struct map_data));
|
||||
|
||||
strcpy(iname,name);
|
||||
|
||||
// Alter the name
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name), ((strchr(name,'@') == NULL)?"%.3d#%s":"%.3d%s"), id, name);
|
||||
// Due to this being custom we only worry about preserving as many characters as necessary for accurate map distinguishing
|
||||
// This also allows us to maintain complete independence with main map functions
|
||||
if((strchr(iname,'@') == NULL) && strlen(iname) > 8) {
|
||||
memmove(iname, iname+(strlen(iname)-9), strlen(iname));
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name),"%d#%s", id, iname);
|
||||
} else
|
||||
snprintf(map[dst_m].name, sizeof(map[dst_m].name),"%.3d%s", id, iname);
|
||||
map[dst_m].name[MAP_NAME_LENGTH-1] = '\0';
|
||||
|
||||
map[dst_m].m = dst_m;
|
||||
@ -2225,6 +2232,7 @@ int map_addinstancemap(const char *name, int id)
|
||||
map[dst_m].block_mob = (struct block_list **)aCalloc(1,size);
|
||||
|
||||
map[dst_m].index = mapindex_addmap(-1, map[dst_m].name);
|
||||
map[dst_m].channel = NULL;
|
||||
|
||||
map_addmap2db(&map[dst_m]);
|
||||
|
||||
|
28
src/map/pc.c
28
src/map/pc.c
@ -1091,7 +1091,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
|
||||
/**
|
||||
* Fixes login-without-aura glitch (the screen won't blink at this point, don't worry :P)
|
||||
**/
|
||||
clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
|
||||
clif_changemap(sd,sd->bl.m,sd->bl.x,sd->bl.y);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4211,7 +4211,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
|
||||
case 12243: // Mercenary's Berserk Potion
|
||||
if( sd->md == NULL || sd->md->db == NULL )
|
||||
return 0;
|
||||
if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAYNIGHTFEVER] || sd->md->sc.data[SC__BLOODYLUST])
|
||||
if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAYNIGHTFEVER])
|
||||
return 0;
|
||||
if( nameid == 12242 && sd->md->db->lv < 40 )
|
||||
return 0;
|
||||
@ -4308,7 +4308,7 @@ int pc_useitem(struct map_session_data *sd,int n)
|
||||
return 0;
|
||||
|
||||
if (sd->sc.count && (
|
||||
sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_SATURDAYNIGHTFEVER] ||
|
||||
sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] ||
|
||||
(sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) ||
|
||||
sd->sc.data[SC_TRICKDEAD] ||
|
||||
sd->sc.data[SC_HIDING] ||
|
||||
@ -4879,7 +4879,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
|
||||
|
||||
if(sd->bl.prev != NULL){
|
||||
unit_remove_map_pc(sd,clrtype);
|
||||
clif_changemap(sd,map[m].index,x,y); // [MouseJstr]
|
||||
clif_changemap(sd,m,x,y); // [MouseJstr]
|
||||
} else if(sd->state.active) //Tag player for rewarping after map-loading is done. [Skotlex]
|
||||
sd->state.rewarp = 1;
|
||||
|
||||
@ -4992,6 +4992,11 @@ int pc_memo(struct map_session_data* sd, int pos)
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
if( map[sd->bl.m].instance_id ) {
|
||||
clif_displaymessage( sd->fd, msg_txt(sd,384) ); // You cannot create a memo in an instance.
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd->status.memo_point[pos].map = map_id2index(sd->bl.m);
|
||||
sd->status.memo_point[pos].x = sd->bl.x;
|
||||
sd->status.memo_point[pos].y = sd->bl.y;
|
||||
@ -8553,8 +8558,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( DIFF_TICK(sd->canequip_tick,gettick()) > 0 )
|
||||
{
|
||||
if( DIFF_TICK(sd->canequip_tick,gettick()) > 0 ) {
|
||||
clif_equipitemack(sd,n,0,0);
|
||||
return 0;
|
||||
}
|
||||
@ -8570,8 +8574,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST])
|
||||
{
|
||||
if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER]) {
|
||||
clif_equipitemack(sd,n,0,0); // fail
|
||||
return 0;
|
||||
}
|
||||
@ -8582,15 +8585,14 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
|
||||
pos = sd->equip_index[EQI_ACC_R] >= 0 ? EQP_ACC_L : EQP_ACC_R;
|
||||
}
|
||||
|
||||
if(pos == EQP_ARMS && id->equip == EQP_HAND_R)
|
||||
{ //Dual wield capable weapon.
|
||||
if(pos == EQP_ARMS && id->equip == EQP_HAND_R) { //Dual wield capable weapon.
|
||||
pos = (req_pos&EQP_ARMS);
|
||||
if (pos == EQP_ARMS) //User specified both slots, pick one for them.
|
||||
pos = sd->equip_index[EQI_HAND_R] >= 0 ? EQP_HAND_L : EQP_HAND_R;
|
||||
}
|
||||
|
||||
if (pos&EQP_HAND_R && battle_config.use_weapon_skill_range&BL_PC)
|
||||
{ //Update skill-block range database when weapon range changes. [Skotlex]
|
||||
if (pos&EQP_HAND_R && battle_config.use_weapon_skill_range&BL_PC) {
|
||||
//Update skill-block range database when weapon range changes. [Skotlex]
|
||||
i = sd->equip_index[EQI_HAND_R];
|
||||
if (i < 0 || !sd->inventory_data[i]) //No data, or no weapon equipped
|
||||
flag = 1;
|
||||
@ -8607,7 +8609,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
|
||||
}
|
||||
}
|
||||
|
||||
if(pos==EQP_AMMO){
|
||||
if(pos==EQP_AMMO) {
|
||||
clif_arrowequip(sd,n);
|
||||
clif_arrow_fail(sd,3);
|
||||
}
|
||||
|
@ -250,7 +250,6 @@ struct map_session_data {
|
||||
unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files
|
||||
unsigned int cansendmail_tick; // [Mail System Flood Protection]
|
||||
unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
|
||||
unsigned int bloodylust_tick; // bloodylust player timer [out/in re full-heal protection]
|
||||
|
||||
struct {
|
||||
short nameid;
|
||||
|
@ -16561,21 +16561,18 @@ BUILDIN_FUNC(instance_npcname)
|
||||
BUILDIN_FUNC(instance_mapname)
|
||||
{
|
||||
const char *str;
|
||||
char iname[12];
|
||||
int16 m;
|
||||
short instance_id = 0;
|
||||
|
||||
str = script_getstr(st,2);
|
||||
|
||||
if( script_hasdata(st,3) )
|
||||
instance_id = script_getnum(st,3);
|
||||
else
|
||||
instance_id = script_instancegetid(st);
|
||||
|
||||
// Build the instance mapname
|
||||
snprintf(iname, sizeof(iname), ((strchr(str,'@') == NULL)?"%.3d#%s":"%.3d%s"), instance_id, str);
|
||||
|
||||
// Check that instance mapname is a valid map
|
||||
if( !instance_id || (m = map_mapname2mapid(iname)) < 0 )
|
||||
if(!instance_id || (m = instance_mapname2mapid(str,instance_id)) < 0)
|
||||
script_pushconststr(st, "");
|
||||
else
|
||||
script_pushconststr(st, map[m].name);
|
||||
@ -16616,7 +16613,6 @@ BUILDIN_FUNC(instance_warpall)
|
||||
short instance_id;
|
||||
const char *mapn;
|
||||
int x, y;
|
||||
unsigned short mapindex;
|
||||
|
||||
mapn = script_getstr(st,2);
|
||||
x = script_getnum(st,3);
|
||||
@ -16632,9 +16628,8 @@ BUILDIN_FUNC(instance_warpall)
|
||||
if( !(p = party_search(instance_data[instance_id].party_id)) )
|
||||
return 0;
|
||||
|
||||
mapindex = map_id2index(m);
|
||||
for( i = 0; i < MAX_PARTY; i++ )
|
||||
if( (pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == instance_id ) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
|
||||
if( (pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == instance_id ) pc_setpos(pl_sd,map_id2index(m),x,y,CLR_TELEPORT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
103
src/map/skill.c
103
src/map/skill.c
@ -5028,7 +5028,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
dstsd = sd;
|
||||
}
|
||||
}
|
||||
else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAYNIGHTFEVER] || tsc->data[SC__BLOODYLUST])
|
||||
else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAYNIGHTFEVER])
|
||||
heal = 0; //Needed so that it actually displays 0 when healing.
|
||||
}
|
||||
clif_skill_nodamage (src, bl, skill_id, heal, 1);
|
||||
@ -10081,6 +10081,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
||||
case SC_DIMENSIONDOOR:
|
||||
case SC_CHAOSPANIC:
|
||||
case SC_MAELSTROM:
|
||||
case SC_BLOODYLUST:
|
||||
case WM_REVERBERATION:
|
||||
case WM_SEVERE_RAINSTORM:
|
||||
case WM_POEMOFNETHERWORLD:
|
||||
@ -10565,11 +10566,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
||||
sc_start2(src,src, type, 100, skill_id, skill_lv, skill_get_time(skill_id, skill_lv)));
|
||||
break;
|
||||
|
||||
case SC_BLOODYLUST: //set in another group so instance will move if recasted
|
||||
flag |= 33;
|
||||
skill_unitsetting(src, skill_id, skill_lv, x, y, 0);
|
||||
break;
|
||||
|
||||
case KO_MAKIBISHI:
|
||||
for( i = 0; i < (skill_lv+2); i++ ) {
|
||||
x = src->x - 1 + rnd()%3;
|
||||
@ -10629,7 +10625,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
|
||||
sd->sc.data[SC_AUTOCOUNTER] ||
|
||||
sd->sc.data[SC_STEELBODY] ||
|
||||
(sd->sc.data[SC_DANCING] && skill_id < RK_ENCHANTBLADE && !pc_checkskill(sd, WM_LESSON)) ||
|
||||
sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
|
||||
sd->sc.data[SC_BERSERK] ||
|
||||
sd->sc.data[SC_BASILICA] ||
|
||||
sd->sc.data[SC_MARIONETTE] ||
|
||||
sd->sc.data[SC_WHITEIMPRISON] ||
|
||||
@ -11163,9 +11159,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
|
||||
case SO_VACUUM_EXTREME:
|
||||
range++;
|
||||
|
||||
break;
|
||||
case SC_BLOODYLUST:
|
||||
skill_clear_group(src, 32);
|
||||
break;
|
||||
case GN_WALLOFTHORN:
|
||||
if( flag&1 )
|
||||
@ -11299,6 +11292,9 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
|
||||
if (unit_flag&UF_RANGEDSINGLEUNIT && i == (layout->count / 2))
|
||||
val2 |= UF_RANGEDSINGLEUNIT; // center.
|
||||
|
||||
if( sd && map_getcell(src->m, ux, uy, CELL_CHKMAELSTROM) ) //Does not recover SP from monster skills
|
||||
map_foreachincell(skill_maelstrom_suction,src->m,ux,uy,BL_SKILL,skill_id,skill_lv);
|
||||
|
||||
if( range <= 0 )
|
||||
map_foreachincell(skill_cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src);
|
||||
if( !alive )
|
||||
@ -11360,7 +11356,8 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un
|
||||
nullpo_ret(sg=src->group);
|
||||
nullpo_ret(ss=map_id2bl(sg->src_id));
|
||||
|
||||
if( skill_get_type(sg->skill_id) == BF_MAGIC && map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
|
||||
if( (skill_get_type(sg->skill_id) == BF_MAGIC && map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR) ||
|
||||
map_getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) )
|
||||
return 0; //AoE skills are ineffective. [Skotlex]
|
||||
|
||||
if( skill_get_inf2(sg->skill_id)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL) && map_getcell(bl->m, bl->x, bl->y, CELL_CHKBASILICA) )
|
||||
@ -11400,26 +11397,17 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un
|
||||
sc_start4(ss, bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit);
|
||||
break;
|
||||
|
||||
case UNT_PNEUMA:
|
||||
case UNT_CHAOSPANIC:
|
||||
case UNT_MAELSTROM:
|
||||
if (!sce)
|
||||
sc_start4(ss, bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
|
||||
break;
|
||||
case UNT_BLOODYLUST:
|
||||
if (sg->src_id == bl->id)
|
||||
break; //Does not affect the caster.
|
||||
if (!sce) {
|
||||
TBL_PC *sd = BL_CAST(BL_PC, bl); //prevent fullheal exploit
|
||||
if (sd && sd->bloodylust_tick && DIFF_TICK(gettick(), sd->bloodylust_tick) < skill_get_time2(SC_BLOODYLUST, 1))
|
||||
clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv,
|
||||
sc_start4(ss, bl, type, 100, sg->skill_lv, 1, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv)));
|
||||
else {
|
||||
if (sd) sd->bloodylust_tick = gettick();
|
||||
clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv,
|
||||
sc_start4(ss, bl, type, 100, sg->skill_lv, 0, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv)));
|
||||
}
|
||||
}
|
||||
if( !sce && sc_start4(ss, bl,type,100,sg->skill_lv,0,SC__BLOODYLUST,0,sg->limit) )
|
||||
sc_start(ss, bl,SC__BLOODYLUST,100,sg->skill_lv,sg->limit);
|
||||
break;
|
||||
|
||||
case UNT_PNEUMA:
|
||||
case UNT_CHAOSPANIC:
|
||||
if (!sce)
|
||||
sc_start4(ss, bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
|
||||
break;
|
||||
|
||||
case UNT_WARP_WAITING: {
|
||||
@ -12413,15 +12401,10 @@ int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick
|
||||
case SO_WATER_INSIGNIA:
|
||||
case SO_WIND_INSIGNIA:
|
||||
case SO_EARTH_INSIGNIA:
|
||||
case SC_BLOODYLUST:
|
||||
if (sce)
|
||||
status_change_end(bl, type, INVALID_TIMER);
|
||||
break;
|
||||
case SC_BLOODYLUST:
|
||||
if (sce) {
|
||||
status_change_end(bl, type, INVALID_TIMER);
|
||||
status_set_sp(bl, 0, 0); //set sp to 0 when quitting zone
|
||||
}
|
||||
break;
|
||||
case BA_DISSONANCE:
|
||||
case DC_UGLYDANCE: //Used for updating song timers in overlap instances
|
||||
{
|
||||
@ -12908,6 +12891,22 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case AS_CLOAKING:
|
||||
{
|
||||
static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
|
||||
static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
|
||||
|
||||
if( (sd->bl.type == BL_PC && battle_config.pc_cloak_check_type&1)
|
||||
|| (sd->bl.type != BL_PC && battle_config.monster_cloak_check_type&1) ) { //Check for walls.
|
||||
int i;
|
||||
ARR_FIND( 0, 8, i, map_getcell(sd->bl.m, sd->bl.x+dx[i], sd->bl.y+dy[i], CELL_CHKNOPASS) != 0 );
|
||||
if( i == 8 ) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AL_WARP:
|
||||
if(!battle_config.duel_allow_teleport && sd->duel_group) { // duel restriction [LuzZza]
|
||||
char output[128]; sprintf(output, msg_txt(sd,365), skill_get_name(AL_WARP));
|
||||
@ -15002,10 +15001,6 @@ int skill_clear_group (struct block_list *bl, int flag)
|
||||
if( flag&8 )
|
||||
group[count++]= ud->skillunit[i];
|
||||
break;
|
||||
case SC_BLOODYLUST:
|
||||
if (flag & 32)
|
||||
group[count++] = ud->skillunit[i];
|
||||
break;
|
||||
default:
|
||||
if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP)
|
||||
group[count++]= ud->skillunit[i];
|
||||
@ -15036,7 +15031,6 @@ struct skill_unit_group *skill_locate_element_field(struct block_list *bl)
|
||||
case SA_LANDPROTECTOR:
|
||||
case NJ_SUITON:
|
||||
case SO_WARMER:
|
||||
case SC_BLOODYLUST:
|
||||
return ud->skillunit[i];
|
||||
}
|
||||
}
|
||||
@ -15317,6 +15311,34 @@ static int skill_trap_splash (struct block_list *bl, va_list ap)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int skill_maelstrom_suction(struct block_list *bl, va_list ap)
|
||||
{
|
||||
uint16 skill_id, skill_lv;
|
||||
struct skill_unit *unit;
|
||||
|
||||
skill_id = va_arg(ap,int);
|
||||
skill_lv = va_arg(ap,int);
|
||||
unit = (struct skill_unit *)bl;
|
||||
|
||||
if( unit == NULL || unit->group == NULL )
|
||||
return 0;
|
||||
|
||||
if( skill_get_inf2(skill_id)&INF2_TRAP )
|
||||
return 0;
|
||||
|
||||
if( unit->group->skill_id == SC_MAELSTROM ){
|
||||
struct block_list *src;
|
||||
if( (src = map_id2bl(unit->group->src_id)) ){
|
||||
int sp = unit->group->skill_lv * skill_lv;
|
||||
if( src->type == BL_PC )
|
||||
sp += ((TBL_PC*)src)->status.job_level / 5;
|
||||
status_heal(src, 0, sp/2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------*/
|
||||
@ -15405,6 +15427,9 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
|
||||
nullpo_retr(NULL, group->unit); // crash-protection against poor coding
|
||||
nullpo_retr(NULL, unit=&group->unit[idx]);
|
||||
|
||||
if( map_getcell(map_id2bl(group->src_id)->m, x, y, CELL_CHKMAELSTROM) )
|
||||
return unit;
|
||||
|
||||
if(!unit->alive)
|
||||
group->alive_count++;
|
||||
|
||||
|
@ -1865,6 +1865,7 @@ struct s_skill_magicmushroom_db {
|
||||
uint16 skill_id;
|
||||
};
|
||||
extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
|
||||
int skill_maelstrom_suction(struct block_list *bl, va_list ap);
|
||||
/**
|
||||
* Ranger
|
||||
**/
|
||||
|
@ -496,10 +496,10 @@ void initChangeTables(void) {
|
||||
set_sc(MH_PAIN_KILLER , SC_PAIN_KILLER , SI_PAIN_KILLER , SCB_ASPD );
|
||||
|
||||
add_sc(MH_STYLE_CHANGE , SC_STYLE_CHANGE );
|
||||
set_sc(MH_TINDER_BREAKER , SC_TINDER_BREAKER2 , SI_TINDER_BREAKER, SCB_FLEE );
|
||||
set_sc(MH_TINDER_BREAKER , SC_TINDER_BREAKER , SI_TINDER_BREAKER_POSTDELAY, SCB_FLEE );
|
||||
set_sc(MH_CBC , SC_CBC, SI_CBC , SCB_FLEE );
|
||||
set_sc(MH_EQC , SC_EQC, SI_EQC , SCB_DEF2|SCB_BATK|SCB_MAXHP );
|
||||
set_sc(MH_TINDER_BREAKER , SC_TINDER_BREAKER2 , SI_TINDER_BREAKER , SCB_FLEE );
|
||||
set_sc(MH_TINDER_BREAKER , SC_TINDER_BREAKER , SI_TINDER_BREAKER_POSTDELAY , SCB_FLEE );
|
||||
set_sc(MH_CBC , SC_CBC , SI_CBC , SCB_FLEE );
|
||||
set_sc(MH_EQC , SC_EQC , SI_EQC , SCB_DEF2|SCB_BATK|SCB_MAXHP );
|
||||
|
||||
add_sc( MER_CRASH , SC_STUN );
|
||||
set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
|
||||
@ -635,7 +635,7 @@ void initChangeTables(void) {
|
||||
set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
|
||||
set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
|
||||
add_sc( SC_CHAOSPANIC , SC_CONFUSION );
|
||||
set_sc_with_vfx( SC_BLOODYLUST , SC__BLOODYLUST , SI_BERSERK , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN );
|
||||
add_sc( SC_BLOODYLUST , SC_BERSERK );
|
||||
/**
|
||||
* Sura
|
||||
**/
|
||||
@ -1048,7 +1048,6 @@ void initChangeTables(void) {
|
||||
StatusChangeStateTable[SC_BERSERK] |= SCS_NOCHAT;
|
||||
StatusChangeStateTable[SC_SATURDAYNIGHTFEVER] |= SCS_NOCHAT;
|
||||
StatusChangeStateTable[SC_DEEPSLEEP] |= SCS_NOCHAT;
|
||||
StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCHAT;
|
||||
StatusChangeStateTable[SC_NOCHAT] |= SCS_NOCHAT|SCS_NOCHATCOND;
|
||||
|
||||
}
|
||||
@ -1233,8 +1232,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
|
||||
status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
|
||||
if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
|
||||
status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
|
||||
if (sc->data[SC__BLOODYLUST] && status->hp <= 100)
|
||||
status_change_end(target, SC__BLOODYLUST, INVALID_TIMER);
|
||||
}
|
||||
|
||||
switch (target->type) {
|
||||
@ -1367,7 +1364,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
|
||||
}
|
||||
|
||||
if(hp) {
|
||||
if( sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) ) {
|
||||
if( sc && (sc->data[SC_BERSERK]) ) {
|
||||
if( flag&1 )
|
||||
flag &= ~2;
|
||||
else
|
||||
@ -3488,7 +3485,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|
||||
if (
|
||||
(sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
|
||||
|| (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
|
||||
|| sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]
|
||||
|| sc->data[SC_BERSERK]
|
||||
|| sc->data[SC_TRICKDEAD]
|
||||
|| sc->data[SC_BLEEDING]
|
||||
|| sc->data[SC_MAGICMUSHROOM]
|
||||
@ -4910,7 +4907,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
|
||||
if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
|
||||
flee -= flee * 50/100;
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if(sc->data[SC_BERSERK])
|
||||
flee -= flee * 50/100;
|
||||
if(sc->data[SC_BLIND])
|
||||
flee -= flee * 25/100;
|
||||
@ -4957,7 +4954,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
|
||||
if(!sc || !sc->count)
|
||||
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
|
||||
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if(sc->data[SC_BERSERK])
|
||||
return 0;
|
||||
if(sc->data[SC_SKA])
|
||||
return sc->data[SC_SKA]->val3;
|
||||
@ -5037,7 +5034,7 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
|
||||
return (short)cap_value(def2,1,SHRT_MAX);
|
||||
#endif
|
||||
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if(sc->data[SC_BERSERK])
|
||||
return 0;
|
||||
if(sc->data[SC_ETERNALCHAOS])
|
||||
return 0;
|
||||
@ -5095,7 +5092,7 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
|
||||
if(!sc || !sc->count)
|
||||
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
|
||||
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if(sc->data[SC_BERSERK])
|
||||
return 0;
|
||||
if(sc->data[SC_BARRIER])
|
||||
return 100;
|
||||
@ -5145,7 +5142,7 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang
|
||||
#endif
|
||||
|
||||
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if(sc->data[SC_BERSERK])
|
||||
return 0;
|
||||
if(sc->data[SC_SKA])
|
||||
return 90;
|
||||
@ -5290,7 +5287,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
|
||||
val = max( val, 1 * pc_checkskill(sd,TF_MISS) );
|
||||
if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 )
|
||||
val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 );
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if( sc->data[SC_BERSERK] )
|
||||
val = max( val, 25 );
|
||||
if( sc->data[SC_RUN] )
|
||||
val = max( val, 55 );
|
||||
@ -5405,7 +5402,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
|
||||
}
|
||||
}
|
||||
|
||||
if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15)
|
||||
if(sc->data[SC_BERSERK] && skills1 < 15)
|
||||
skills1 = 15;
|
||||
else if(sc->data[SC_MADNESSCANCEL] && skills1 < 15) // needs more info
|
||||
skills1 = 15;
|
||||
@ -5550,7 +5547,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
|
||||
}
|
||||
aspd_rate -= max;
|
||||
|
||||
if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
|
||||
if(sc->data[SC_BERSERK])
|
||||
aspd_rate -= 300;
|
||||
else if(sc->data[SC_MADNESSCANCEL])
|
||||
aspd_rate -= 200;
|
||||
@ -5652,7 +5649,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
|
||||
maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100;
|
||||
if(sc->data[SC_DELUGE])
|
||||
maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
|
||||
if(sc->data[SC_BERSERK])
|
||||
maxhp += maxhp * 2;
|
||||
if(sc->data[SC_MARIONETTE])
|
||||
maxhp -= 1000;
|
||||
@ -6310,7 +6307,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
|
||||
case SC__LAZINESS:
|
||||
case SC__UNLUCKY:
|
||||
case SC__WEAKNESS:
|
||||
case SC__BLOODYLUST:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6690,12 +6686,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
|
||||
//There all like berserk, do not everlap each other
|
||||
case SC__BLOODYLUST:
|
||||
if(!sd) return 0; //should only affect player
|
||||
case SC_BERSERK:
|
||||
if (((type == SC_BERSERK) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST]))
|
||||
|| ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC_BERSERK]))
|
||||
)
|
||||
if(sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST])
|
||||
return 0;
|
||||
break;
|
||||
|
||||
@ -6946,7 +6938,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
}
|
||||
break;
|
||||
case SC_SATURDAYNIGHTFEVER:
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION])
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
@ -7067,8 +7059,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
|
||||
status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
|
||||
break;
|
||||
case SC__BLOODYLUST:
|
||||
case SC_BERSERK:
|
||||
if( val3 == SC__BLOODYLUST )
|
||||
break;
|
||||
if(battle_config.berserk_cancels_buffs) {
|
||||
status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
|
||||
status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
|
||||
@ -7324,7 +7317,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
val4 = sce->val4;
|
||||
break;
|
||||
case SC_LERADSDEW:
|
||||
if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
|
||||
if (sc && sc->data[SC_BERSERK])
|
||||
return 0;
|
||||
case SC_SHAPESHIFT:
|
||||
case SC_PROPERTYWALK:
|
||||
@ -7785,9 +7778,10 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
|
||||
case SC_BERSERK:
|
||||
if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)
|
||||
if( val3 == SC__BLOODYLUST )
|
||||
sc_start(src,bl,(sc_type)val3,100,val1,tick);
|
||||
if (!val3 && !(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4))
|
||||
sc_start4(src,bl, SC_ENDURE, 100,10,0,0,2, tick);
|
||||
case SC__BLOODYLUST:
|
||||
//HP healing is performing after the calc_status call.
|
||||
//Val2 holds HP penalty
|
||||
if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
|
||||
@ -8962,7 +8956,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
case SC_BERSERK:
|
||||
opt_flag = 0;
|
||||
// case SC__BLOODYLUST:
|
||||
sc->opt3 |= OPT3_BERSERK;
|
||||
break;
|
||||
// case ???: // doesn't seem to do anything
|
||||
@ -9101,7 +9094,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
|
||||
|
||||
switch (type) {
|
||||
case SC__BLOODYLUST:
|
||||
case SC_BERSERK:
|
||||
if (!(sce->val2)) { //don't heal if already set
|
||||
status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
|
||||
@ -9580,15 +9572,15 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
|
||||
case SC_BERSERK:
|
||||
case SC_SATURDAYNIGHTFEVER:
|
||||
//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
|
||||
if (status->hp > 100 && sce->val2)
|
||||
if(status->hp > 200 && sc && sc->data[SC__BLOODYLUST]) {
|
||||
status_percent_heal(bl, 100, 0);
|
||||
status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER);
|
||||
} else if (status->hp > 100 && sce->val2) //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
|
||||
status_set_hp(bl, 100, 0);
|
||||
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
|
||||
{
|
||||
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) {
|
||||
sc->data[SC_ENDURE]->val4 = 0;
|
||||
status_change_end(bl, SC_ENDURE, INVALID_TIMER);
|
||||
}
|
||||
case SC__BLOODYLUST:
|
||||
sc_start4(bl, bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
|
||||
if( type == SC_SATURDAYNIGHTFEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds.
|
||||
sc_start(bl, bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
|
||||
@ -9875,7 +9867,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
break;
|
||||
case SC_BERSERK:
|
||||
opt_flag = 0;
|
||||
// case SC__BLOODYLUST:
|
||||
sc->opt3 &= ~OPT3_BERSERK;
|
||||
break;
|
||||
// case ???: // doesn't seem to do anything
|
||||
@ -10257,7 +10248,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SC__BLOODYLUST:
|
||||
case SC_BERSERK:
|
||||
// 5% every 10 seconds [DracoRPG]
|
||||
if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )
|
||||
@ -11015,7 +11005,6 @@ int status_change_clear_buffs (struct block_list* bl, int type)
|
||||
continue;
|
||||
break;
|
||||
//The rest are buffs that can be removed.
|
||||
case SC__BLOODYLUST:
|
||||
case SC_BERSERK:
|
||||
case SC_SATURDAYNIGHTFEVER:
|
||||
if (!(type&1))
|
||||
|
@ -987,8 +987,7 @@ int unit_can_move(struct block_list *bl) {
|
||||
(sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
|
||||
(sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
|
||||
) )
|
||||
|| (sc->data[SC_CLOAKING] && //Need wall at level 1-2
|
||||
sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
|
||||
|| (sc->data[SC_CLOAKING] && sc->data[SC_CLOAKING]->val1 < 3) // Can't move at level less than 3
|
||||
)
|
||||
return 0;
|
||||
|
||||
@ -1475,6 +1474,11 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
}
|
||||
}
|
||||
|
||||
if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map_getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!status_check_skilluse(src, NULL, skill_id, 0))
|
||||
return 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user