- 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://svn.code.sf.net/p/rathena/svn/trunk@6204 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-04-20 23:24:20 +00:00
parent dbe31a0f87
commit c69118e1e5
9 changed files with 5273 additions and 5118 deletions

View File

@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/04/20
* 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. [Skotlex]
* Removed bonuses bDamageWhenUnequip, bLoseSPWhenUnequip as they are no
longer needed. [Skotlex]
* Updated sql-files/item_db.sql with latest. [Skotlex]
* Fixed buffer overflow in clif_MainChatMessage. It now prints a Debug
message with the offending line. [Skotlex]
* Cleaned up a bunch of GS/NJ skills [Skotlex]

View File

@ -292,9 +292,9 @@ bHPLossRate 2023
bAddRace2 2024
bHPGainValue 2025
bSubSize 2026
bDamageWhenUnequip 2027
bAddItemHealRate 2028
bLoseSPWhenUnequip 2029
bExpAddRace 2030
bSPGainRace 2031
bSPSubRace2 2032
@ -674,4 +674,4 @@ GUILD_SAMEMAP 18
GUILD_SAMEMAP_WOS 19
GUILD_AREA 20
GUILD_AREA_WOS 21
SELF 22
SELF 22

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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;

View File

@ -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 {

View File

@ -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;
}

View File

@ -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)
);