From b0c94b71b90c7ed4d3199e0ad019073c3f75f800 Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 4 Mar 2008 18:04:04 +0000 Subject: - Updated firepillar so it cannot be placed on top of others. - Updated the firepillar code so it behaves like the other traps. - Changed the default format for @me and @main to avoid crashes on the newer clients. - Fixed the char-sql server so it returns a valid 'not found' packet when attempting to load a non-existing homunculus. - Fixed jump to use 0,0 for random coordinates rather than -1,-1 - Added missing \n to error reporting in getmonsterinfo - Additional status changes now only get triggered if the attack did damage, not if they get absorbed. - Fixed a logical comparison in unit_free to properly remove pets/homuncs when their intimacy is reduced to 0. - Properly set the opt3 value for Moonlight, Changeundead and Soul Link - Fixed the "no equip" flag of cards not being properly applied when attemting to equip items. - Added a check to avoid invoking pet menu entries when the pet is incuvated. - Fixed the session_data de-association in chrif_auth_delete - Cleaned chrif_auth_ok so that the latest received char info is kept when previous char login data was already in there. - Corrected docs mentioning non-existing flag 'mf_nopvp' git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12293 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char_sql/int_homun.c | 71 +++++++++++++++++++++++++++++++----------------- src/map/atcommand.c | 13 +++++---- src/map/battle.c | 4 +-- src/map/chrif.c | 22 +++++++++------ src/map/pc.c | 13 ++++++--- src/map/pet.c | 2 +- src/map/script.c | 2 +- src/map/skill.c | 24 ++++------------ src/map/status.c | 32 +++++++++++++++------- src/map/unit.c | 4 +-- 10 files changed, 110 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/char_sql/int_homun.c b/src/char_sql/int_homun.c index a838ebf1d..df08484ab 100644 --- a/src/char_sql/int_homun.c +++ b/src/char_sql/int_homun.c @@ -49,6 +49,18 @@ int mapif_info_homunculus(int fd, int account_id, struct s_homunculus *hd) return 0; } +int mapif_noinfo_homunculus(int fd, int account_id) +{ + WFIFOHEAD(fd, sizeof(struct s_homunculus)+9); + WFIFOW(fd,0) = 0x3891; + WFIFOW(fd,2) = sizeof(struct s_homunculus)+9; + WFIFOL(fd,4) = account_id; + WFIFOB(fd,8) = 0; // not found. + memset(WFIFOP(fd,9), 0, sizeof(struct s_homunculus)); + WFIFOSET(fd, sizeof(struct s_homunculus)+9); + return 0; +} + int mapif_homunculus_deleted(int fd, int flag) { WFIFOHEAD(fd, 3); @@ -157,34 +169,43 @@ int mapif_load_homunculus(int fd) Sql_ShowDebug(sql_handle); return 0; } - if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) - { - homun_pt->hom_id = RFIFOL(fd,6); - Sql_GetData(sql_handle, 1, &data, NULL); homun_pt->char_id = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); homun_pt->class_ = atoi(data); - Sql_GetData(sql_handle, 3, &data, &len); memcpy(homun_pt->name, data, min(len, NAME_LENGTH)); - Sql_GetData(sql_handle, 4, &data, NULL); homun_pt->level = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); homun_pt->exp = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); homun_pt->intimacy = (unsigned int)strtoul(data, NULL, 10); - homun_pt->intimacy = cap_value(homun_pt->intimacy, 0, 100000); - Sql_GetData(sql_handle, 7, &data, NULL); homun_pt->hunger = atoi(data); - homun_pt->hunger = cap_value(homun_pt->hunger, 0, 100); - Sql_GetData(sql_handle, 8, &data, NULL); homun_pt->str = atoi(data); - Sql_GetData(sql_handle, 9, &data, NULL); homun_pt->agi = atoi(data); - Sql_GetData(sql_handle, 10, &data, NULL); homun_pt->vit = atoi(data); - Sql_GetData(sql_handle, 11, &data, NULL); homun_pt->int_ = atoi(data); - Sql_GetData(sql_handle, 12, &data, NULL); homun_pt->dex = atoi(data); - Sql_GetData(sql_handle, 13, &data, NULL); homun_pt->luk = atoi(data); - Sql_GetData(sql_handle, 14, &data, NULL); homun_pt->hp = atoi(data); - Sql_GetData(sql_handle, 15, &data, NULL); homun_pt->max_hp = atoi(data); - Sql_GetData(sql_handle, 16, &data, NULL); homun_pt->sp = atoi(data); - Sql_GetData(sql_handle, 17, &data, NULL); homun_pt->max_sp = atoi(data); - Sql_GetData(sql_handle, 18, &data, NULL); homun_pt->skillpts = atoi(data); - Sql_GetData(sql_handle, 19, &data, NULL); homun_pt->rename_flag = atoi(data); - Sql_GetData(sql_handle, 20, &data, NULL); homun_pt->vaporize = atoi(data); + if( !Sql_NumRows(sql_handle) ) + { //No homunculus found. + mapif_noinfo_homunculus(fd, RFIFOL(fd,2)); + Sql_FreeResult(sql_handle); + return 0; + } + if( SQL_SUCCESS != Sql_NextRow(sql_handle) ) + { + Sql_ShowDebug(sql_handle); Sql_FreeResult(sql_handle); + return 0; } + homun_pt->hom_id = RFIFOL(fd,6); + Sql_GetData(sql_handle, 1, &data, NULL); homun_pt->char_id = atoi(data); + Sql_GetData(sql_handle, 2, &data, NULL); homun_pt->class_ = atoi(data); + Sql_GetData(sql_handle, 3, &data, &len); memcpy(homun_pt->name, data, min(len, NAME_LENGTH)); + Sql_GetData(sql_handle, 4, &data, NULL); homun_pt->level = atoi(data); + Sql_GetData(sql_handle, 5, &data, NULL); homun_pt->exp = atoi(data); + Sql_GetData(sql_handle, 6, &data, NULL); homun_pt->intimacy = (unsigned int)strtoul(data, NULL, 10); + homun_pt->intimacy = cap_value(homun_pt->intimacy, 0, 100000); + Sql_GetData(sql_handle, 7, &data, NULL); homun_pt->hunger = atoi(data); + homun_pt->hunger = cap_value(homun_pt->hunger, 0, 100); + Sql_GetData(sql_handle, 8, &data, NULL); homun_pt->str = atoi(data); + Sql_GetData(sql_handle, 9, &data, NULL); homun_pt->agi = atoi(data); + Sql_GetData(sql_handle, 10, &data, NULL); homun_pt->vit = atoi(data); + Sql_GetData(sql_handle, 11, &data, NULL); homun_pt->int_ = atoi(data); + Sql_GetData(sql_handle, 12, &data, NULL); homun_pt->dex = atoi(data); + Sql_GetData(sql_handle, 13, &data, NULL); homun_pt->luk = atoi(data); + Sql_GetData(sql_handle, 14, &data, NULL); homun_pt->hp = atoi(data); + Sql_GetData(sql_handle, 15, &data, NULL); homun_pt->max_hp = atoi(data); + Sql_GetData(sql_handle, 16, &data, NULL); homun_pt->sp = atoi(data); + Sql_GetData(sql_handle, 17, &data, NULL); homun_pt->max_sp = atoi(data); + Sql_GetData(sql_handle, 18, &data, NULL); homun_pt->skillpts = atoi(data); + Sql_GetData(sql_handle, 19, &data, NULL); homun_pt->rename_flag = atoi(data); + Sql_GetData(sql_handle, 20, &data, NULL); homun_pt->vaporize = atoi(data); + Sql_FreeResult(sql_handle); // Load Homunculus Skill if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `skill_homunculus` WHERE `homun_id`=%d", homun_pt->hom_id) ) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 7b1e4c483..dbb9c1aed 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -545,14 +545,17 @@ int atcommand_jump(const int fd, struct map_session_data* sd, const char* comman sscanf(message, "%d %d", &x, &y); - if (x <= 0) //If coordinates are 'wrong', random jump. - x = -1; - if (y <= 0) - y = -1; - if (sd->bl.m >= 0 && map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { + if (map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map. return -1; } + + if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS)) + { //This is to prevent the pc_setpos call from printing an error. + clif_displaymessage(fd, msg_txt(2)); + x = y = 0; //Invalid cell, use random spot. + } + pc_setpos(sd, sd->mapindex, x, y, 3); sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d clif_displaymessage(fd, atcmd_output); diff --git a/src/map/battle.c b/src/map/battle.c index 1f7295578..c8e822a63 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -158,7 +158,7 @@ int battle_delay_damage_sub (int tid, unsigned int tick, int id, int data) { map_freeblock_lock(); status_fix_damage(dat->src, target, dat->damage, dat->delay); - if ((dat->dmg_lv == ATK_DEF || dat->damage > 0) && dat->attack_type) + if (dat->damage > 0 && dat->attack_type) { if (!status_isdead(target)) skill_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick); @@ -179,7 +179,7 @@ int battle_delay_damage (unsigned int tick, struct block_list *src, struct block if (!battle_config.delay_battle_damage) { map_freeblock_lock(); status_fix_damage(src, target, damage, ddelay); - if ((damage > 0 || dmg_lv == ATK_DEF) && attack_type) + if (damage > 0 && attack_type) { if (!status_isdead(target)) skill_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick()); diff --git a/src/map/chrif.c b/src/map/chrif.c index db59e4097..941e17968 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -116,9 +116,9 @@ bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) { struct auth_node *node; if ((node=chrif_auth_check(account_id, char_id, state))) { - if (node->fd && session[node->fd] && node->sd && - session[node->fd]->session_data == node->sd) - session[node->fd]->session_data = NULL; + int fd = node->sd?node->sd->fd:node->fd; + if (session[fd] && session[fd]->session_data == node->sd) + session[fd]->session_data = NULL; if (node->char_dat) aFree(node->char_dat); if (node->sd) aFree(node->sd); ers_free(auth_db_ers, node); @@ -558,7 +558,9 @@ void chrif_authok(int fd) if ((node = chrif_search(account_id))) { //Is the character already awaiting authorization? - if (node->state == ST_LOGIN && node->sd) + if (node->state != ST_LOGIN) + return; //character in logout phase, do not touch that data. + if (node->sd) { sd = node->sd; if(node->char_dat == NULL && @@ -566,16 +568,18 @@ void chrif_authok(int fd) node->char_id == char_id && node->login_id1 == RFIFOL(fd, 8)) { //Auth Ok - if (!pc_authok(sd, RFIFOL(fd, 16), RFIFOL(fd, 12), status)) - chrif_auth_delete(account_id, char_id, ST_LOGIN); + if (pc_authok(sd, RFIFOL(fd, 16), RFIFOL(fd, 12), status)) + return; } else { //Auth Failed pc_authfail(sd); chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already. - chrif_auth_delete(account_id, char_id, ST_LOGIN); } + chrif_auth_delete(account_id, char_id, ST_LOGIN); + return; } - //Otherwise discard the entry received as we already have information. - return; + //When we receive double login info and the client has not connected yet, + //discard the older one and keep the new one. + chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN); } // Awaiting for client to connect. diff --git a/src/map/pc.c b/src/map/pc.c index 489ff18d9..2a9299658 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -555,12 +555,17 @@ int pc_isequip(struct map_session_data *sd,int n) return 0; if(item->sex != 2 && sd->status.sex != item->sex) return 0; - if(map[sd->bl.m].flag.pvp && item->flag.no_equip&1) + if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1))) return 0; - if(map_flag_gvg(sd->bl.m) && item->flag.no_equip&2) + if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2))) return 0; - if(map[sd->bl.m].flag.restricted && item->flag.no_equip&map[sd->bl.m].zone) - return 0; + if(map[sd->bl.m].flag.restricted) + { + int flag =map[sd->bl.m].zone; + if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag)) + return 0; + } + if (sd->sc.count) { if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG] diff --git a/src/map/pet.c b/src/map/pet.c index f8ee3e216..0ccae4701 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -624,7 +624,7 @@ int pet_menu(struct map_session_data *sd,int menunum) return 1; //You lost the pet already. - if(!sd->status.pet_id || sd->pd->pet.intimate <= 0) + if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate) return 1; switch(menunum) { diff --git a/src/map/script.c b/src/map/script.c index 8fc6ad3f5..e0b1db6db 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12152,7 +12152,7 @@ BUILDIN_FUNC(getmonsterinfo) mob_id = script_getnum(st,2); if (!mobdb_checkid(mob_id)) { - ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i", mob_id); + ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i\n", mob_id); if ( !script_getnum(st,3) ) //requested a string script_pushconststr(st,"null"); else diff --git a/src/map/skill.c b/src/map/skill.c index 3ce19042a..3855891a9 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1630,7 +1630,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if (!dmg.amotion) { status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo. - if (dmg.dmg_lv == ATK_DEF || damage > 0) { + if (damage > 0) { if (!status_isdead(bl)) skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick); //Counter status effects [Skotlex] @@ -6824,15 +6824,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns skill_delunit(src); break; - case UNT_FIREPILLAR_ACTIVE: - skill_area_temp[1] = 0; - map_foreachinrange(skill_attack_area,bl, - skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, - BF_MAGIC,ss,&src->bl,sg->skill_id,sg->skill_lv,tick,0,BCT_ENEMY); // area damage [Celest] - sg->interval = -1; //Mark it used up so others can't trigger it for massive splash damage. [Skotlex] - sg->limit=DIFF_TICK(tick,sg->tick) + 1500; - break; - case UNT_SKIDTRAP: { skill_blown(&src->bl,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0); @@ -6874,8 +6865,10 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_SANDMAN: case UNT_FLASHER: case UNT_FREEZINGTRAP: + case UNT_FIREPILLAR_ACTIVE: map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); - clif_changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS); + if (sg->unit_id != UNT_FIREPILLAR_ACTIVE) + clif_changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS); src->range = -1; //Disable range so it does not invoke a for each in area again. sg->limit=DIFF_TICK(tick,sg->tick)+1500; break; @@ -9056,12 +9049,6 @@ int skill_trap_splash (struct block_list *bl, va_list ap) case UNT_FLASHER: skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,tick); break; - case UNT_LANDMINE: - case UNT_BLASTMINE: - case UNT_CLAYMORETRAP: - case UNT_FREEZINGTRAP: - skill_attack(skill_get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0); - break; case UNT_GROUNDDRIFT_WIND: if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1)) sc_start(bl,SC_STUN,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv)); @@ -9083,7 +9070,8 @@ int skill_trap_splash (struct block_list *bl, va_list ap) skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0); break; default: - return 0; + skill_attack(skill_get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0); + break; } return 1; } diff --git a/src/map/status.c b/src/map/status.c index 595bccee1..eae8805e4 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -6026,11 +6026,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val opt_flag = 0; break; //0x100 missing? -// TODO: -// case SC_MOONLIT: -// sc->opt3 |= 0x200; -// opt_flag = 0; -// break; + case SC_DANCING: + if ((val1&0xFFFF) == CG_MOONLIT) + sc->opt3 |= 0x200; + opt_flag = 0; + break; case SC_MARIONETTE: case SC_MARIONETTE2: sc->opt3 |= 0x400; @@ -6056,11 +6056,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val sc->opt3 |= 0x8000; opt_flag = 0; break; -// TODO: -// case SC_BIOLABAURA: -// sc->opt3 |= 0x10000; -// opt_flag = 0; -// break; + case SC_CHANGEUNDEAD: + sc->opt3 |= 0x10000; + opt_flag = 0; + break; //OPTION case SC_HIDING: sc->option |= OPTION_HIDE; @@ -6613,6 +6612,11 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) sc->opt3 &= ~0x80; opt_flag = 0; break; + case SC_DANCING: + if ((sce->val1&0xFFFF) == CG_MOONLIT) + sc->opt3 &= ~0x200; + opt_flag = 0; + break; case SC_MARIONETTE: case SC_MARIONETTE2: sc->opt3 &= ~0x400; @@ -6630,6 +6634,14 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) sc->opt3 &= ~0x2000; opt_flag = 0; break; + case SC_SPIRIT: + sc->opt3 &= ~0x8000; + opt_flag = 0; + break; + case SC_CHANGEUNDEAD: + sc->opt3 &= ~0x10000; + opt_flag = 0; + break; default: opt_flag = 0; } diff --git a/src/map/unit.c b/src/map/unit.c index 66f362085..164e84327 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1706,7 +1706,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) case BL_PET: { struct pet_data *pd = (struct pet_data*)bl; - if( pd->pet.intimate <= 0 && !(pd->msd && pd->msd->state.active) ) + if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) ) { //If logging out, this is deleted on unit_free clif_clearunit_area(bl,clrtype); map_delblock(bl); @@ -1721,7 +1721,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) { struct homun_data *hd = (struct homun_data *) bl; ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick. - if(!hd->homunculus.intimacy && !(hd->master && hd->master->state.active) ) + if(!hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) ) { //If logging out, this is deleted on unit_free clif_emotion(bl, 28) ; //sob clif_clearunit_area(bl,clrtype); -- cgit v1.2.3-60-g2f50