diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 22 | ||||
-rw-r--r-- | src/common/socket.c | 11 | ||||
-rw-r--r-- | src/config/const.h | 7 | ||||
-rw-r--r-- | src/map/battle.c | 42 | ||||
-rw-r--r-- | src/map/script.c | 45 | ||||
-rw-r--r-- | src/map/skill.c | 62 | ||||
-rw-r--r-- | src/map/status.c | 2 |
7 files changed, 130 insertions, 61 deletions
diff --git a/src/char/char.c b/src/char/char.c index b18beed60..698832bfb 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -453,16 +453,31 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) || (p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->robe != cp->robe) || (p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) || - (p->uniqueitem_counter != cp->uniqueitem_counter ) + (p->uniqueitem_counter != cp->uniqueitem_counter ) || (p->sex != cp->sex) ) { //Save status unsigned int opt = 0; + char sex; if( p->allow_party ) opt |= OPT_ALLOW_PARTY; if( p->show_equip ) opt |= OPT_SHOW_EQUIP; + switch (p->sex) + { + case 0: + sex = 'F'; + break; + case 1: + sex = 'M'; + break; + case 99: + default: + sex = 'U'; + break; + } + if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `base_level`='%d', `job_level`='%d'," "`base_exp`='%u', `job_exp`='%u', `zeny`='%d'," "`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d'," @@ -470,7 +485,8 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) "`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d'," "`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d'," "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d'," - "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'" + "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'," + " sex = '%c'" " WHERE `account_id`='%d' AND `char_id` = '%d'", char_db, p->base_level, p->job_level, p->base_exp, p->job_exp, p->zeny, @@ -481,7 +497,7 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y, mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename, (unsigned long)p->delete_date, // FIXME: platform-dependent size - p->robe,p->slotchange,opt,p->font,p->uniqueitem_counter, + p->robe,p->slotchange,opt,p->font,p->uniqueitem_counter, sex, p->account_id, p->char_id) ) { Sql_ShowDebug(inter->sql_handle); diff --git a/src/common/socket.c b/src/common/socket.c index f307dc4a9..09521c312 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -29,8 +29,12 @@ # include <errno.h> # include <net/if.h> # include <netdb.h> +#if defined __linux__ || defined __linux +# include <linux/tcp.h> +#else # include <netinet/in.h> # include <netinet/tcp.h> +#endif # include <sys/ioctl.h> # include <sys/socket.h> # include <sys/time.h> @@ -333,6 +337,13 @@ void setsocketopts(int fd, struct hSockOpt *opt) { lopt.l_linger = 0; // Do not care if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lopt, sizeof(lopt)) ) ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd); + +#ifdef TCP_THIN_LINEAR_TIMEOUTS + setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof yes); +#endif +#ifdef TCP_THIN_DUPACK + setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof yes); +#endif } /*====================================== diff --git a/src/config/const.h b/src/config/const.h index 7b5ed5506..e10d2ad2a 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -73,17 +73,16 @@ /* Renewal's dmg level modifier, used as a macro for a easy way to turn off. */ #ifdef RENEWAL_LVDMG #define RE_LVL_DMOD(val) do { \ - if( status->get_lv(src) > 100 && (val) > 0 ) \ + if( (val) > 0 ) \ skillratio = skillratio * status->get_lv(src) / (val); \ } while(0) #define RE_LVL_MDMOD(val) do { \ - if( status->get_lv(src) > 100 && (val) > 0) \ + if ( (val) > 0 ) \ md.damage = md.damage * status->get_lv(src) / (val); \ } while(0) /* ranger traps special */ #define RE_LVL_TMDMOD() do { \ - if( status->get_lv(src) > 100 ) \ - md.damage = md.damage * 150 / 100 + md.damage * status->get_lv(src) / 100; \ + md.damage = md.damage * 150 / 100 + md.damage * status->get_lv(src) / 100; \ } while(0) #else #define RE_LVL_DMOD(val) diff --git a/src/map/battle.c b/src/map/battle.c index bbb03eb1f..77edb31f1 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2078,11 +2078,6 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block case NJ_KIRIKAGE: skillratio += 100 * (skill_lv-1); break; -#ifdef RENEWAL - case NJ_KUNAI: - skillratio += 50 + 150 * skill_lv; - break; -#endif case KN_CHARGEATK: { int k = (flag-1)/3; //+100% every 3 cells of distance @@ -2521,6 +2516,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block RE_LVL_DMOD(120); if( tsc && tsc->data[SC_KO_JYUMONJIKIRI] ) skillratio += status->get_lv(src) * skill_lv; + break; case KO_HUUMARANKA: skillratio += -100 + 150 * skill_lv + status_get_agi(src) + status_get_dex(src) + 100 * (sd ? pc->checkskill(sd, NJ_HUUMA) : 0); break; @@ -2528,11 +2524,6 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += -100 + 100 * skill_lv; RE_LVL_DMOD(100); break; - case KO_BAKURETSU: - skillratio += -100 + (50 + status_get_dex(src) / 4) * skill_lv * (sd?pc->checkskill(sd,NJ_TOBIDOUGU):10) * 4 / 100; - RE_LVL_DMOD(120); - skillratio += 10 * (sd ? sd->status.job_level : 0); - break; case MH_NEEDLE_OF_PARALYZE: skillratio += 600 + 100 * skill_lv; break; @@ -3933,14 +3924,16 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * break; case KO_HAPPOKUNAI: { - struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag); + struct Damage wd = battle->calc_weapon_attack(src, target, 0, 1, mflag); #ifdef RENEWAL short totaldef = status->get_total_def(target); #else short totaldef = tstatus->def2 + (short)status->get_def(target); #endif - md.damage = 3 * wd.damage * (5 + skill_lv) / 5; + if ( sd ) wd.damage += sd->bonus.arrow_atk; + md.damage = (int)(3 * (1 + wd.damage) * (5 + skill_lv) / 5.0f); md.damage -= totaldef; + } break; } @@ -4242,10 +4235,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 ); break; #ifdef RENEWAL + case NJ_KUNAI: case HW_MAGICCRASHER: + case NJ_SYURIKEN: + case GS_MAGICALBULLET: +#endif + case KO_BAKURETSU: flag.tdef = 1; break; -#endif } } else //Range for normal attacks. wd.flag |= flag.arrow?BF_LONG:BF_SHORT; @@ -4597,7 +4594,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list break; case NJ_SYURIKEN: // [malufett] GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) ); - wd.damage += battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon) - status->get_total_def(target); + wd.damage += battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon); break; case MO_EXTREMITYFIST: // [malufett] { @@ -4736,13 +4733,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER); } - - #ifdef RENEWAL - if( sd && skill_id == NJ_KUNAI ){ - flag.tdef = 1; - ATK_ADD( sd->bonus.arrow_atk ); - } - #endif switch(skill_id){ case SR_GATEOFHELL: if (wd.dmg_lv != ATK_FLEE) @@ -4776,6 +4766,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon); } #endif + + case KO_BAKURETSU: + { + GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0)); + skillratio = skill_lv * (50 + status_get_dex(src) / 4); + skillratio = (int)(skillratio * (sd ? pc->checkskill(sd, NJ_TOBIDOUGU) : 10) * 40.f / 100.0f * status->get_lv(src) / 120); + ATK_RATE(skillratio + 10 * (sd ? sd->status.job_level : 0)); + } + break; default: ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag)); } @@ -4805,7 +4804,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_ADD( status->get_matk(src, 2) ); #else ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage ); - flag.tdef = 1; #endif #ifndef RENEWAL case NJ_SYURIKEN: diff --git a/src/map/script.c b/src/map/script.c index c7b1ae849..031dfc21b 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10639,27 +10639,51 @@ BUILDIN(changebase) { return true; } +static TBL_PC *prepareChangeSex(struct script_state* st) +{ + int i; + TBL_PC *sd = script->rid2sd(st); + + if (sd == NULL) + return NULL; + + pc->resetskill(sd, 4); + // to avoid any problem with equipment and invalid sex, equipment is unequiped. + for (i=0; i<EQI_MAX; i++) + if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], 3); + return sd; +} + /*========================================== * Unequip all item and request for a changesex to char-serv *------------------------------------------*/ BUILDIN(changesex) { - int i; - TBL_PC *sd = NULL; - sd = script->rid2sd(st); - - if( sd == NULL ) + TBL_PC *sd = prepareChangeSex(st); + if (sd == NULL) return false; - - pc->resetskill(sd,4); - // to avoid any problem with equipment and invalid sex, equipment is unequiped. - for( i=0; i<EQI_MAX; i++ ) - if( sd->equip_index[i] >= 0 ) pc->unequipitem(sd, sd->equip_index[i], 3); chrif->changesex(sd); return true; } /*========================================== + * Unequip all items and change character sex [4144] + *------------------------------------------*/ +BUILDIN(changecharsex) +{ + TBL_PC *sd = prepareChangeSex(st); + if (sd == NULL) + return false; + if (sd->status.sex == 99) + sd->status.sex = 0; + sd->status.sex = sd->status.sex ? 0 : 1; + chrif->save(sd, 0); + if (sd->fd) + clif->authfail_fd(sd->fd, 15); + return true; +} + +/*========================================== * Works like 'announce' but outputs in the common chat window *------------------------------------------*/ BUILDIN(globalmes) { @@ -19302,6 +19326,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(skillpointcount,""), BUILDIN_DEF(changebase,"i?"), BUILDIN_DEF(changesex,""), + BUILDIN_DEF(changecharsex,""), // [4144] BUILDIN_DEF(waitingroom,"si?????"), BUILDIN_DEF(delwaitingroom,"?"), BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"), diff --git a/src/map/skill.c b/src/map/skill.c index b80779e92..5eb319c02 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3574,7 +3574,6 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case WM_SEVERE_RAINSTORM_MELEE: case WM_GREAT_ECHO: case GN_SLINGITEM_RANGEMELEEATK: - case KO_JYUMONJIKIRI: case KO_SETSUDAN: case GC_DARKCROW: case LG_OVERBRAND_BRANDISH: @@ -4216,27 +4215,27 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 } break; + case KO_JYUMONJIKIRI: case GC_DARKILLUSION: { short x, y; - short dir = map->calc_dir(src,bl->x,bl->y); + short dir = map->calc_dir(bl, src->x, src->y); - if( dir > 0 && dir < 4) x = 2; - else if( dir > 4 ) x = -2; - else x = 0; - if( dir > 2 && dir < 6 ) y = 2; - else if( dir == 7 || dir < 2 ) y = -2; - else y = 0; + if ( dir < 4 ) { + x = bl->x + 2 * (dir > 0) - 3 * (dir > 0); + y = bl->y + 1 - (dir / 2) - (dir > 2); + } else { + x = bl->x + 2 * (dir > 4) - 1 * (dir > 4); + y = bl->y + (dir / 6) - 1 + (dir > 6); + } - if( unit->movepos(src, bl->x+x, bl->y+y, 1, 1) ) - { - clif->slide(src,bl->x+x,bl->y+y); + if ( unit->movepos(src, x, y, 1, 1) ) { + clif->slide(src, x, y); clif->fixpos(src); // the official server send these two packets. - skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); - if( rnd()%100 < 4 * skill_lv ) - skill->castend_damage_id(src,bl,GC_CROSSIMPACT,skill_lv,tick,flag); + skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); + if ( rnd() % 100 < 4 * skill_lv && skill_id == GC_DARKILLUSION ) + skill->castend_damage_id(src, bl, GC_CROSSIMPACT, skill_lv, tick, flag); } - } break; case GC_WEAPONCRUSH: @@ -6041,7 +6040,6 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case MO_ABSORBSPIRITS: { int sp = 0; - int i; if ( dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (sd->duel_group && sd->duel_group == dstsd->duel_group)) && ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION) @@ -6055,7 +6053,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin mob->target(dstmd,src,0); } if ( dstsd ) { - for (i = SPIRITS_TYPE_CHARM_WATER; i < SPIRITS_TYPE_SPHERE; i++) + int i; + for ( i = SPIRITS_TYPE_CHARM_WATER; i < SPIRITS_TYPE_SPHERE; i++ ) pc->del_charm(dstsd, dstsd->spiritcharm[i], i); } if (sp) status->heal(src, 0, sp, 3); @@ -11067,7 +11066,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ break; case BA_ASSASSINCROSS: if(sd) - val1 = (pc->checkskill(sd,BA_MUSICALLESSON) + 1) / 2; + val1 = pc->checkskill(sd,BA_MUSICALLESSON) / 2; #ifdef RENEWAL // This formula was taken from a RE calculator // and the changes published on irowiki @@ -11908,19 +11907,38 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 int heal; #ifdef RENEWAL struct mob_data *md = BL_CAST(BL_MOB, bl); - if( md && md->class_ == MOBID_EMPERIUM ) + if (md && md->class_ == MOBID_EMPERIUM) break; #endif - if( (sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) + if ((sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) || (!(battle_config.song_timer_reset) && tsc && tsc->data[type] && tsc->data[type]->val4 == 1)) break; + heal = skill->calc_heal(ss,bl,sg->skill_id, sg->skill_lv, true); if( tsc->data[SC_AKAITSUKI] && heal ) heal = ~heal + 1; clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1); status->heal(bl, heal, 0, 0); + + if (!battle_config.song_timer_reset) + sc_start4(ss, bl, type, 100, sg->skill_lv, sg->val1, sg->val2, 0, sg->limit); } break; + case UNT_POEMBRAGI: + case UNT_WHISTLE: + case UNT_ASSASSINCROSS: + case UNT_HUMMING: + case UNT_DONTFORGETME: + case UNT_FORTUNEKISS: + case UNT_SERVICEFORYOU: + if (battle_config.song_timer_reset + || (!(battle_config.song_timer_reset) && tsc && tsc->data[type] && tsc->data[type]->val4 == 1) + || (sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) + ) + break; + + sc_start4(ss, bl, type, 100, sg->skill_lv, sg->val1, sg->val2, 0, sg->limit); + break; case UNT_TATAMIGAESHI: case UNT_DEMONSTRATION: skill->attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); @@ -12439,7 +12457,9 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) { case DC_DONTFORGETME: case DC_FORTUNEKISS: case DC_SERVICEFORYOU: - if ((battle_config.song_timer_reset && sce) || (!battle_config.song_timer_reset && sce && sce->val4 != 1)) { + if ((battle_config.song_timer_reset && sce) // athena style + || (!battle_config.song_timer_reset && sce && sce->val4 != 1) + ) { timer->delete(sce->timer, status->change_timer); //NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas... //not possible on our current implementation. diff --git a/src/map/status.c b/src/map/status.c index 23deca6fa..92c4ad3e0 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -12180,7 +12180,7 @@ int status_readdb(void) sv->readdb(map->db_path, "pre-re/job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, status->readdb_job1); #endif sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2); - sv->readdb(map->db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->atkmods), status->readdb_sizefix); + sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->atkmods), status->readdb_sizefix); sv->readdb(map->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(status->refine_info), status->readdb_refine); sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig); |