summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-04-20 23:24:20 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-04-20 23:24:20 +0000
commit8cd804f247a2d36ff8dc69d09a1004f5ec84197a (patch)
tree88c4f726d6a9fea3d3a13032db4bb1b850a2ddee /src/map
parenta09e5436e06f844688f708c23975d3ce7e4b3965 (diff)
downloadhercules-8cd804f247a2d36ff8dc69d09a1004f5ec84197a.tar.gz
hercules-8cd804f247a2d36ff8dc69d09a1004f5ec84197a.tar.bz2
hercules-8cd804f247a2d36ff8dc69d09a1004f5ec84197a.tar.xz
hercules-8cd804f247a2d36ff8dc69d09a1004f5ec84197a.zip
- Added two columns to item_db: equip_script and unequip_script are scripts that are executed once when the corresponding item is equipped or unequipped respectively.
- Removed bonuses bDamageWhenUnequip, bLoseSPWhenUnequip - Updated sql-files/item_db.sql with latest. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6204 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/itemdb.c116
-rw-r--r--src/map/itemdb.h5
-rw-r--r--src/map/map.h5
-rw-r--r--src/map/pc.c129
-rw-r--r--src/map/status.c2
5 files changed, 156 insertions, 101 deletions
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index cfb354383..5f5c21c16 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -854,13 +854,30 @@ static int itemdb_read_sqldb(void)
if (sql_res) {
// Parse each row in the query result into sql_row
while ((sql_row = mysql_fetch_row(sql_res)))
- {
- /* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+
- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
- +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+
- | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script |
- +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ */
-
+ { /*Table structure is:
+ 00 id
+ 01 name_english
+ 02 name_japanese
+ 03 type
+ 04 price_buy
+ 05 price_sell
+ 06 weight
+ 07 attack
+ 08 defence
+ 09 range
+ 10 slots
+ 11 equip_jobs
+ 12 equip_upper
+ 13 equip_genders
+ 14 equip_locations
+ 15 weapon_level
+ 16 equip_level
+ 17 refineable
+ 18 view
+ 19 script
+ 20 equip_script
+ 21 unequip_script
+ */
nameid = atoi(sql_row[0]);
// If the identifier is not within the valid range, process the next row
@@ -937,7 +954,29 @@ static int itemdb_read_sqldb(void)
id->script = parse_script((unsigned char *) script, 0);
}
} else id->script = NULL;
-
+
+ if (id->equip_script)
+ aFree(id->equip_script);
+ if (sql_row[20] != NULL) {
+ if (sql_row[20][0] == '{')
+ id->equip_script = parse_script((unsigned char *) sql_row[20], 0);
+ else {
+ sprintf(script, "{%s}", sql_row[20]);
+ id->equip_script = parse_script((unsigned char *) script, 0);
+ }
+ } else id->equip_script = NULL;
+
+ if (id->unequip_script)
+ aFree(id->unequip_script);
+ if (sql_row[21] != NULL) {
+ if (sql_row[21][0] == '{')
+ id->unequip_script = parse_script((unsigned char *) sql_row[21], 0);
+ else {
+ sprintf(script, "{%s}", sql_row[21]);
+ id->unequip_script = parse_script((unsigned char *) script, 0);
+ }
+ } else id->unequip_script = NULL;
+
// ----------
id->flag.available = 1;
@@ -1077,9 +1116,54 @@ static int itemdb_readdb(void)
aFree(id->script);
id->script=NULL;
}
+ if (id->equip_script) {
+ aFree(id->equip_script);
+ id->equip_script=NULL;
+ }
+ if (id->unequip_script) {
+ aFree(id->unequip_script);
+ id->unequip_script=NULL;
+ }
+
if((p=strchr(np,'{'))==NULL)
continue;
- id->script = parse_script((unsigned char *) p,lines);
+
+ str[19] = p; //Script
+ np = strchr(p,'}');
+
+ while (np && np[1] && np[1] != ',')
+ np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
+ if (!np || !np[1]) {
+ //Couldn't find the end of the script field.
+ id->script = parse_script((unsigned char *) str[19],lines);
+ continue;
+ }
+ np[1] = '\0'; //Set end of script
+ id->script = parse_script((unsigned char *) str[19],lines);
+ np+=2; //Skip to next field
+
+ if(!np || (p=strchr(np,'{'))==NULL)
+ continue;
+
+ str[20] = p; //Equip Script
+ np = strchr(p,'}');
+
+ while (np && np[1] && np[1] != ',')
+ np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
+ if (!np || !np[1]) {
+ //Couldn't find the end of the script field.
+ id->equip_script = parse_script((unsigned char *) str[20],lines);
+ continue;
+ }
+
+ np[1] = '\0'; //Set end of script
+ id->equip_script = parse_script((unsigned char *) str[20],lines);
+ np+=2; //Skip comma, to next field
+
+ if(!np || (p=strchr(np,'{'))==NULL)
+ continue;
+ //Unequip script, last column.
+ id->unequip_script = parse_script((unsigned char *) p,lines);
}
fclose(fp);
if (ln > 0) {
@@ -1133,6 +1217,16 @@ static int itemdb_final_sub (DBKey key,void *data,va_list ap)
aFree(id->script);
id->script = NULL;
}
+ if (id->equip_script)
+ {
+ aFree(id->equip_script);
+ id->equip_script = NULL;
+ }
+ if (id->unequip_script)
+ {
+ aFree(id->unequip_script);
+ id->unequip_script = NULL;
+ }
// Whether to clear the item data (exception: do not clear the dummy item data
if (flag && id != dummy_item)
aFree(id);
@@ -1153,6 +1247,10 @@ void do_final_itemdb(void)
if (dummy_item) {
if (dummy_item->script)
aFree(dummy_item->script);
+ if (dummy_item->equip_script)
+ aFree(dummy_item->equip_script);
+ if (dummy_item->unequip_script)
+ aFree(dummy_item->unequip_script);
aFree(dummy_item);
dummy_item = NULL;
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index f65b4b943..88741b3b6 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -34,7 +34,10 @@ struct item_data {
// some script commands should be revised as well...
unsigned int class_base[3]; //Specifies if the base can wear this item (split in 3 indexes per type: 1-1, 2-1, 2-2)
unsigned class_upper : 3; //Specifies if the upper-type can equip it (1: normal, 2: upper, 3: baby)
- unsigned char *script; // 攻撃,防御の属性設定もこの中で可能かな?
+ unsigned char *script; //Default script for everything.
+ unsigned char *equip_script; //Script executed once when equipping.
+ unsigned char *unequip_script;//Script executed once when unequipping.
+
struct {
unsigned available : 1;
unsigned value_notdc : 1;
diff --git a/src/map/map.h b/src/map/map.h
index 1c6c8214b..0a7ee5f90 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -603,8 +603,6 @@ struct map_session_data {
int addeff3[SC_COMMON_MAX-SC_COMMON_MIN+1];
short addeff3_type[SC_COMMON_MAX-SC_COMMON_MIN+1];
short sp_gain_race[12];
- short unequip_losehp[11];
- short unequip_losesp[11];
// zeroed arrays end here.
// zeroed structures start here
struct s_autospell{
@@ -1116,11 +1114,12 @@ enum {
SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017
SP_SKILL_ATK, SP_UNSTRIPABLE, SP_ADD_DAMAGE_BY_CLASS, // 2018-2020
SP_SP_GAIN_VALUE, SP_IGNORE_DEF_MOB, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025
- SP_SUBSIZE, SP_DAMAGE_WHEN_UNEQUIP, SP_ADD_ITEM_HEAL_RATE, SP_LOSESP_WHEN_UNEQUIP, SP_EXP_ADDRACE, // 2026-2030
+ SP_SUBSIZE, SP_FREE, SP_ADD_ITEM_HEAL_RATE, SP_FREE2, SP_EXP_ADDRACE, // 2026-2030
SP_SP_GAIN_RACE, SP_SUBRACE2, SP_ADDEFF_WHENHIT_SHORT, // 2031-2033
SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037
SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE //2041
+ //Before you add more here, notice that 2027&2029 are available.
};
enum {
diff --git a/src/map/pc.c b/src/map/pc.c
index b9b532ea1..c7cf8b24f 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1184,7 +1184,6 @@ static int pc_bonus_item_drop(struct s_add_drop *drop, short *count, short id, s
*/
int pc_bonus(struct map_session_data *sd,int type,int val)
{
- int i;
nullpo_retr(0, sd);
switch(type){
@@ -1642,30 +1641,6 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
if(!sd->state.lr_flag)
sd->hp_gain_value += val;
break;
- case SP_DAMAGE_WHEN_UNEQUIP:
- if(!sd->state.lr_flag) {
- for (i=0; i<11; i++) {
- //I think this one is bugged, notice how it uses the item_db info rather
- // than inventory equipped position index [Skotlex]
-// if (sd->inventory_data[current_equip_item_index]->equip & equip_pos[i]) {
- if(sd->status.inventory[current_equip_item_index].equip & equip_pos[i]) {
- sd->unequip_losehp[i] += val;
- break;
- }
- }
- }
- break;
- case SP_LOSESP_WHEN_UNEQUIP:
- if(!sd->state.lr_flag) {
- for (i=0; i<11; i++) {
-// if (sd->inventory_data[current_equip_item_index]->equip & equip_pos[i]) {
- if(sd->status.inventory[current_equip_item_index].equip & equip_pos[i]) {
- sd->unequip_losesp[i] += val;
- break;
- }
- }
- }
- break;
default:
if(battle_config.error_log)
ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
@@ -6231,7 +6206,10 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
sd->status.inventory[arrow].equip=32768;
}
status_calc_pc(sd,0);
-
+ //OnEquip script [Skotlex]
+ if (sd->inventory_data[n] && sd->inventory_data[n]->equip_script)
+ run_script(sd->inventory_data[n]->equip_script,0,sd->bl.id,0);
+
if(sd->sc.count) {
if (sd->sc.data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
@@ -6250,7 +6228,6 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
*/
int pc_unequipitem(struct map_session_data *sd,int n,int flag)
{
- short hp = 0, sp = 0;
nullpo_retr(0, sd);
// -- moonsoul (if player is berserk then cannot unequip)
@@ -6262,73 +6239,53 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
if(battle_config.battle_log)
ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip);
- if(sd->status.inventory[n].equip){
- int i;
- for(i=0;i<11;i++) {
- if(sd->status.inventory[n].equip & equip_pos[i]) {
- sd->equip_index[i] = -1;
- if(sd->unequip_losehp[i] > 0) {
- hp += sd->unequip_losehp[i];
- sd->unequip_losehp[i] = 0;
- }
- if(sd->unequip_losesp[i] > 0) {
- sp += sd->unequip_losesp[i];
- sd->unequip_losesp[i] = 0;
- }
- }
- }
- if(sd->status.inventory[n].equip & 0x0002) {
- sd->weapontype1 = 0;
- sd->status.weapon = sd->weapontype2;
- pc_calcweapontype(sd);
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- if(sd->sc.data[SC_DANCING].timer!=-1) //When unequipping, stop dancing. [Skotlex]
- skill_stop_dancing(&sd->bl);
- }
- if(sd->status.inventory[n].equip & 0x0020) {
- sd->status.shield = sd->weapontype2 = 0;
- pc_calcweapontype(sd);
- clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
- }
- if(sd->status.inventory[n].equip & 0x0001) {
- sd->status.head_bottom = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
- if(sd->status.inventory[n].equip & 0x0100) {
- sd->status.head_top = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if(sd->status.inventory[n].equip & 0x0200) {
- sd->status.head_mid = 0;
- clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
- if(sd->status.inventory[n].equip & 0x0040)
- clif_changelook(&sd->bl,LOOK_SHOES,0);
-
- clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
- sd->status.inventory[n].equip=0;
- if(flag&1)
- pc_checkallowskill(sd);
- if(sd->weapontype1 == 0 && sd->weapontype2 == 0)
- skill_enchant_elemental_end(&sd->bl,-1); //武器持ち誓えは無?件で?性付?解除
- } else {
+ if(!sd->status.inventory[n].equip){ //Nothing to unequip
clif_unequipitemack(sd,n,0,0);
+ return 0;
+ }
+
+ if(sd->status.inventory[n].equip & 0x0002) {
+ sd->weapontype1 = 0;
+ sd->status.weapon = sd->weapontype2;
+ pc_calcweapontype(sd);
+ clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ if(sd->sc.data[SC_DANCING].timer!=-1) //When unequipping, stop dancing. [Skotlex]
+ skill_stop_dancing(&sd->bl);
+ }
+ if(sd->status.inventory[n].equip & 0x0020) {
+ sd->status.shield = sd->weapontype2 = 0;
+ pc_calcweapontype(sd);
+ clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
}
+ if(sd->status.inventory[n].equip & 0x0001) {
+ sd->status.head_bottom = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+ if(sd->status.inventory[n].equip & 0x0100) {
+ sd->status.head_top = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if(sd->status.inventory[n].equip & 0x0200) {
+ sd->status.head_mid = 0;
+ clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+ if(sd->status.inventory[n].equip & 0x0040)
+ clif_changelook(&sd->bl,LOOK_SHOES,0);
+ clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
+ sd->status.inventory[n].equip=0;
+ if(flag&1)
+ pc_checkallowskill(sd);
+ if(sd->weapontype1 == 0 && sd->weapontype2 == 0)
+ skill_enchant_elemental_end(&sd->bl,-1); //武器持ち誓えは無?件で?性付?解除
if(flag&1) {
status_calc_pc(sd,0);
if(sd->sc.count && sd->sc.data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
}
-
- if (hp > 0 || sp > 0) {
- if (hp > sd->status.hp)
- hp = sd->status.hp;
- if (sp > sd->status.sp)
- sp = sd->status.sp;
- pc_heal(sd, -hp, -sp);
- }
-
+ //OnUnEquip script [Skotlex]
+ if (sd->inventory_data[n] && sd->inventory_data[n]->unequip_script)
+ run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,0);
return 0;
}
diff --git a/src/map/status.c b/src/map/status.c
index d40830465..4eec25e6b 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -701,8 +701,6 @@ int status_calc_pc(struct map_session_data* sd,int first)
+ sizeof(sd->addeff3)
+ sizeof(sd->addeff3_type)
+ sizeof(sd->sp_gain_race)
- + sizeof(sd->unequip_losehp)
- + sizeof(sd->unequip_losesp)
);