summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c2
-rw-r--r--src/map/battle.c17
-rw-r--r--src/map/chrif.c37
-rw-r--r--src/map/chrif.h2
-rw-r--r--src/map/script.c9
-rw-r--r--src/map/skill.c1
6 files changed, 46 insertions, 22 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 560848c5b..b9b4704bc 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6431,7 +6431,7 @@ ACMD(changesex)
// to avoid any problem with equipment and invalid sex, equipment is unequipped.
for( i=0; i<EQI_MAX; i++ )
if( sd->equip_index[i] >= 0 ) pc->unequipitem(sd, sd->equip_index[i], 3);
- chrif->changesex(sd);
+ chrif->changesex(sd, true);
return true;
}
diff --git a/src/map/battle.c b/src/map/battle.c
index 539d3516e..31b04ad44 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -427,7 +427,7 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
else
damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag & 8);
- if ( flag & 2 && sd->bonus.arrow_atk )
+ if ( flag & 2 && sd->bonus.arrow_atk && skill_id != GN_CARTCANNON )
damage += sd->bonus.arrow_atk;
if ( sd->battle_status.equip_atk != 0 )
@@ -886,8 +886,6 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == NC_ARMSCANNON )
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- if( skill_id == GN_CARTCANNON )
- damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
}
@@ -2541,7 +2539,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case GN_CARTCANNON:
- skillratio = 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40) + 60 * skill_lv;
+ skillratio += -100 + (int)(50.0f * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40.0f) + 60.0f * skill_lv);
break;
case GN_SPORE_EXPLOSION:
skillratio = 100 * skill_lv + (200 + st->int_) * status->get_lv(src) / 100;
@@ -4352,6 +4350,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case PA_SACRIFICE:
flag.distinct = 1;
break;
+ case GN_CARTCANNON:
case PA_SHIELDCHAIN:
case GS_MAGICALBULLET:
case NJ_SYURIKEN:
@@ -4928,6 +4927,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
wd.damage = max(wd.damage, 1);
}
break;
+ case GN_CARTCANNON:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
+ ATK_ADD(sd ? sd->bonus.arrow_atk : 0);
+ wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
+ if ( sd && s_ele != sd->bonus.arrow_ele )
+ s_ele = sd->bonus.arrow_ele;
+ break;
case NJ_TATAMIGAESHI:
ATK_RATE(200);
/* Fall through */
@@ -5208,7 +5215,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
//Div fix.
damage_div_fix(wd.damage, wd.div_);
if ( skill_id > 0 && (skill->get_ele(skill_id, skill_lv) == ELE_NEUTRAL || flag.distinct) ) { // re-evaluate forced neutral skills
- wd.damage = battle->attr_fix(src, target, wd.damage, s_ele_, tstatus->def_ele, tstatus->ele_lv);
+ wd.damage = battle->attr_fix(src, target, wd.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
if ( flag.lh )
wd.damage2 = battle->attr_fix(src, target, wd.damage2, s_ele_, tstatus->def_ele, tstatus->ele_lv);
}
diff --git a/src/map/chrif.c b/src/map/chrif.c
index da946f050..6ac7d5695 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -62,7 +62,7 @@ struct chrif_interface chrif_s;
//2b0a: Incoming/Outgoing, socket_datasync()
//2b0b: Outgoing, update charserv skillid2idx
//2b0c: Outgoing, chrif_changeemail -> 'change mail address ...'
-//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY'
+//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY' (or char)
//2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
//2b0f: Incoming, chrif_char_ask_name_answer -> 'answer of the 2b0e'
//2b10: Outgoing, chrif_updatefamelist -> 'Update the fame ranking lists and send them'
@@ -744,10 +744,18 @@ bool chrif_changeemail(int id, const char *actual_email, const char *new_email)
}
/*==========================================
- * S 2b0e <accid>.l <name>.24B <type>.w { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
+ * S 2b0e <accid>.l <name>.24B <type>.w { <additional fields>.12B }
+ * { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
* Send an account modification request to the login server (via char server).
- * type of operation:
- * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6: charban
+ * type of operation {additional fields}:
+ * 1: block { n/a }
+ * 2: ban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
+ * 3: unblock { n/a }
+ * 4: unban { n/a }
+ * 5: changesex { n/a } -- use chrif_changesex
+ * 6: charban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
+ * 7: charunban { n/a }
+ * 8: changecharsex { <sex>.b } -- use chrif_changesex
*------------------------------------------*/
bool chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second)
{
@@ -772,14 +780,24 @@ bool chrif_char_ask_name(int acc, const char* character_name, unsigned short ope
return true;
}
-bool chrif_changesex(struct map_session_data *sd) {
+/**
+ * Requests a sex change (either per character or per account).
+ *
+ * @param sd The character's data.
+ * @param change_account Whether to change the per-account sex.
+ * @retval true.
+ */
+bool chrif_changesex(struct map_session_data *sd, bool change_account)
+{
chrif_check(false);
WFIFOHEAD(chrif->fd,44);
WFIFOW(chrif->fd,0) = 0x2b0e;
WFIFOL(chrif->fd,2) = sd->status.account_id;
safestrncpy((char*)WFIFOP(chrif->fd,6), sd->status.name, NAME_LENGTH);
- WFIFOW(chrif->fd,30) = 5;
+ WFIFOW(chrif->fd,30) = change_account ? 5 : 8;
+ if (!change_account)
+ WFIFOB(chrif->fd,32) = sd->status.sex == SEX_MALE ? SEX_FEMALE : SEX_MALE;
WFIFOSET(chrif->fd,44);
clif->message(sd->fd, msg_sd(sd,408)); //"Disconnecting to perform change-sex request..."
@@ -795,7 +813,7 @@ bool chrif_changesex(struct map_session_data *sd) {
* R 2b0f <accid>.l <name>.24B <type>.w <answer>.w
* Processing a reply to chrif->char_ask_name() (request to modify an account).
* type of operation:
- * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban
+ * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban, 8: changecharsex
* type of answer:
* 0: login-server request done
* 1: player not found
@@ -847,8 +865,11 @@ void chrif_changedsex(int fd) {
ShowNotice("chrif_changedsex %d.\n", acc);
// Path to activate this response:
- // Map(start) (0x2b0e) -> Char(0x2727) -> Login
+ // Map(start) (0x2b0e type 5) -> Char(0x2727) -> Login
// Login(0x2723) [ALL] -> Char (0x2b0d)[ALL] -> Map (HERE)
+ // OR
+ // Map(start) (0x2b03 type 8) -> Char
+ // Char(0x2b0d)[ALL] -> Map (HERE)
// Char will usually be "logged in" despite being forced to log-out in the beginning
// of this process, but there's no need to perform map-server specific response
// as everything should been changed through char-server [Panikon]
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 271fc076d..c90d00ef5 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -103,7 +103,7 @@ struct chrif_interface {
bool (*char_reset_offline) (void);
bool (*send_users_tochar) (void);
bool (*char_online) (struct map_session_data *sd);
- bool (*changesex) (struct map_session_data *sd);
+ bool (*changesex) (struct map_session_data *sd, bool change_account);
//int (*chardisconnect) (struct map_session_data *sd); // FIXME: Commented out in clif.c, function does not exist
bool (*divorce) (int partner_id1, int partner_id2);
diff --git a/src/map/script.c b/src/map/script.c
index 265c4a549..51bb344fe 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -11254,7 +11254,7 @@ BUILDIN(changesex)
TBL_PC *sd = prepareChangeSex(st);
if (sd == NULL)
return false;
- chrif->changesex(sd);
+ chrif->changesex(sd, true);
return true;
}
@@ -11266,12 +11266,7 @@ 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);
+ chrif->changesex(sd, false);
return true;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 4c8ecb40f..a9737f129 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -7649,6 +7649,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
map->freeblock_unlock(); // Don't consume item requirements
return 0;
}
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
}
break;