Merge pull request #279 from rathena/revert-264-cleanup/skill_db
Revert rathena/rathena#264 -- Skill DB clean up - Reverted until further issues in the main pull request are resolved.
This commit is contained in:
commit
fe3fccee73
@ -4644,10 +4644,5 @@ BSF_REM_ON_MADOGEAR 0x080
|
||||
BSF_REM_ON_DAMAGED 0x100
|
||||
BSF_PERMANENT 0x200
|
||||
|
||||
SKILL_PERM 0
|
||||
SKILL_TEMP 1
|
||||
SKILL_TEMPLEVEL 2
|
||||
SKILL_PERM_GRANT 3
|
||||
|
||||
false 0
|
||||
true 1
|
||||
|
@ -504,7 +504,7 @@
|
||||
357,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x0, LK_CONCENTRATION,Concentration
|
||||
358,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_TENSIONRELAX,Relax
|
||||
359,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_BERSERK,Frenzy
|
||||
360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_FURY,Fury
|
||||
//360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_FURY,Fury
|
||||
|
||||
//****
|
||||
// High Priest
|
||||
@ -553,10 +553,10 @@
|
||||
//****
|
||||
// Whitesmith
|
||||
384,0,0,4,0,0x1,0,10,1,yes,0,0,0,weapon,0,0x4000, WS_MELTDOWN,Shattering Strike
|
||||
385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATECOIN,Create Coins
|
||||
386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATENUGGET,Create Nuggets
|
||||
//385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATECOIN,Create Coins
|
||||
//386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATENUGGET,Create Nuggets
|
||||
387,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x4000, WS_CARTBOOST,Cart Boost
|
||||
388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WS_SYSTEMCREATE,Auto Attack System
|
||||
//388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WS_SYSTEMCREATE,Auto Attack System
|
||||
|
||||
//****
|
||||
// Stalker
|
||||
@ -768,11 +768,6 @@
|
||||
543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, NJ_NEN,Soul
|
||||
544,-5,6,1,0,0x40,0,10,1,no,0,0,0,weapon,0,0x0, NJ_ISSEN,Final Strike
|
||||
|
||||
572,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_DEATHKNIGHT,SL_DEATHKNIGHT
|
||||
573,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_COLLECTOR,SL_COLLECTOR
|
||||
574,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_NINJA,SL_NINJA
|
||||
575,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_GUNNER,SL_GUNNER
|
||||
|
||||
//****
|
||||
// Additional NPC Skills (Episode 11.3)
|
||||
653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,0x0, NPC_EARTHQUAKE,Earthquake
|
||||
@ -823,12 +818,12 @@
|
||||
689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000, CASH_BLESSING,Party Blessing
|
||||
690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000, CASH_INCAGI,Party Increase AGI
|
||||
691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0, CASH_ASSUMPTIO,Party Assumptio
|
||||
692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_CATCRY,Cat Cry
|
||||
//692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_CATCRY,Cat Cry
|
||||
693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0, ALL_PARTYFLEE,Party Flee
|
||||
//694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_ANGEL_PROTECT,Angel's Protection
|
||||
695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_DREAM_SUMMERNIGHT,Summer Night Dream
|
||||
//695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_DREAM_SUMMERNIGHT,Summer Night Dream
|
||||
//696,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, NPC_CHANGEUNDEAD2,Change Undead
|
||||
697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0, ALL_REVERSEORCISH,Reverse Orcish
|
||||
//697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0, ALL_REVERSEORCISH,Reverse Orcish
|
||||
698,0,6,4,0,0x01,0,1,1,no,0,0x2,0,none,0,0x0, ALL_WEWISH,Christmas Carol
|
||||
//699,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_SONKRAN,ALL_SONKRAN
|
||||
|
||||
|
@ -504,7 +504,7 @@
|
||||
357,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x0, LK_CONCENTRATION,Concentration
|
||||
358,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_TENSIONRELAX,Relax
|
||||
359,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_BERSERK,Frenzy
|
||||
360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_FURY,Fury
|
||||
//360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, LK_FURY,Fury
|
||||
|
||||
//****
|
||||
// High Priest
|
||||
@ -553,10 +553,10 @@
|
||||
//****
|
||||
// Whitesmith
|
||||
384,0,0,4,0,0x1,0,10,1,yes,0,0,0,weapon,0,0x4000, WS_MELTDOWN,Shattering Strike
|
||||
385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATECOIN,Create Coins
|
||||
386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATENUGGET,Create Nuggets
|
||||
//385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATECOIN,Create Coins
|
||||
//386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0, WS_CREATENUGGET,Create Nuggets
|
||||
387,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x4000, WS_CARTBOOST,Cart Boost
|
||||
388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WS_SYSTEMCREATE,Auto Attack System
|
||||
//388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WS_SYSTEMCREATE,Auto Attack System
|
||||
|
||||
//****
|
||||
// Stalker
|
||||
@ -768,11 +768,6 @@
|
||||
543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, NJ_NEN,Soul
|
||||
544,-5,8,1,0,0x40,0,10,1,no,0,0,0,misc,0,0x0, NJ_ISSEN,Final Strike
|
||||
|
||||
572,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_DEATHKNIGHT,SL_DEATHKNIGHT
|
||||
573,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_COLLECTOR,SL_COLLECTOR
|
||||
574,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_NINJA,SL_NINJA
|
||||
575,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, SL_GUNNER,SL_GUNNER
|
||||
|
||||
//****
|
||||
// Additional NPC Skills (Episode 11.3)
|
||||
653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,0x0, NPC_EARTHQUAKE,Earthquake
|
||||
@ -823,10 +818,10 @@
|
||||
689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0, CASH_BLESSING,Party Blessing
|
||||
690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0, CASH_INCAGI,Party Increase AGI
|
||||
691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0, CASH_ASSUMPTIO,Party Assumptio
|
||||
692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_CATCRY,Cat Cry
|
||||
//692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_CATCRY,Cat Cry
|
||||
693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0, ALL_PARTYFLEE,Party Flee
|
||||
694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_ANGEL_PROTECT,Angel's Protection
|
||||
695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_DREAM_SUMMERNIGHT,Summer Night Dream
|
||||
//694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_ANGEL_PROTECT,Angel's Protection
|
||||
//695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, ALL_DREAM_SUMMERNIGHT,Summer Night Dream
|
||||
//696,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0, NPC_CHANGEUNDEAD2,Change Undead
|
||||
697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0, ALL_REVERSEORCISH,Reverse Orcish
|
||||
698,0,6,4,0,0x01,0,1,1,no,0,0x2,0,none,0,0x0, ALL_WEWISH,Christmas Carol
|
||||
|
@ -5411,15 +5411,9 @@ Flag 2 means that the level parameter is to be interpreted as a stackable
|
||||
additional bonus to the skill level. If the character did not have that skill
|
||||
previously, they will now at 0+the level given.
|
||||
|
||||
Flag 3 is the same as flag 1 in that it saves to the database. However, these skills
|
||||
Flag 4 is the same as flag 1 in that it saves to the database. However, these skills
|
||||
are ignored when any action is taken that adjusts the skill tree (reset/job change).
|
||||
|
||||
Flag contants:
|
||||
0 - SKILL_PERM
|
||||
1 - SKILL_TEMP
|
||||
2 - SKILL_TEMPLEVEL
|
||||
3 - SKILL_PERM_GRANT
|
||||
|
||||
// This will permanently give the character Stone Throw (TF_THROWSTONE,152), at
|
||||
// level 1.
|
||||
skill 152,1,0;
|
||||
|
@ -225,7 +225,7 @@ alberta_in,58,52,4 script Purchasing Team#Buying 59,{
|
||||
mes "Okay, you're now approved to open the Bulk Buyer Shop.";
|
||||
set Zeny,Zeny-10000;
|
||||
getitem 6377,5; //Buy_Stall_Permit
|
||||
skill "ALL_BUYING_STORE",1,SKILL_PERM_GRANT;
|
||||
skill "ALL_BUYING_STORE",1,4;
|
||||
next;
|
||||
mes "[Mr. Hugh]";
|
||||
mes "Currently, only normal items ^8C2121EXCEPT^000000 equipment, certain potions, and hand-crafted items can be purchased in bulk, but this can still be very beneficial to you, depending on how you use it.";
|
||||
|
@ -79,7 +79,7 @@ payon,173,141,4 script Ripped Cabus#GymPass 899,{
|
||||
mes "training together like this.";
|
||||
delitem 7776,1; //Max_Weight_Up_Scroll
|
||||
set gympassmemory,.@add_carry;
|
||||
skill "ALL_INCCARRY",.@add_carry,SKILL_PERM_GRANT;
|
||||
skill "ALL_INCCARRY",.@add_carry,4;
|
||||
close;
|
||||
}
|
||||
else {
|
||||
@ -135,7 +135,7 @@ payon,173,141,4 script Ripped Cabus#GymPass 899,{
|
||||
mes "muscles grew back,";
|
||||
mes "just like that! Try not to";
|
||||
mes "wimp out again, okay?";
|
||||
skill "ALL_INCCARRY",gympassmemory,SKILL_PERM_GRANT;
|
||||
skill "ALL_INCCARRY",gympassmemory,4;
|
||||
close;
|
||||
}
|
||||
else {
|
||||
|
@ -1,6 +0,0 @@
|
||||
-- Resetting all `lv` of skills that has `flag` >= 3 (the skill that its `learned_lv` has been changed by script or special case by `learned_lv` + SKILL_FLAG_REPLACED_LV_0)
|
||||
-- If there's ALL_INCCARRY and ALL_BUYING_STORE, set the `flag` to SKILL_FLAG_PERM_GRANTED (new value is 3), those are exclusive skills given in our official scripts!
|
||||
|
||||
UPDATE `skill` SET `lv` = `flag` - 3 WHERE `flag` >= 3;
|
||||
UPDATE `skill` SET `flag` = 0 WHERE `flag` >= 3;
|
||||
UPDATE `skill` SET `flag` = 3 WHERE `id` = 681 OR `id` = 2535;
|
@ -434,6 +434,12 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
|
||||
strcat(save_status, " memo");
|
||||
}
|
||||
|
||||
//FIXME: is this neccessary? [ultramage]
|
||||
for(i=0;i<MAX_SKILL;i++)
|
||||
if ((p->skill[i].lv != 0) && (p->skill[i].id == 0))
|
||||
p->skill[i].id = i; // Fix skill tree
|
||||
|
||||
|
||||
//skills
|
||||
if( memcmp(p->skill, cp->skill, sizeof(p->skill)) )
|
||||
{
|
||||
@ -938,6 +944,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) {
|
||||
//=====================================================================================================
|
||||
int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) {
|
||||
int i,j;
|
||||
char t_msg[128] = "";
|
||||
struct mmo_charstatus* cp;
|
||||
StringBuf buf;
|
||||
SqlStmt* stmt;
|
||||
@ -947,13 +954,11 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
struct point tmp_point;
|
||||
struct item tmp_item;
|
||||
struct s_skill tmp_skill;
|
||||
uint16 skill_count = 0;
|
||||
struct s_friend tmp_friend;
|
||||
#ifdef HOTKEY_SAVING
|
||||
struct hotkey tmp_hotkey;
|
||||
int hotkey_num;
|
||||
#endif
|
||||
StringBuf msg_buf;
|
||||
|
||||
memset(p, 0, sizeof(struct mmo_charstatus));
|
||||
|
||||
@ -1060,13 +1065,11 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
p->save_point.y = MAP_DEFAULT_Y;
|
||||
}
|
||||
|
||||
StringBuf_Init(&msg_buf);
|
||||
StringBuf_AppendStr(&msg_buf, " status");
|
||||
strcat(t_msg, " status");
|
||||
|
||||
if (!load_everything) // For quick selection of data when displaying the char menu
|
||||
{
|
||||
SqlStmt_Free(stmt);
|
||||
StringBuf_Destroy(&msg_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1085,7 +1088,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
tmp_point.map = mapindex_name2id(point_map);
|
||||
memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
|
||||
}
|
||||
StringBuf_AppendStr(&msg_buf, " memo");
|
||||
strcat(t_msg, " memo");
|
||||
|
||||
//read inventory
|
||||
//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `unique_id`)
|
||||
@ -1117,7 +1120,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
|
||||
memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
|
||||
|
||||
StringBuf_AppendStr(&msg_buf, " inventory");
|
||||
strcat(t_msg, " inventory");
|
||||
|
||||
//read cart
|
||||
//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `unique_id`)
|
||||
@ -1147,34 +1150,33 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
|
||||
for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
|
||||
memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
|
||||
StringBuf_AppendStr(&msg_buf, " cart");
|
||||
strcat(t_msg, " cart");
|
||||
|
||||
//read storage
|
||||
storage_fromsql(p->account_id, &p->storage);
|
||||
StringBuf_AppendStr(&msg_buf, " storage");
|
||||
strcat(t_msg, " storage");
|
||||
|
||||
//read skill
|
||||
//`skill` (`char_id`, `id`, `lv`)
|
||||
if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv`,`flag` FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.skill_db, MAX_SKILL)
|
||||
|| SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|
||||
|| SQL_ERROR == SqlStmt_Execute(stmt)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_UINT16, &tmp_skill.id , 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UINT8 , &tmp_skill.lv , 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT8 , &tmp_skill.flag, 0, NULL, NULL) )
|
||||
|| SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|
||||
|| SQL_ERROR == SqlStmt_Execute(stmt)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id , 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR , &tmp_skill.lv , 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UCHAR , &tmp_skill.flag, 0, NULL, NULL) )
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
|
||||
if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED )
|
||||
tmp_skill.flag = SKILL_FLAG_PERMANENT;
|
||||
|
||||
for( i = 0; skill_count < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++ ) {
|
||||
if( tmp_skill.id > 0 && tmp_skill.id < MAX_SKILL_ID ) {
|
||||
memcpy(&p->skill[i], &tmp_skill, sizeof(tmp_skill));
|
||||
skill_count++;
|
||||
}
|
||||
for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
|
||||
{
|
||||
if( tmp_skill.id < ARRAYLENGTH(p->skill) )
|
||||
memcpy(&p->skill[tmp_skill.id], &tmp_skill, sizeof(tmp_skill));
|
||||
else
|
||||
ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
|
||||
}
|
||||
StringBuf_Printf(&msg_buf, " %d skills", skill_count);
|
||||
strcat(t_msg, " skills");
|
||||
|
||||
//read friends
|
||||
//`friends` (`char_id`, `friend_account`, `friend_id`)
|
||||
@ -1188,7 +1190,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
|
||||
for( i = 0; i < MAX_FRIENDS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
|
||||
memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
|
||||
StringBuf_AppendStr(&msg_buf, " friends");
|
||||
strcat(t_msg, " friends");
|
||||
|
||||
#ifdef HOTKEY_SAVING
|
||||
//read hotkeys
|
||||
@ -1209,21 +1211,20 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
else
|
||||
ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
|
||||
}
|
||||
StringBuf_AppendStr(&msg_buf, " hotkeys");
|
||||
strcat(t_msg, " hotkeys");
|
||||
#endif
|
||||
|
||||
/* Mercenary Owner DataBase */
|
||||
mercenary_owner_fromsql(char_id, p);
|
||||
StringBuf_AppendStr(&msg_buf, " mercenary");
|
||||
strcat(t_msg, " mercenary");
|
||||
|
||||
|
||||
if (charserv_config.save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, StringBuf_Value(&msg_buf)); //ok. all data load successfuly!
|
||||
if (charserv_config.save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg); //ok. all data load successfuly!
|
||||
SqlStmt_Free(stmt);
|
||||
StringBuf_Destroy(&buf);
|
||||
|
||||
cp = idb_ensure(char_db_, char_id, char_create_charstatus);
|
||||
memcpy(cp, p, sizeof(struct mmo_charstatus));
|
||||
StringBuf_Destroy(&msg_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
#define MAX_BANK_ZENY SINT32_MAX ///Max zeny in Bank
|
||||
#define MAX_FAME 1000000000 ///Max fame points
|
||||
#define MAX_CART 100 ///Maximum item in cart
|
||||
#define MAX_SKILL 1200 ///Maximum skill can be hold by Player, Homunculus, & Mercenary (skill list) AND skill_db limit
|
||||
#define MAX_SKILL 5020 ///Maximum skill data
|
||||
#define GLOBAL_REG_NUM 256 ///Max permanent character variables per char
|
||||
#define ACCOUNT_REG_NUM 64 ///Max permanent local account variables per account
|
||||
#define ACCOUNT_REG2_NUM 16 ///Max permanent global account variables per account
|
||||
@ -223,11 +223,10 @@ enum e_skill_flag
|
||||
SKILL_FLAG_PERMANENT,
|
||||
SKILL_FLAG_TEMPORARY,
|
||||
SKILL_FLAG_PLAGIARIZED,
|
||||
SKILL_FLAG_PERM_GRANTED, // Permanent, granted through someway e.g. script
|
||||
SKILL_FLAG_TMP_COMBO, //@FIXME for homunculus combo atm
|
||||
|
||||
//! NOTE: This flag be the last flag, and don't change the value if not needed!
|
||||
SKILL_FLAG_REPLACED_LV_0 = 10, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0',
|
||||
SKILL_FLAG_REPLACED_LV_0, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0',
|
||||
SKILL_FLAG_PERM_GRANTED, // permanent, granted through someway e.g. script
|
||||
SKILL_FLAG_TMP_COMBO, //@FIXME for homon combo atm
|
||||
//...
|
||||
};
|
||||
|
||||
enum e_mmo_charstatus_opt {
|
||||
@ -237,9 +236,9 @@ enum e_mmo_charstatus_opt {
|
||||
};
|
||||
|
||||
struct s_skill {
|
||||
uint16 id;
|
||||
uint8 lv;
|
||||
uint8 flag; // see enum e_skill_flag
|
||||
unsigned short id;
|
||||
unsigned char lv;
|
||||
unsigned char flag; // see enum e_skill_flag
|
||||
};
|
||||
|
||||
struct global_reg {
|
||||
@ -625,7 +624,6 @@ enum e_guild_skill {
|
||||
GD_MAX,
|
||||
};
|
||||
|
||||
#define MAX_SKILL_ID GD_MAX
|
||||
|
||||
//These mark the ID of the jobs, as expected by the client. [Skotlex]
|
||||
enum e_job {
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "trade.h"
|
||||
#include "mapreg.h"
|
||||
#include "quest.h"
|
||||
#include "pc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -3251,7 +3250,7 @@ ACMD_FUNC(questskill)
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (skill_id >= MAX_SKILL_ID) {
|
||||
if (skill_id >= MAX_SKILL_DB) {
|
||||
clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
|
||||
return -1;
|
||||
}
|
||||
@ -3264,7 +3263,7 @@ ACMD_FUNC(questskill)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pc_skill(sd, skill_id, 1, ADDSKILL_PERMANENT);
|
||||
pc_skill(sd, skill_id, 1, 0);
|
||||
clif_displaymessage(fd, msg_txt(sd,70)); // You have learned the skill.
|
||||
|
||||
return 0;
|
||||
@ -3275,7 +3274,7 @@ ACMD_FUNC(questskill)
|
||||
*------------------------------------------*/
|
||||
ACMD_FUNC(lostskill)
|
||||
{
|
||||
uint16 skill_id = 0, sk_idx = 0;
|
||||
uint16 skill_id;
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if (!message || !*message || (skill_id = atoi(message)) <= 0)
|
||||
@ -3295,7 +3294,7 @@ ACMD_FUNC(lostskill)
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (!(sk_idx = skill_get_index(skill_id))) {
|
||||
if (skill_id >= MAX_SKILL) {
|
||||
clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
|
||||
return -1;
|
||||
}
|
||||
@ -3308,8 +3307,8 @@ ACMD_FUNC(lostskill)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sd->status.skill[sk_idx].lv = 0;
|
||||
sd->status.skill[sk_idx].flag = SKILL_FLAG_PERMANENT;
|
||||
sd->status.skill[skill_id].lv = 0;
|
||||
sd->status.skill[skill_id].flag = SKILL_FLAG_PERMANENT;
|
||||
clif_deleteskill(sd,skill_id);
|
||||
clif_displaymessage(fd, msg_txt(sd,71)); // You have forgotten the skill.
|
||||
|
||||
@ -5508,11 +5507,11 @@ ACMD_FUNC(skillid) {
|
||||
|
||||
for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) {
|
||||
int idx = skill_get_index(db_data2i(data));
|
||||
if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_db[idx]->desc, message, skillen) == 0) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1164), db_data2i(data), skill_db[idx]->desc, key.str); // skill %d: %s (%s)
|
||||
if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_db[idx].desc, message, skillen) == 0) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1164), db_data2i(data), skill_db[idx].desc, key.str); // skill %d: %s (%s)
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
} else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill_db[idx]->desc,message) ) ) {
|
||||
snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(sd,1164), db_data2i(data), skill_db[idx]->desc, key.str);
|
||||
} else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill_db[idx].desc,message) ) ) {
|
||||
snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(sd,1164), db_data2i(data), skill_db[idx].desc, key.str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5560,7 +5559,7 @@ ACMD_FUNC(useskill)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SKILL_CHK_HOMUN(skill_id)
|
||||
if (skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL
|
||||
&& sd->hd && hom_is_active(sd->hd)) // (If used with @useskill, put the homunc as dest)
|
||||
bl = &sd->hd->bl;
|
||||
else
|
||||
@ -5644,7 +5643,7 @@ ACMD_FUNC(skilltree)
|
||||
{
|
||||
if( ent->need[j].id && pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
|
||||
{
|
||||
sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].lv, skill_db[ent->need[j].id]->desc); // Player requires level %d of skill %s.
|
||||
sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].lv, skill_db[ent->need[j].id].desc); // Player requires level %d of skill %s.
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
meets = 0;
|
||||
}
|
||||
@ -9119,14 +9118,13 @@ ACMD_FUNC(unloadnpcfile) {
|
||||
return 0;
|
||||
}
|
||||
ACMD_FUNC(cart) {
|
||||
#define MC_CART_MDFY(idx, x) \
|
||||
sd->status.skill[(idx)].id = x?MC_PUSHCART:0; \
|
||||
sd->status.skill[(idx)].lv = x?1:0; \
|
||||
sd->status.skill[(idx)].flag = x?SKILL_FLAG_TEMPORARY:SKILL_FLAG_PERMANENT;
|
||||
#define MC_CART_MDFY(x) \
|
||||
sd->status.skill[MC_PUSHCART].id = x?MC_PUSHCART:0; \
|
||||
sd->status.skill[MC_PUSHCART].lv = x?1:0; \
|
||||
sd->status.skill[MC_PUSHCART].flag = x?SKILL_FLAG_TEMPORARY:SKILL_FLAG_PERMANENT;
|
||||
|
||||
int val = atoi(message);
|
||||
bool need_skill = (pc_checkskill(sd, MC_PUSHCART) == 0);
|
||||
uint16 sk_idx = 0;
|
||||
|
||||
if( !message || !*message || val < 0 || val > MAX_CARTS ) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>).
|
||||
@ -9139,22 +9137,19 @@ ACMD_FUNC(cart) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(sk_idx = skill_get_index(MC_PUSHCART)))
|
||||
return -1;
|
||||
|
||||
if( need_skill ) {
|
||||
MC_CART_MDFY(sk_idx,1);
|
||||
MC_CART_MDFY(1);
|
||||
}
|
||||
|
||||
if( !pc_setcart(sd, val) ) {
|
||||
if( need_skill ) {
|
||||
MC_CART_MDFY(sk_idx,0);
|
||||
MC_CART_MDFY(0);
|
||||
}
|
||||
return -1;/* @cart failed */
|
||||
}
|
||||
|
||||
if( need_skill ) {
|
||||
MC_CART_MDFY(sk_idx,0);
|
||||
MC_CART_MDFY(0);
|
||||
}
|
||||
|
||||
clif_displaymessage(fd, msg_txt(sd,1392)); // Cart Added
|
||||
|
@ -1883,10 +1883,10 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
|
||||
struct s_skill_damage *damage = NULL;
|
||||
struct map_data *mapd = &map[m];
|
||||
|
||||
if (!idx || !skill_db[idx]->damage.map)
|
||||
if (!idx || !skill_db[idx].damage.map)
|
||||
return 0;
|
||||
|
||||
damage = &skill_db[idx]->damage;
|
||||
damage = &skill_db[idx].damage;
|
||||
|
||||
//check the adjustment works for specified type
|
||||
if (!battle_skill_damage_iscaster(damage->caster, src->type))
|
||||
@ -6945,12 +6945,11 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
}
|
||||
}
|
||||
if (sd) {
|
||||
uint16 r_skill = 0, sk_idx = 0;
|
||||
if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
|
||||
(r_skill = (uint16)sc->data[SC__AUTOSHADOWSPELL]->val1) && (sk_idx = skill_get_index(r_skill)) &&
|
||||
sd->status.skill[sk_idx].id != 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PLAGIARIZED )
|
||||
sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id != 0 && sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].flag == SKILL_FLAG_PLAGIARIZED )
|
||||
{
|
||||
int r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;
|
||||
int r_skill = sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id,
|
||||
r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;
|
||||
|
||||
if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
|
||||
int type;
|
||||
@ -7790,7 +7789,7 @@ static const struct _battle_data {
|
||||
{ "show_hp_sp_gain", &battle_config.show_hp_sp_gain, 1, 0, 1, },
|
||||
{ "mob_npc_event_type", &battle_config.mob_npc_event_type, 1, 0, 1, },
|
||||
{ "character_size", &battle_config.character_size, 1|2, 0, 1|2, },
|
||||
{ "mob_max_skilllvl", &battle_config.mob_max_skilllvl, MAX_MOBSKILL_LEVEL, 1, MAX_MOBSKILL_LEVEL, },
|
||||
{ "mob_max_skilllvl", &battle_config.mob_max_skilllvl, MAX_SKILL_LEVEL, 1, MAX_SKILL_LEVEL, },
|
||||
{ "retaliate_to_master", &battle_config.retaliate_to_master, 1, 0, 1, },
|
||||
{ "rare_drop_announce", &battle_config.rare_drop_announce, 0, 0, 10000, },
|
||||
{ "duel_allow_pvp", &battle_config.duel_allow_pvp, 0, 0, 1, },
|
||||
|
@ -951,21 +951,19 @@ int chrif_changedsex(int fd) {
|
||||
if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
|
||||
int i;
|
||||
// remove specifical skills of Bard classes
|
||||
for(i = BA_MUSICALLESSON; i <= BA_APPLEIDUN; i++) {
|
||||
uint16 sk_idx = skill_get_index(i);
|
||||
if (sd->status.skill[sk_idx].id > 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PERMANENT) {
|
||||
sd->status.skill_point += sd->status.skill[sk_idx].lv;
|
||||
sd->status.skill[sk_idx].id = 0;
|
||||
sd->status.skill[sk_idx].lv = 0;
|
||||
for(i = 315; i <= 322; i++) {
|
||||
if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
|
||||
sd->status.skill_point += sd->status.skill[i].lv;
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
}
|
||||
}
|
||||
// remove specifical skills of Dancer classes
|
||||
for(i = DC_DANCINGLESSON; i <= DC_SERVICEFORYOU; i++) {
|
||||
uint16 sk_idx = skill_get_index(i);
|
||||
if (sd->status.skill[sk_idx].id > 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PERMANENT) {
|
||||
sd->status.skill_point += sd->status.skill[sk_idx].lv;
|
||||
sd->status.skill[sk_idx].id = 0;
|
||||
sd->status.skill[sk_idx].lv = 0;
|
||||
for(i = 323; i <= 330; i++) {
|
||||
if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
|
||||
sd->status.skill_point += sd->status.skill[i].lv;
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
}
|
||||
}
|
||||
clif_updatestatus(sd, SP_SKILLPOINT);
|
||||
@ -1032,7 +1030,7 @@ int chrif_divorceack(uint32 char_id, int partner_id) {
|
||||
*------------------------------------------*/
|
||||
int chrif_deadopt(int father_id, int mother_id, int child_id) {
|
||||
struct map_session_data* sd;
|
||||
uint16 idx = skill_get_index(WE_CALLBABY);
|
||||
int idx = skill_get_index(WE_CALLBABY);
|
||||
|
||||
if( father_id && ( sd = map_charid2sd(father_id) ) != NULL && sd->status.child == child_id ) {
|
||||
sd->status.child = 0;
|
||||
|
107
src/map/clif.c
107
src/map/clif.c
@ -1486,7 +1486,7 @@ int clif_homskillinfoblock(struct map_session_data *sd)
|
||||
{ //[orn]
|
||||
struct homun_data *hd;
|
||||
int fd = sd->fd;
|
||||
int i, len=4;
|
||||
int i,j,len=4;
|
||||
WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
|
||||
|
||||
hd = sd->hd;
|
||||
@ -1498,17 +1498,15 @@ int clif_homskillinfoblock(struct map_session_data *sd)
|
||||
int id = hd->homunculus.hskill[i].id;
|
||||
if( id != 0 ){
|
||||
int combo = (hd->homunculus.hskill[i].flag)&SKILL_FLAG_TMP_COMBO;
|
||||
short idx = hom_skill_get_index(id);
|
||||
if (idx == -1)
|
||||
continue;
|
||||
j = id - HM_SKILLBASE;
|
||||
WFIFOW(fd,len ) = id;
|
||||
WFIFOW(fd,len+2) = ((combo)?INF_SELF_SKILL:skill_get_inf(id));
|
||||
WFIFOW(fd,len+4) = 0;
|
||||
WFIFOW(fd,len+6) = hd->homunculus.hskill[idx].lv;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[idx].lv);
|
||||
WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[idx].lv);
|
||||
WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[j].lv);
|
||||
WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv);
|
||||
safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
|
||||
WFIFOB(fd,len+36) = (hd->homunculus.hskill[idx].lv < hom_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
|
||||
WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < hom_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
|
||||
len+=37;
|
||||
}
|
||||
}
|
||||
@ -1521,15 +1519,12 @@ int clif_homskillinfoblock(struct map_session_data *sd)
|
||||
void clif_homskillup(struct map_session_data *sd, uint16 skill_id)
|
||||
{ //[orn]
|
||||
struct homun_data *hd;
|
||||
int fd;
|
||||
short idx = -1;
|
||||
int fd, idx;
|
||||
nullpo_retv(sd);
|
||||
idx = skill_id - HM_SKILLBASE;
|
||||
|
||||
if ((idx = hom_skill_get_index(skill_id) == -1))
|
||||
return;
|
||||
|
||||
fd = sd->fd;
|
||||
hd = sd->hd;
|
||||
fd=sd->fd;
|
||||
hd=sd->hd;
|
||||
|
||||
WFIFOHEAD(fd, packet_len(0x239));
|
||||
WFIFOW(fd,0) = 0x239;
|
||||
@ -4822,9 +4817,8 @@ void clif_skillinfoblock(struct map_session_data *sd)
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
fd = sd->fd;
|
||||
if (!fd)
|
||||
return;
|
||||
fd=sd->fd;
|
||||
if (!fd) return;
|
||||
|
||||
WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
|
||||
WFIFOW(fd,0) = 0x10f;
|
||||
@ -4868,30 +4862,28 @@ void clif_skillinfoblock(struct map_session_data *sd)
|
||||
|
||||
/// Adds new skill to the skill tree (ZC_ADD_SKILL).
|
||||
/// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B
|
||||
void clif_addskill(struct map_session_data *sd, int skill_id)
|
||||
void clif_addskill(struct map_session_data *sd, int id)
|
||||
{
|
||||
int fd;
|
||||
uint16 idx = 0;
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
fd = sd->fd;
|
||||
if (!fd || !(idx = skill_get_index(skill_id)))
|
||||
return;
|
||||
if (!fd) return;
|
||||
|
||||
if( sd->status.skill[idx].id <= 0 )
|
||||
if( sd->status.skill[id].id <= 0 )
|
||||
return;
|
||||
|
||||
WFIFOHEAD(fd, packet_len(0x111));
|
||||
WFIFOW(fd,0) = 0x111;
|
||||
WFIFOW(fd,2) = skill_id;
|
||||
WFIFOL(fd,4) = skill_get_inf(skill_id);
|
||||
WFIFOW(fd,8) = sd->status.skill[idx].lv;
|
||||
WFIFOW(fd,10) = skill_get_sp(skill_id,sd->status.skill[idx].lv);
|
||||
WFIFOW(fd,12)= skill_get_range2(&sd->bl, skill_id,sd->status.skill[idx].lv);
|
||||
safestrncpy((char*)WFIFOP(fd,14), skill_get_name(skill_id), NAME_LENGTH);
|
||||
if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT )
|
||||
WFIFOB(fd,38) = (sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_))? 1:0;
|
||||
WFIFOW(fd,2) = id;
|
||||
WFIFOL(fd,4) = skill_get_inf(id);
|
||||
WFIFOW(fd,8) = sd->status.skill[id].lv;
|
||||
WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
|
||||
WFIFOW(fd,12)= skill_get_range2(&sd->bl, id,sd->status.skill[id].lv);
|
||||
safestrncpy((char*)WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
|
||||
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
|
||||
WFIFOB(fd,38) = (sd->status.skill[id].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
|
||||
else
|
||||
WFIFOB(fd,38) = 0;
|
||||
WFIFOSET(fd,packet_len(0x111));
|
||||
@ -4900,21 +4892,18 @@ void clif_addskill(struct map_session_data *sd, int skill_id)
|
||||
|
||||
/// Deletes a skill from the skill tree (ZC_SKILLINFO_DELETE).
|
||||
/// 0441 <skill id>.W
|
||||
void clif_deleteskill(struct map_session_data *sd, int skill_id)
|
||||
void clif_deleteskill(struct map_session_data *sd, int id)
|
||||
{
|
||||
#if PACKETVER >= 20081217
|
||||
int fd;
|
||||
uint16 idx = 0;
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
fd = sd->fd;
|
||||
if (!fd || !(idx = skill_get_index(skill_id)))
|
||||
return;
|
||||
if( !fd ) return;
|
||||
|
||||
WFIFOHEAD(fd,packet_len(0x441));
|
||||
WFIFOW(fd,0) = 0x441;
|
||||
WFIFOW(fd,2) = skill_id;
|
||||
WFIFOW(fd,2) = id;
|
||||
WFIFOSET(fd,packet_len(0x441));
|
||||
#endif
|
||||
clif_skillinfoblock(sd);
|
||||
@ -4923,7 +4912,7 @@ void clif_deleteskill(struct map_session_data *sd, int skill_id)
|
||||
/// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE).
|
||||
/// 010e <skill id>.W <level>.W <sp cost>.W <attack range>.W <upgradable>.B
|
||||
void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int range, int upgradable) {
|
||||
int fd;
|
||||
int fd;
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
@ -4941,22 +4930,19 @@ void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int rang
|
||||
|
||||
/// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE2).
|
||||
/// 07e1 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <upgradable>.B
|
||||
void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf)
|
||||
void clif_skillinfo(struct map_session_data *sd,int skill, int inf)
|
||||
{
|
||||
const int fd = sd->fd;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
if (!idx)
|
||||
return;
|
||||
|
||||
WFIFOHEAD(fd,packet_len(0x7e1));
|
||||
WFIFOW(fd,0) = 0x7e1;
|
||||
WFIFOW(fd,2) = skill_id;
|
||||
WFIFOL(fd,4) = inf?inf:skill_get_inf(skill_id);
|
||||
WFIFOW(fd,8) = sd->status.skill[idx].lv;
|
||||
WFIFOW(fd,10) = skill_get_sp(skill_id,sd->status.skill[idx].lv);
|
||||
WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv);
|
||||
if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT )
|
||||
WFIFOB(fd,14) = (sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_))? 1:0;
|
||||
WFIFOW(fd,2) = skill;
|
||||
WFIFOL(fd,4) = inf?inf:skill_get_inf(skill);
|
||||
WFIFOW(fd,8) = sd->status.skill[skill].lv;
|
||||
WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv);
|
||||
WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv);
|
||||
if( sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT )
|
||||
WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0;
|
||||
else
|
||||
WFIFOB(fd,14) = 0;
|
||||
WFIFOSET(fd,packet_len(0x7e1));
|
||||
@ -11380,12 +11366,12 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
|
||||
if (tmp&INF_GROUND_SKILL || !tmp)
|
||||
return; //Using a ground/passive skill on a target? WRONG.
|
||||
|
||||
if( SKILL_CHK_HOMUN(skill_id) ) {
|
||||
if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE + MAX_HOMUNSKILL ) {
|
||||
clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skill_id, skill_lv, target_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if( SKILL_CHK_MERC(skill_id) ) {
|
||||
if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) {
|
||||
clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skill_id, skill_lv, target_id);
|
||||
return;
|
||||
}
|
||||
@ -11454,7 +11440,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
|
||||
|
||||
sd->skillitem = sd->skillitemlv = 0;
|
||||
|
||||
if( SKILL_CHK_GUILD(skill_id) ) {
|
||||
if( skill_id >= GD_SKILLBASE ) {
|
||||
if( sd->state.gmaster_flag )
|
||||
skill_lv = guild_checkskill(sd->guild, skill_id);
|
||||
else
|
||||
@ -11481,12 +11467,12 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
|
||||
if( !(skill_get_inf(skill_id)&INF_GROUND_SKILL) )
|
||||
return; //Using a target skill on the ground? WRONG.
|
||||
|
||||
if( SKILL_CHK_HOMUN(skill_id) ) {
|
||||
if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE + MAX_HOMUNSKILL ) {
|
||||
clif_parse_UseSkillToPos_homun(sd->hd, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if( SKILL_CHK_MERC(skill_id) ) {
|
||||
if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) {
|
||||
clif_parse_UseSkillToPos_mercenary(sd->md, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
|
||||
return;
|
||||
}
|
||||
@ -15695,18 +15681,15 @@ void clif_mercenary_skillblock(struct map_session_data *sd)
|
||||
WFIFOW(fd,0) = 0x29d;
|
||||
for( i = 0; i < MAX_MERCSKILL; i++ )
|
||||
{
|
||||
uint16 id;
|
||||
short idx = -1;
|
||||
int id, j;
|
||||
if( (id = md->db->skill[i].id) == 0 )
|
||||
continue;
|
||||
if ((idx = mercenary_skill_get_index(id)) == -1)
|
||||
continue;
|
||||
|
||||
j = id - MC_SKILLBASE;
|
||||
WFIFOW(fd,len) = id;
|
||||
WFIFOL(fd,len+2) = skill_get_inf(id);
|
||||
WFIFOW(fd,len+6) = md->db->skill[idx].lv;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[idx].lv);
|
||||
WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[idx].lv);
|
||||
WFIFOW(fd,len+6) = md->db->skill[j].lv;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[j].lv);
|
||||
WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[j].lv);
|
||||
safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
|
||||
WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
|
||||
len += 37;
|
||||
|
@ -532,9 +532,9 @@ void clif_class_change(struct block_list *bl,int class_,int type);
|
||||
|
||||
void clif_skillinfoblock(struct map_session_data *sd);
|
||||
void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int range, int upgradable);
|
||||
void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf);
|
||||
void clif_addskill(struct map_session_data *sd, int skill_id);
|
||||
void clif_deleteskill(struct map_session_data *sd, int skill_id);
|
||||
void clif_skillinfo(struct map_session_data *sd,int skill, int inf);
|
||||
void clif_addskill(struct map_session_data *sd, int id);
|
||||
void clif_deleteskill(struct map_session_data *sd, int id);
|
||||
|
||||
void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime);
|
||||
void clif_skillcastcancel(struct block_list* bl);
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "../common/showmsg.h"
|
||||
#include "../common/random.h"
|
||||
#include "../common/strlib.h"
|
||||
#include "../common/utils.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "clif.h"
|
||||
@ -559,12 +558,13 @@ struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16
|
||||
memset(&req,0,sizeof(req));
|
||||
|
||||
if( idx == 0 ) // invalid skill id
|
||||
return req;
|
||||
|
||||
if( skill_lv < 1 || skill_lv > MAX_SKILL_LEVEL )
|
||||
return req;
|
||||
|
||||
skill_lv = cap_value(skill_lv, 1, MAX_SKILL_LEVEL);
|
||||
|
||||
req.hp = skill_db[idx]->require.hp[skill_lv-1];
|
||||
req.sp = skill_db[idx]->require.sp[skill_lv-1];
|
||||
req.hp = skill_db[idx].require.hp[skill_lv-1];
|
||||
req.sp = skill_db[idx].require.sp[skill_lv-1];
|
||||
|
||||
return req;
|
||||
}
|
||||
@ -815,7 +815,6 @@ void read_elementaldb(void) {
|
||||
uint8 i;
|
||||
|
||||
elemental_count = 0;
|
||||
memset(elemental_db, 0, sizeof(elemental_db));
|
||||
for(i = 0; i<ARRAYLENGTH(filename); i++){
|
||||
sv_readdb(db_path, filename[i], ',', 26, 26, -1, &read_elementaldb_sub, i);
|
||||
}
|
||||
@ -826,8 +825,7 @@ void read_elementaldb(void) {
|
||||
* ElementalID,SkillID,SkillLevel,ReqMode
|
||||
*/
|
||||
static bool read_elemental_skilldb_sub(char* str[], int columns, int current) {
|
||||
uint16 class_ = atoi(str[0]), skill_id, skill_lv, skillmode;
|
||||
uint8 i;
|
||||
uint16 class_ = atoi(str[0]), i, skill_id, skill_lv, skillmode;
|
||||
struct s_elemental_db *db;
|
||||
|
||||
ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
|
||||
@ -837,8 +835,8 @@ static bool read_elemental_skilldb_sub(char* str[], int columns, int current) {
|
||||
}
|
||||
|
||||
skill_id = atoi(str[1]);
|
||||
if( !SKILL_CHK_ELEM(skill_id) ) {
|
||||
ShowError("read_elemental_skilldb_sub: Invalid Elemental skill '%d'.\n", skill_id);
|
||||
if( skill_id < EL_SKILLBASE || skill_id >= EL_SKILLBASE + MAX_ELEMENTALSKILL ) {
|
||||
ShowError("read_elemental_skilldb_sub: Skill out of range, line %d.\n", current);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -64,20 +64,6 @@ static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data
|
||||
struct npc_data **guild_flags;
|
||||
unsigned short guild_flags_count;
|
||||
|
||||
/**
|
||||
* Get guild skill index in guild_skill_tree
|
||||
* @param skill_id
|
||||
* @return Index in skill_tree or -1
|
||||
**/
|
||||
static short guild_skill_get_index(uint16 skill_id) {
|
||||
if (!SKILL_CHK_GUILD(skill_id))
|
||||
return -1;
|
||||
skill_id -= GD_SKILLBASE;
|
||||
if (skill_id >= MAX_GUILDSKILL)
|
||||
return -1;
|
||||
return skill_id;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Retrieves and validates the sd pointer for this guild member [Skotlex]
|
||||
*------------------------------------------*/
|
||||
@ -98,41 +84,44 @@ static TBL_PC* guild_sd_check(int guild_id, uint32 account_id, uint32 char_id) {
|
||||
|
||||
// Modified [Komurka]
|
||||
int guild_skill_get_max (int id) {
|
||||
if ((id = guild_skill_get_index(id)) < 0)
|
||||
if (id < GD_SKILLBASE || id >= GD_SKILLBASE+MAX_GUILDSKILL)
|
||||
return 0;
|
||||
return guild_skill_tree[id].max;
|
||||
return guild_skill_tree[id-GD_SKILLBASE].max;
|
||||
}
|
||||
|
||||
// Retrive skill_lv learned by guild
|
||||
|
||||
int guild_checkskill(struct guild *g, int id) {
|
||||
if ((id = guild_skill_get_index(id)) < 0)
|
||||
int idx = id - GD_SKILLBASE;
|
||||
if (idx < 0 || idx >= MAX_GUILDSKILL)
|
||||
return 0;
|
||||
return g->skill[id].lv;
|
||||
return g->skill[idx].lv;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* guild_skill_tree.txt reading - from jA [Komurka]
|
||||
*------------------------------------------*/
|
||||
static bool guild_read_guildskill_tree_db(char* split[], int columns, int current) {// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
|
||||
int k, skill_id = atoi(split[0]);
|
||||
short idx = -1;
|
||||
int k, id, skill_id;
|
||||
|
||||
if ((idx = guild_skill_get_index(skill_id)) < 0) {
|
||||
ShowError("guild_read_guildskill_tree_db: Invalid Guild skill '%s'.\n", split[1]);
|
||||
skill_id = atoi(split[0]);
|
||||
id = skill_id - GD_SKILLBASE;
|
||||
|
||||
if( id < 0 || id >= MAX_GUILDSKILL ) {
|
||||
ShowWarning("guild_read_guildskill_tree_db: Invalid skill id %d.\n", skill_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
guild_skill_tree[idx].id = skill_id;
|
||||
guild_skill_tree[idx].max = atoi(split[1]);
|
||||
guild_skill_tree[id].id = skill_id;
|
||||
guild_skill_tree[id].max = atoi(split[1]);
|
||||
|
||||
if( guild_skill_tree[idx].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[idx].max == 0 ) {// enable guild's glory when required for emblems
|
||||
guild_skill_tree[idx].max = 1;
|
||||
if( guild_skill_tree[id].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max == 0 ) {// enable guild's glory when required for emblems
|
||||
guild_skill_tree[id].max = 1;
|
||||
}
|
||||
|
||||
for( k = 0; k < MAX_GUILD_SKILL_REQUIRE; k++ ) {
|
||||
guild_skill_tree[idx].need[k].id = atoi(split[k*2+2]);
|
||||
guild_skill_tree[idx].need[k].lv = atoi(split[k*2+3]);
|
||||
guild_skill_tree[id].need[k].id = atoi(split[k*2+2]);
|
||||
guild_skill_tree[id].need[k].lv = atoi(split[k*2+3]);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -142,13 +131,13 @@ static bool guild_read_guildskill_tree_db(char* split[], int columns, int curren
|
||||
* Guild skill check - from jA [Komurka]
|
||||
*------------------------------------------*/
|
||||
int guild_check_skill_require(struct guild *g,int id) {
|
||||
uint8 i;
|
||||
short idx = -1;
|
||||
int i;
|
||||
int idx = id-GD_SKILLBASE;
|
||||
|
||||
if(g == NULL)
|
||||
return 0;
|
||||
|
||||
if ((idx = guild_skill_get_index(id)) < 0)
|
||||
if (idx < 0 || idx >= MAX_GUILDSKILL)
|
||||
return 0;
|
||||
|
||||
for(i=0;i<MAX_GUILD_SKILL_REQUIRE;i++)
|
||||
@ -1268,41 +1257,37 @@ int guild_getexp(struct map_session_data *sd,int exp) {
|
||||
/*====================================================
|
||||
* Ask to increase guildskill skill_id
|
||||
*---------------------------------------------------*/
|
||||
void guild_skillup(TBL_PC* sd, uint16 skill_id) {
|
||||
int guild_skillup(TBL_PC* sd, uint16 skill_id) {
|
||||
struct guild* g;
|
||||
short idx = guild_skill_get_index(skill_id);
|
||||
short max = 0;
|
||||
int idx = skill_id - GD_SKILLBASE;
|
||||
int max = guild_skill_get_max(skill_id);
|
||||
|
||||
nullpo_retv(sd);
|
||||
nullpo_ret(sd);
|
||||
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
if( sd->status.guild_id == 0 || (g=sd->guild) == NULL || // no guild
|
||||
strcmp(sd->status.name, g->master) ) // not the guild master
|
||||
return;
|
||||
|
||||
max = guild_skill_get_max(skill_id);
|
||||
if( idx < 0 || idx >= MAX_GUILDSKILL || // not a guild skill
|
||||
sd->status.guild_id == 0 || (g=sd->guild) == NULL || // no guild
|
||||
strcmp(sd->status.name, g->master) ) // not the guild master
|
||||
return 0;
|
||||
|
||||
if( g->skill_point > 0 &&
|
||||
g->skill[idx].id != 0 &&
|
||||
g->skill[idx].lv < max )
|
||||
g->skill[idx].id != 0 &&
|
||||
g->skill[idx].lv < max )
|
||||
intif_guild_skillup(g->guild_id, skill_id, sd->status.account_id, max);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*====================================================
|
||||
* Notification of guildskill skill_id increase request
|
||||
*---------------------------------------------------*/
|
||||
int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id) {
|
||||
struct map_session_data *sd = map_id2sd(account_id);
|
||||
struct guild *g = guild_search(guild_id);
|
||||
struct map_session_data *sd=map_id2sd(account_id);
|
||||
struct guild *g=guild_search(guild_id);
|
||||
int i;
|
||||
short idx = guild_skill_get_index(skill_id);
|
||||
|
||||
if (g == NULL || idx == -1)
|
||||
if(g==NULL)
|
||||
return 0;
|
||||
if (sd != NULL) {
|
||||
int lv = g->skill[idx].lv;
|
||||
if( sd != NULL ) {
|
||||
int lv = g->skill[skill_id-GD_SKILLBASE].lv;
|
||||
int range = skill_get_range(skill_id, lv);
|
||||
clif_skillup(sd,skill_id,lv,range,1);
|
||||
|
||||
@ -1312,14 +1297,14 @@ int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id) {
|
||||
case GD_GLORYWOUNDS:
|
||||
case GD_SOULCOLD:
|
||||
case GD_HAWKEYES:
|
||||
guild_guildaura_refresh(sd,skill_id,g->skill[idx].lv);
|
||||
guild_guildaura_refresh(sd,skill_id,g->skill[skill_id-GD_SKILLBASE].lv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Inform all members
|
||||
for (i = 0; i < g->max_member; i++)
|
||||
if ((sd = g->member[i].sd) != NULL)
|
||||
for(i=0;i<g->max_member;i++)
|
||||
if((sd=g->member[i].sd)!=NULL)
|
||||
clif_guild_skillinfo(sd);
|
||||
|
||||
return 0;
|
||||
|
@ -60,7 +60,7 @@ int guild_member_withdraw(int guild_id,uint32 account_id,uint32 char_id,int flag
|
||||
const char *name,const char *mes);
|
||||
int guild_expulsion(struct map_session_data *sd,int guild_id,
|
||||
uint32 account_id,uint32 char_id,const char *mes);
|
||||
void guild_skillup(struct map_session_data* sd, uint16 skill_id);
|
||||
int guild_skillup(struct map_session_data* sd, uint16 skill_id);
|
||||
void guild_block_skill(struct map_session_data *sd, int time);
|
||||
int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd);
|
||||
int guild_reply_reqalliance(struct map_session_data *sd,uint32 account_id,int flag);
|
||||
|
@ -38,11 +38,10 @@ static struct view_data hom_viewdb[MAX_HOMUNCULUS_CLASS];
|
||||
* @param skill_id
|
||||
* @return -1 if invalid skill or skill index for homunculus skill_tree
|
||||
*/
|
||||
short hom_skill_get_index(uint16 skill_id) {
|
||||
if (!SKILL_CHK_HOMUN(skill_id))
|
||||
static short hom_skill_get_index(int skill_id) {
|
||||
if (!skill_get_index(skill_id))
|
||||
return -1;
|
||||
skill_id -= HM_SKILLBASE;
|
||||
if (skill_id >= MAX_HOMUNSKILL)
|
||||
if ((skill_id -= HM_SKILLBASE) < 0 || skill_id >= MAX_HOMUNSKILL)
|
||||
return -1;
|
||||
return skill_id;
|
||||
}
|
||||
@ -125,8 +124,8 @@ int hom_class2mapid(int hom_class)
|
||||
void hom_addspiritball(TBL_HOM *hd, int max) {
|
||||
nullpo_retv(hd);
|
||||
|
||||
if (max > MAX_SPIRITBALL)
|
||||
max = MAX_SPIRITBALL;
|
||||
if (max > MAX_SKILL_LEVEL)
|
||||
max = MAX_SKILL_LEVEL;
|
||||
if (hd->homunculus.spiritball < 0)
|
||||
hd->homunculus.spiritball = 0;
|
||||
|
||||
@ -153,8 +152,8 @@ void hom_delspiritball(TBL_HOM *hd, int count, int type) {
|
||||
}
|
||||
if (count <= 0)
|
||||
return;
|
||||
if (count > MAX_SPIRITBALL)
|
||||
count = MAX_SPIRITBALL;
|
||||
if (count > MAX_SKILL_LEVEL)
|
||||
count = MAX_SKILL_LEVEL;
|
||||
if (count > hd->homunculus.spiritball)
|
||||
count = hd->homunculus.spiritball;
|
||||
|
||||
@ -269,7 +268,7 @@ void hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
|
||||
/* load previous homunculus form skills first. */
|
||||
if (hd->homunculus.prev_class != 0 && (c = hom_class2index(hd->homunculus.prev_class)) >= 0) {
|
||||
for (i = 0; i < MAX_SKILL_TREE && (skill_id = hskill_tree[c][i].id) > 0; i++) {
|
||||
short idx = hom_skill_get_index(skill_id);
|
||||
int idx = hom_skill_get_index(skill_id);
|
||||
if (idx < 0)
|
||||
continue;
|
||||
if (hd->homunculus.hskill[idx].id)
|
||||
@ -297,7 +296,7 @@ void hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
|
||||
|
||||
for (i = 0; i < MAX_SKILL_TREE && (skill_id = hskill_tree[c][i].id) > 0; i++) {
|
||||
int intimacy;
|
||||
short idx = hom_skill_get_index(skill_id);
|
||||
int idx = hom_skill_get_index(skill_id);
|
||||
if (idx < 0)
|
||||
continue;
|
||||
if (hd->homunculus.hskill[idx].id)
|
||||
@ -332,7 +331,7 @@ void hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
|
||||
*/
|
||||
short hom_checkskill(struct homun_data *hd,uint16 skill_id)
|
||||
{
|
||||
short idx = hom_skill_get_index(skill_id);
|
||||
int idx = hom_skill_get_index(skill_id);
|
||||
if (idx < 0) // Invalid skill
|
||||
return 0;
|
||||
|
||||
@ -1461,9 +1460,8 @@ void read_homunculusdb(void) {
|
||||
*/
|
||||
static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
|
||||
{// <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>,<intimacy lv req>
|
||||
uint16 skill_id;
|
||||
uint8 i;
|
||||
short class_idx, idx = -1;
|
||||
int skill_id, class_idx;
|
||||
int i, j;
|
||||
int minJobLevelPresent = 0;
|
||||
|
||||
if (columns == 14)
|
||||
@ -1471,27 +1469,29 @@ static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
|
||||
|
||||
// check for bounds [celest]
|
||||
if ((class_idx = hom_class2index(atoi(split[0]))) == -1) {
|
||||
ShowWarning("read_homunculus_skilldb: Invalid homunculus class %d.\n", atoi(split[0]));
|
||||
ShowWarning("read_homunculus_skilldb: Invalud homunculus class %d.\n", atoi(split[0]));
|
||||
return false;
|
||||
}
|
||||
|
||||
skill_id = atoi(split[1]);
|
||||
if ((idx = hom_skill_get_index(skill_id)) == -1) {
|
||||
ShowError("read_homunculus_skilldb: Invalid Homunculus skill '%s'.\n", split[1]);
|
||||
skill_id = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
|
||||
// Search an empty line or a line with the same skill_id (stored in j)
|
||||
ARR_FIND( 0, MAX_SKILL_TREE, j, !hskill_tree[class_idx][j].id || hskill_tree[class_idx][j].id == skill_id );
|
||||
if (j == MAX_SKILL_TREE) {
|
||||
ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", skill_id, atoi(split[0]));
|
||||
return false;
|
||||
}
|
||||
|
||||
hskill_tree[class_idx][idx].id = skill_id;
|
||||
hskill_tree[class_idx][idx].max = atoi(split[2]);
|
||||
hskill_tree[class_idx][j].id = skill_id;
|
||||
hskill_tree[class_idx][j].max = atoi(split[2]);
|
||||
if (minJobLevelPresent)
|
||||
hskill_tree[class_idx][idx].joblv = atoi(split[3]);
|
||||
hskill_tree[class_idx][j].joblv = atoi(split[3]);
|
||||
|
||||
for (i = 0; i < MAX_HOM_SKILL_REQUIRE; i++) {
|
||||
hskill_tree[class_idx][idx].need[i].id = atoi(split[3+i*2+minJobLevelPresent]);
|
||||
hskill_tree[class_idx][idx].need[i].lv = atoi(split[3+i*2+minJobLevelPresent+1]);
|
||||
hskill_tree[class_idx][j].need[i].id = atoi(split[3+i*2+minJobLevelPresent]);
|
||||
hskill_tree[class_idx][j].need[i].lv = atoi(split[3+i*2+minJobLevelPresent+1]);
|
||||
}
|
||||
|
||||
hskill_tree[class_idx][idx].intimacylv = atoi(split[13+minJobLevelPresent]);
|
||||
hskill_tree[class_idx][j].intimacylv = atoi(split[13+minJobLevelPresent]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -159,8 +159,6 @@ void hom_delspiritball(TBL_HOM *hd, int count, int type);
|
||||
|
||||
uint8 hom_get_intimacy_grade(struct homun_data *hd);
|
||||
|
||||
short hom_skill_get_index(uint16 skill_id);
|
||||
|
||||
void do_final_homunculus(void);
|
||||
void do_init_homunculus(void);
|
||||
|
||||
|
@ -325,12 +325,8 @@ enum e_item_ammo
|
||||
AMMO_KUNAI,
|
||||
AMMO_CANNONBALL,
|
||||
AMMO_THROWABLE_ITEM, ///Sling items
|
||||
|
||||
MAX_AMMO_TYPE,
|
||||
};
|
||||
|
||||
#define AMMO_TYPE_ALL ((1<<MAX_AMMO_TYPE)-1)
|
||||
|
||||
///Item combo struct
|
||||
struct item_combo
|
||||
{
|
||||
|
@ -59,20 +59,6 @@ struct view_data * mercenary_get_viewdata(int class_){
|
||||
return &mercenary_db[i].vd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mercenary skill index for mercenary skill tree
|
||||
* @param skill_id
|
||||
* @return Index in skill_tree or -1
|
||||
**/
|
||||
short mercenary_skill_get_index(uint16 skill_id) {
|
||||
if (!SKILL_CHK_MERC(skill_id))
|
||||
return -1;
|
||||
skill_id -= MC_SKILLBASE;
|
||||
if (skill_id >= MAX_MERCSKILL)
|
||||
return -1;
|
||||
return skill_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Mercenary for Player
|
||||
* @param sd The Player
|
||||
@ -459,11 +445,14 @@ void mercenary_kills(struct mercenary_data *md){
|
||||
* @return Skill Level or 0 if Mercenary doesn't have the skill
|
||||
**/
|
||||
int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id) {
|
||||
short idx = mercenary_skill_get_index(skill_id);
|
||||
int i = skill_id - MC_SKILLBASE;
|
||||
|
||||
if( !md || !md->db || idx == -1)
|
||||
if( !md || !md->db )
|
||||
return 0;
|
||||
return md->db->skill[idx].lv;
|
||||
if( md->db->skill[i].id == skill_id )
|
||||
return md->db->skill[i].lv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -540,7 +529,6 @@ static bool mercenary_readdb_sub(char* str[], int columns, int current)
|
||||
void mercenary_readdb(void) {
|
||||
const char *filename[]={ "mercenary_db.txt",DBIMPORT"/mercenary_db.txt"};
|
||||
uint8 i;
|
||||
|
||||
mercenary_count = 0; //Reset the counter
|
||||
memset(mercenary_db,0,sizeof(mercenary_db));
|
||||
for(i = 0; i<ARRAYLENGTH(filename); i++){
|
||||
@ -554,9 +542,7 @@ void mercenary_readdb(void) {
|
||||
static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
|
||||
{// <merc id>,<skill id>,<skill level>
|
||||
struct s_mercenary_db *db;
|
||||
uint16 class_, skill_id, skill_lv;
|
||||
uint8 i = 0;
|
||||
short idx = -1;
|
||||
uint16 i, class_, skill_id, skill_lv;
|
||||
|
||||
class_ = atoi(str[0]);
|
||||
ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
|
||||
@ -567,16 +553,18 @@ static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
|
||||
}
|
||||
|
||||
skill_id = atoi(str[1]);
|
||||
if( (idx = mercenary_skill_get_index(skill_id)) == -1 ) {
|
||||
ShowError("read_mercenary_skilldb: Invalid Mercenary skill '%s'.\n", str[1]);
|
||||
if( skill_id < MC_SKILLBASE || skill_id >= MC_SKILLBASE + MAX_MERCSKILL )
|
||||
{
|
||||
ShowError("read_mercenary_skilldb : Skill %d out of range.\n", skill_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
db = &mercenary_db[i];
|
||||
skill_lv = atoi(str[2]);
|
||||
|
||||
db->skill[idx].id = skill_id;
|
||||
db->skill[idx].lv = skill_lv;
|
||||
i = skill_id - MC_SKILLBASE;
|
||||
db->skill[i].id = skill_id;
|
||||
db->skill[i].lv = skill_lv;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -587,7 +575,6 @@ static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
|
||||
void mercenary_read_skilldb(void){
|
||||
const char *filename[]={ "mercenary_skill_db.txt",DBIMPORT"/mercenary_skill_db.txt"};
|
||||
uint8 i;
|
||||
|
||||
for(i = 0; i<ARRAYLENGTH(filename); i++){
|
||||
sv_readdb(db_path, filename[i], ',', 3, 3, -1, &mercenary_read_skilldb_sub, i);
|
||||
}
|
||||
|
@ -71,7 +71,6 @@ void mercenary_set_calls(struct mercenary_data *md, int value);
|
||||
void mercenary_kills(struct mercenary_data *md);
|
||||
|
||||
int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id);
|
||||
short mercenary_skill_get_index(uint16 skill_id);
|
||||
|
||||
/**
|
||||
* atcommand.c required
|
||||
|
@ -3492,9 +3492,8 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
|
||||
|
||||
//Go Backwards to give better priority to advanced skills.
|
||||
for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
|
||||
uint16 skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
|
||||
uint16 sk_idx = 0;
|
||||
if (!skill_id || !(sk_idx = skill_get_index(skill_id)) || sd->status.skill[sk_idx].lv < 1 ||
|
||||
int skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
|
||||
if (!skill_id || sd->status.skill[skill_id].lv < 1 ||
|
||||
(skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
|
||||
skill_get_nocast(skill_id)&16
|
||||
)
|
||||
@ -3514,7 +3513,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
|
||||
|
||||
memset (&ms[i], 0, sizeof(struct mob_skill));
|
||||
ms[i].skill_id = skill_id;
|
||||
ms[i].skill_lv = sd->status.skill[sk_idx].lv;
|
||||
ms[i].skill_lv = sd->status.skill[skill_id].lv;
|
||||
ms[i].state = MSS_ANY;
|
||||
ms[i].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5%
|
||||
ms[i].emotion = -1;
|
||||
@ -4290,7 +4289,7 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
|
||||
|
||||
//Skill ID
|
||||
j = atoi(str[3]);
|
||||
if (j <= 0 || j > MAX_SKILL_ID || !skill_get_index(j)) //fixed Lupus
|
||||
if (j <= 0 || j > MAX_SKILL_DB) //fixed Lupus
|
||||
{
|
||||
if (mob_id < 0)
|
||||
ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for all mobs\n", j);
|
||||
|
@ -112,12 +112,12 @@ int npc_isnear_sub(struct block_list* bl, va_list args) {
|
||||
if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
if (idx > 0 && skill_db[idx]->unit_nonearnpc_type) {
|
||||
if (idx > 0 && skill_db[idx].unit_nonearnpc_type) {
|
||||
while (1) {
|
||||
if (skill_db[idx]->unit_nonearnpc_type&1 && nd->subtype == NPCTYPE_WARP) break;
|
||||
if (skill_db[idx]->unit_nonearnpc_type&2 && nd->subtype == NPCTYPE_SHOP) break;
|
||||
if (skill_db[idx]->unit_nonearnpc_type&4 && nd->subtype == NPCTYPE_SCRIPT) break;
|
||||
if (skill_db[idx]->unit_nonearnpc_type&8 && nd->subtype == NPCTYPE_TOMB) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == NPCTYPE_WARP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == NPCTYPE_SHOP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&4 && nd->subtype == NPCTYPE_SCRIPT) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&8 && nd->subtype == NPCTYPE_TOMB) break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1687,9 +1687,8 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
// custom merchant shop exp bonus
|
||||
if( battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0 )
|
||||
{
|
||||
uint16 sk_idx = skill_get_index(MC_DISCOUNT);
|
||||
if( sd->status.skill[sk_idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
|
||||
skill = sd->status.skill[sk_idx].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
if( sd->status.skill[MC_DISCOUNT].flag >= SKILL_FLAG_REPLACED_LV_0 )
|
||||
skill = sd->status.skill[MC_DISCOUNT].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
|
||||
if( skill > 0 )
|
||||
{
|
||||
@ -1851,9 +1850,8 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
|
||||
// custom merchant shop exp bonus
|
||||
if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
|
||||
{
|
||||
uint16 sk_idx = skill_get_index(MC_OVERCHARGE);
|
||||
if( sd->status.skill[sk_idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
|
||||
skill = sd->status.skill[sk_idx].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
if( sd->status.skill[MC_OVERCHARGE].flag >= SKILL_FLAG_REPLACED_LV_0 )
|
||||
skill = sd->status.skill[MC_OVERCHARGE].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
|
||||
if( skill > 0 )
|
||||
{
|
||||
|
617
src/map/pc.c
617
src/map/pc.c
@ -934,12 +934,12 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
|
||||
clif_updatestatus(b_sd, SP_JOBEXP);
|
||||
|
||||
// Baby Skills
|
||||
pc_skill(b_sd, WE_BABY, 1, ADDSKILL_PERMANENT);
|
||||
pc_skill(b_sd, WE_CALLPARENT, 1, ADDSKILL_PERMANENT);
|
||||
pc_skill(b_sd, WE_BABY, 1, 0);
|
||||
pc_skill(b_sd, WE_CALLPARENT, 1, 0);
|
||||
|
||||
// Parents Skills
|
||||
pc_skill(p1_sd, WE_CALLBABY, 1, ADDSKILL_PERMANENT);
|
||||
pc_skill(p2_sd, WE_CALLBABY, 1, ADDSKILL_PERMANENT);
|
||||
pc_skill(p1_sd, WE_CALLBABY, 1, 0);
|
||||
pc_skill(p2_sd, WE_CALLBABY, 1, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1248,7 +1248,6 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
|
||||
* Check if player have any item cooldowns on
|
||||
**/
|
||||
pc_itemcd_do(sd,true);
|
||||
pc_validate_skill(sd);
|
||||
|
||||
#ifdef BOUND_ITEMS
|
||||
// Party bound item check
|
||||
@ -1356,7 +1355,7 @@ void pc_reg_received(struct map_session_data *sd)
|
||||
|
||||
if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
|
||||
sd->cloneskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM));
|
||||
if (sd->cloneskill_idx > 0) {
|
||||
if (sd->cloneskill_idx >= 0) {
|
||||
sd->status.skill[sd->cloneskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM);
|
||||
sd->status.skill[sd->cloneskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM_LV);
|
||||
if (sd->status.skill[sd->cloneskill_idx].lv > i)
|
||||
@ -1366,7 +1365,7 @@ void pc_reg_received(struct map_session_data *sd)
|
||||
}
|
||||
if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) {
|
||||
sd->reproduceskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
|
||||
if (sd->reproduceskill_idx > 0) {
|
||||
if (sd->reproduceskill_idx >= 0) {
|
||||
sd->status.skill[sd->reproduceskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE);
|
||||
sd->status.skill[sd->reproduceskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_LV);
|
||||
if (i < sd->status.skill[sd->reproduceskill_idx].lv)
|
||||
@ -1449,20 +1448,21 @@ void pc_reg_received(struct map_session_data *sd)
|
||||
|
||||
static int pc_calc_skillpoint(struct map_session_data* sd)
|
||||
{
|
||||
uint16 i, skill_point = 0;
|
||||
uint16 i, skill_point=0;
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
for(i = 1; i < MAX_SKILL; i++) {
|
||||
if( sd->status.skill[i].id && sd->status.skill[i].lv > 0) {
|
||||
uint16 inf2 = skill_get_inf2(sd->status.skill[i].id);
|
||||
if ((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
|
||||
for(i=1;i<MAX_SKILL;i++){
|
||||
uint8 skill_lv;
|
||||
if( (skill_lv = pc_checkskill(sd,i)) > 0) {
|
||||
uint16 inf2 = skill_get_inf2(i);
|
||||
if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
|
||||
!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
|
||||
)
|
||||
{
|
||||
) {
|
||||
if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
|
||||
skill_point += sd->status.skill[i].lv;
|
||||
else if(sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0)
|
||||
skill_point += skill_lv;
|
||||
else
|
||||
if(sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0)
|
||||
skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
|
||||
}
|
||||
}
|
||||
@ -1471,57 +1471,6 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
|
||||
return skill_point;
|
||||
}
|
||||
|
||||
static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
|
||||
uint16 i = 0;
|
||||
|
||||
if (!sd || !pc_has_permission(sd, PC_PERM_ALL_SKILL) || !SKILL_MAX_DB())
|
||||
return false;
|
||||
|
||||
/**
|
||||
* Dummy skills must NOT be added here otherwise they'll be displayed in the,
|
||||
* skill tree and since they have no icons they'll give resource errors
|
||||
* Get ALL skills except npc/guild ones. [Skotlex]
|
||||
* Don't add SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
|
||||
**/
|
||||
for( i = 0; i < MAX_SKILL; i++ ) {
|
||||
uint16 skill_id = skill_idx2id(i);
|
||||
if (!skill_id || (skill_get_inf2(skill_id)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)))
|
||||
continue;
|
||||
switch (skill_id) {
|
||||
case SM_SELFPROVOKE:
|
||||
case AB_DUPLELIGHT_MELEE:
|
||||
case AB_DUPLELIGHT_MAGIC:
|
||||
case WL_CHAINLIGHTNING_ATK:
|
||||
case WL_TETRAVORTEX_FIRE:
|
||||
case WL_TETRAVORTEX_WATER:
|
||||
case WL_TETRAVORTEX_WIND:
|
||||
case WL_TETRAVORTEX_GROUND:
|
||||
case WL_SUMMON_ATK_FIRE:
|
||||
case WL_SUMMON_ATK_WIND:
|
||||
case WL_SUMMON_ATK_WATER:
|
||||
case WL_SUMMON_ATK_GROUND:
|
||||
case LG_OVERBRAND_BRANDISH:
|
||||
case LG_OVERBRAND_PLUSATK:
|
||||
case WM_SEVERE_RAINSTORM_MELEE:
|
||||
case RL_R_TRIP_PLUSATK:
|
||||
case SG_DEVIL:
|
||||
case MO_TRIPLEATTACK:
|
||||
case RG_SNATCHER:
|
||||
continue;
|
||||
default:
|
||||
{
|
||||
uint8 lv = (uint8)skill_get_max(skill_id);
|
||||
if (lv > 0) {
|
||||
sd->status.skill[i].id = skill_id;
|
||||
if (addlv)
|
||||
sd->status.skill[i].lv = lv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Calculation of skill level.
|
||||
@ -1529,8 +1478,8 @@ static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
|
||||
*------------------------------------------*/
|
||||
void pc_calc_skilltree(struct map_session_data *sd)
|
||||
{
|
||||
int i, flag;
|
||||
int c = 0;
|
||||
int i,flag;
|
||||
int c=0;
|
||||
|
||||
nullpo_retv(sd);
|
||||
i = pc_calc_skilltree_normalize_job(sd);
|
||||
@ -1547,52 +1496,41 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
sd->status.skill[i].id = 0; //First clear skills.
|
||||
/* permanent skills that must be re-checked */
|
||||
if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) {
|
||||
uint16 sk_id = skill_idx2id(i);
|
||||
if (!sk_id) {
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
continue;
|
||||
}
|
||||
switch (sk_id) {
|
||||
switch( i ) {
|
||||
case NV_TRICKDEAD:
|
||||
if( (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) {
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_SKILL; i++ ) {
|
||||
uint16 skill_id = 0;
|
||||
|
||||
// Restore original level of skills after deleting earned skills.
|
||||
if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) {
|
||||
for( i = 0; i < MAX_SKILL; i++ )
|
||||
{
|
||||
if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
|
||||
{ // Restore original level of skills after deleting earned skills.
|
||||
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
}
|
||||
|
||||
//Enable Bard/Dancer spirit linked skills.
|
||||
if (!(skill_id = skill_idx2id(i)) || skill_id < DC_HUMMING || skill_id > DC_SERVICEFORYOU)
|
||||
continue;
|
||||
|
||||
if( &sd->sc && sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER ) {
|
||||
//Link Dancer skills to bard.
|
||||
if( sd->status.sex ) {
|
||||
if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU )
|
||||
{ //Enable Bard/Dancer spirit linked skills.
|
||||
if( sd->status.sex )
|
||||
{ //Link dancer skills to bard.
|
||||
if( sd->status.skill[i-8].lv < 10 )
|
||||
continue;
|
||||
sd->status.skill[i].id = skill_id;
|
||||
sd->status.skill[i].id = i;
|
||||
sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
|
||||
sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
|
||||
}
|
||||
//Link Bard skills to dancer.
|
||||
else {
|
||||
else
|
||||
{ //Link bard skills to dancer.
|
||||
if( sd->status.skill[i].lv < 10 )
|
||||
continue;
|
||||
sd->status.skill[i-8].id = skill_id - 8;
|
||||
sd->status.skill[i-8].id = i - 8;
|
||||
sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
|
||||
sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
|
||||
}
|
||||
@ -1602,84 +1540,105 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
// Removes Taekwon Ranker skill bonus
|
||||
if ((sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON) {
|
||||
uint16 c_ = pc_class2idx(JOB_TAEKWON);
|
||||
|
||||
for (i = 0; i < MAX_SKILL_TREE; i++) {
|
||||
uint16 sk_id = skill_tree[c_][i].id;
|
||||
uint16 sk_idx = 0;
|
||||
|
||||
if (!sk_id || !(sk_idx = skill_get_index(skill_tree[c_][i].id)))
|
||||
continue;
|
||||
|
||||
if (sd->status.skill[sk_idx].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[sk_idx].flag != SKILL_FLAG_PERM_GRANTED) {
|
||||
if (sk_id == NV_BASIC || sk_id == NV_FIRSTAID || sk_id == WE_CALLBABY)
|
||||
uint16 x = skill_get_index(skill_tree[c_][i].id), skid = sd->status.skill[x].id;
|
||||
if (skid && x > 0 && sd->status.skill[x].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[x].flag != SKILL_FLAG_PERM_GRANTED) {
|
||||
if (skid == NV_BASIC || skid == NV_FIRSTAID || skid == WE_CALLBABY)
|
||||
continue;
|
||||
sd->status.skill[sk_idx].id = 0;
|
||||
sd->status.skill[sk_idx].lv = 0;
|
||||
sd->status.skill[sk_idx].flag = SKILL_FLAG_PERMANENT;
|
||||
sd->status.skill[x].id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grant all skills
|
||||
pc_grant_allskills(sd, false);
|
||||
if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) {
|
||||
for( i = 0; i < MAX_SKILL; i++ ) {
|
||||
switch(i) {
|
||||
/**
|
||||
* Dummy skills must be added here otherwise they'll be displayed in the,
|
||||
* skill tree and since they have no icons they'll give resource errors
|
||||
**/
|
||||
case SM_SELFPROVOKE:
|
||||
case AB_DUPLELIGHT_MELEE:
|
||||
case AB_DUPLELIGHT_MAGIC:
|
||||
case WL_CHAINLIGHTNING_ATK:
|
||||
case WL_TETRAVORTEX_FIRE:
|
||||
case WL_TETRAVORTEX_WATER:
|
||||
case WL_TETRAVORTEX_WIND:
|
||||
case WL_TETRAVORTEX_GROUND:
|
||||
case WL_SUMMON_ATK_FIRE:
|
||||
case WL_SUMMON_ATK_WIND:
|
||||
case WL_SUMMON_ATK_WATER:
|
||||
case WL_SUMMON_ATK_GROUND:
|
||||
case LG_OVERBRAND_BRANDISH:
|
||||
case LG_OVERBRAND_PLUSATK:
|
||||
case WM_SEVERE_RAINSTORM_MELEE:
|
||||
case RL_R_TRIP_PLUSATK:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if( skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL) )
|
||||
continue; //Only skills you can't have are npc/guild ones
|
||||
if( skill_get_max(i) > 0 )
|
||||
sd->status.skill[i].id = i;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
uint16 skid = 0;
|
||||
|
||||
short skid=0;
|
||||
flag = 0;
|
||||
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++) {
|
||||
bool fail = false;
|
||||
uint16 sk_idx = skill_get_index(skid);
|
||||
|
||||
if (sd->status.skill[sk_idx].id)
|
||||
for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ )
|
||||
{
|
||||
int f;
|
||||
if( sd->status.skill[skid].id )
|
||||
continue; //Skill already known.
|
||||
|
||||
if (!battle_config.skillfree) {
|
||||
uint8 j;
|
||||
f = 1;
|
||||
if(!battle_config.skillfree) {
|
||||
int j;
|
||||
for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
|
||||
uint16 sk_need_id = skill_tree[c][i].need[j].id;
|
||||
uint16 sk_need_idx = 0;
|
||||
|
||||
if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
|
||||
short sk_need = 0;
|
||||
|
||||
if (sd->status.skill[sk_need_idx].id == 0 || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_PLAGIARIZED)
|
||||
sk_need = sk_need_id; //Not learned.
|
||||
else if (sd->status.skill[sk_need_idx].flag >= SKILL_FLAG_REPLACED_LV_0) //Real learned level
|
||||
sk_need = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
int k;
|
||||
if((k=skill_tree[c][i].need[j].id))
|
||||
{
|
||||
if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
|
||||
k = 0; //Not learned.
|
||||
else
|
||||
sk_need = pc_checkskill(sd,sk_need_id);
|
||||
|
||||
if (sk_need < skill_tree[c][i].need[j].lv) {
|
||||
fail = true;
|
||||
if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real learned level
|
||||
k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
else
|
||||
k = pc_checkskill(sd,k);
|
||||
if (k < skill_tree[c][i].need[j].lv)
|
||||
{
|
||||
f = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->status.job_level < skill_tree[c][i].joblv) { //We need to get the actual class in this case
|
||||
if( sd->status.job_level < skill_tree[c][i].joblv ) { //We need to get the actual class in this case
|
||||
int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
|
||||
class_ = pc_class2idx(class_);
|
||||
if (class_ == c || (class_ != c && sd->status.job_level < skill_tree[class_][i].joblv))
|
||||
fail = true; // job level requirement wasn't satisfied
|
||||
f = 0; // job level requirement wasn't satisfied
|
||||
}
|
||||
}
|
||||
|
||||
if (!fail) {
|
||||
int inf2 = skill_get_inf2(skid);
|
||||
if( f ) {
|
||||
int inf2;
|
||||
inf2 = skill_get_inf2(skid);
|
||||
|
||||
if (!sd->status.skill[skid].lv && (
|
||||
if(!sd->status.skill[skid].lv && (
|
||||
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
|
||||
inf2&INF2_WEDDING_SKILL ||
|
||||
(inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
|
||||
))
|
||||
continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
|
||||
|
||||
sd->status.skill[sk_idx].id = skid;
|
||||
sd->status.skill[skid].id = skid;
|
||||
|
||||
if(inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
|
||||
sd->status.skill[sk_idx].lv = 1; // need to manually specify a skill level
|
||||
sd->status.skill[sk_idx].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
|
||||
sd->status.skill[skid].lv = 1; // need to manually specify a skill level
|
||||
sd->status.skill[skid].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
|
||||
}
|
||||
flag = 1; // skill list has changed, perform another pass
|
||||
}
|
||||
@ -1687,7 +1646,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
} while(flag);
|
||||
|
||||
if( c > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
|
||||
unsigned short skid = 0;
|
||||
short skid=0;
|
||||
/* Taekwon Ranker Bonus Skill Tree
|
||||
============================================
|
||||
- Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
|
||||
@ -1695,28 +1654,25 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
- (sd->status.skill_point == 0) to wait until all skill points are assigned to avoid problems with Job Change quest. */
|
||||
|
||||
for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
|
||||
uint16 sk_idx = 0;
|
||||
if (!(sk_idx = skill_get_index(skid)))
|
||||
continue;
|
||||
if( (skill_get_inf2(skid)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
|
||||
continue; //Do not include Quest/Wedding skills.
|
||||
if( sd->status.skill[sk_idx].id == 0 ) { //do we really want skid as index ? //Lighta
|
||||
sd->status.skill[sk_idx].id = skid;
|
||||
sd->status.skill[sk_idx].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
|
||||
if( sd->status.skill[skid].id == 0 ) { //do we really want skid as index ? //Lighta
|
||||
sd->status.skill[skid].id = skid;
|
||||
sd->status.skill[skid].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
|
||||
} else if( skid != NV_BASIC )
|
||||
sd->status.skill[sk_idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[sk_idx].lv; // Remember original level
|
||||
sd->status.skill[sk_idx].lv = skill_tree_get_max(skid, sd->status.class_);
|
||||
sd->status.skill[skid].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[skid].lv; // Remember original level
|
||||
sd->status.skill[skid].lv = skill_tree_get_max(skid, sd->status.class_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Checks if you can learn a new skill after having leveled up a skill.
|
||||
static void pc_check_skilltree(struct map_session_data *sd)
|
||||
static void pc_check_skilltree(struct map_session_data *sd, int skill)
|
||||
{
|
||||
int i, flag = 0;
|
||||
int c = 0;
|
||||
int i,id=0,flag;
|
||||
int c=0;
|
||||
|
||||
if (battle_config.skillfree)
|
||||
if(battle_config.skillfree)
|
||||
return; //Function serves no purpose if this is set
|
||||
|
||||
i = pc_calc_skilltree_normalize_job(sd);
|
||||
@ -1726,54 +1682,44 @@ static void pc_check_skilltree(struct map_session_data *sd)
|
||||
return;
|
||||
}
|
||||
c = pc_class2idx(c);
|
||||
|
||||
do {
|
||||
uint16 skid = 0;
|
||||
|
||||
flag = 0;
|
||||
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
|
||||
uint16 sk_idx = skill_get_index(skid);
|
||||
bool fail = false;
|
||||
uint8 j = 0;
|
||||
|
||||
if (sd->status.skill[sk_idx].id) //Already learned
|
||||
for( i = 0; i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0; i++ )
|
||||
{
|
||||
int j, f = 1;
|
||||
if( sd->status.skill[id].id ) //Already learned
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
|
||||
uint16 sk_need_id = skill_tree[c][i].need[j].id;
|
||||
uint16 sk_need_idx = 0;
|
||||
|
||||
if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
|
||||
short sk_need = sk_need_id;
|
||||
|
||||
if (sd->status.skill[sk_need_idx].id == 0 || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_PLAGIARIZED)
|
||||
sk_need = 0; //Not learned.
|
||||
else if (sd->status.skill[sk_need_idx].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
|
||||
sk_need = sd->status.skill[sk_need_idx].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ){
|
||||
int k = skill_tree[c][i].need[j].id;
|
||||
if( k != 0 ){
|
||||
if( sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED )
|
||||
k = 0; //Not learned.
|
||||
else
|
||||
sk_need = pc_checkskill(sd,sk_need_id);
|
||||
|
||||
if (sk_need < skill_tree[c][i].need[j].lv) {
|
||||
fail = true;
|
||||
if( sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
|
||||
k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
else
|
||||
k = pc_checkskill(sd,k);
|
||||
if( k < skill_tree[c][i].need[j].lv )
|
||||
{
|
||||
f = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( fail )
|
||||
if( !f )
|
||||
continue;
|
||||
if( sd->status.job_level < skill_tree[c][i].joblv )
|
||||
continue;
|
||||
|
||||
j = skill_get_inf2(skid);
|
||||
if( !sd->status.skill[sk_idx].lv && (
|
||||
j = skill_get_inf2(id);
|
||||
if( !sd->status.skill[id].lv && (
|
||||
(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
|
||||
j&INF2_WEDDING_SKILL ||
|
||||
(j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
|
||||
) )
|
||||
continue; //Cannot be learned via normal means.
|
||||
|
||||
sd->status.skill[sk_idx].id = skid;
|
||||
sd->status.skill[id].id = id;
|
||||
flag = 1;
|
||||
}
|
||||
} while(flag);
|
||||
@ -1785,12 +1731,14 @@ void pc_clean_skilltree(struct map_session_data *sd)
|
||||
{
|
||||
uint16 i;
|
||||
for (i = 0; i < MAX_SKILL; i++){
|
||||
if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) {
|
||||
if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED)
|
||||
{
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
}
|
||||
else if (sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0){
|
||||
else
|
||||
if (sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0){
|
||||
sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
}
|
||||
@ -3868,78 +3816,74 @@ void pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type
|
||||
* 2 - Like 1, except the level granted can stack with previously learned level.
|
||||
* 4 - Like 0, except the skill will ignore skill tree (saves through job changes and resets).
|
||||
*------------------------------------------*/
|
||||
bool pc_skill(TBL_PC* sd, uint16 skill_id, int level, enum e_addskill_type type) {
|
||||
uint16 idx = 0;
|
||||
int pc_skill(TBL_PC* sd, int id, int level, int flag)
|
||||
{
|
||||
nullpo_ret(sd);
|
||||
|
||||
if (!skill_id || !(idx = skill_get_index(skill_id))) {
|
||||
ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", skill_id);
|
||||
return false;
|
||||
if( id <= 0 || id >= MAX_SKILL || skill_db[id].name == NULL) {
|
||||
ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", id);
|
||||
return 0;
|
||||
}
|
||||
if (level > MAX_SKILL_LEVEL) {
|
||||
if( level > MAX_SKILL_LEVEL ) {
|
||||
ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
if (type == ADDSKILL_TEMP_ADDLEVEL && sd->status.skill[idx].lv + level > MAX_SKILL_LEVEL) {
|
||||
ShowWarning("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d. Set to max level.\n", level, MAX_SKILL_LEVEL, sd->status.skill[idx].lv);
|
||||
level = MAX_SKILL_LEVEL - sd->status.skill[idx].lv;
|
||||
if( flag == 2 && sd->status.skill[id].lv + level > MAX_SKILL_LEVEL ) {
|
||||
ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[id].lv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ADDSKILL_PERMANENT: //Set skill data overwriting whatever was there before.
|
||||
sd->status.skill[idx].id = skill_id;
|
||||
sd->status.skill[idx].lv = level;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_PERMANENT;
|
||||
if (level == 0) { //Remove skill.
|
||||
sd->status.skill[idx].id = 0;
|
||||
clif_deleteskill(sd,skill_id);
|
||||
switch( flag ){
|
||||
case 0: //Set skill data overwriting whatever was there before.
|
||||
sd->status.skill[id].id = id;
|
||||
sd->status.skill[id].lv = level;
|
||||
sd->status.skill[id].flag = SKILL_FLAG_PERMANENT;
|
||||
if( level == 0 ) { //Remove skill.
|
||||
sd->status.skill[id].id = 0;
|
||||
clif_deleteskill(sd,id);
|
||||
} else
|
||||
clif_addskill(sd,skill_id);
|
||||
if (!skill_get_inf(skill_id)) //Only recalculate for passive skills.
|
||||
clif_addskill(sd,id);
|
||||
if( !skill_get_inf(id) ) //Only recalculate for passive skills.
|
||||
status_calc_pc(sd, SCO_NONE);
|
||||
break;
|
||||
|
||||
case ADDSKILL_TEMP: //Item bonus skill.
|
||||
if (sd->status.skill[idx].id != 0) {
|
||||
if (sd->status.skill[idx].lv >= level)
|
||||
return true;
|
||||
if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) //Non-granted skill, store it's level.
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[idx].lv;
|
||||
case 1: //Item bonus skill.
|
||||
if( sd->status.skill[id].id == id ) {
|
||||
if( sd->status.skill[id].lv >= level )
|
||||
return 0;
|
||||
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
|
||||
sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv;
|
||||
} else {
|
||||
sd->status.skill[idx].id = skill_id;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY;
|
||||
sd->status.skill[id].id = id;
|
||||
sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
|
||||
}
|
||||
sd->status.skill[idx].lv = level;
|
||||
sd->status.skill[id].lv = level;
|
||||
break;
|
||||
|
||||
case ADDSKILL_TEMP_ADDLEVEL: //Add skill bonus on top of what you had.
|
||||
if (sd->status.skill[idx].id != 0) {
|
||||
if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT)
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[idx].lv; // Store previous level.
|
||||
case 2: //Add skill bonus on top of what you had.
|
||||
if( sd->status.skill[id].id == id ) {
|
||||
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
|
||||
sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
|
||||
} else {
|
||||
sd->status.skill[idx].id = skill_id;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
|
||||
sd->status.skill[id].id = id;
|
||||
sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
|
||||
}
|
||||
sd->status.skill[idx].lv += level;
|
||||
sd->status.skill[id].lv += level;
|
||||
break;
|
||||
|
||||
case ADDSKILL_PERMANENT_GRANTED: //Permanent granted skills ignore the skill tree
|
||||
sd->status.skill[idx].id = skill_id;
|
||||
sd->status.skill[idx].lv = level;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_PERM_GRANTED;
|
||||
if (level == 0) { //Remove skill.
|
||||
sd->status.skill[idx].id = 0;
|
||||
clif_deleteskill(sd,skill_id);
|
||||
case 4: //Permanent granted skills ignore the skill tree
|
||||
sd->status.skill[id].id = id;
|
||||
sd->status.skill[id].lv = level;
|
||||
sd->status.skill[id].flag = SKILL_FLAG_PERM_GRANTED;
|
||||
if( level == 0 ) { //Remove skill.
|
||||
sd->status.skill[id].id = 0;
|
||||
clif_deleteskill(sd,id);
|
||||
} else
|
||||
clif_addskill(sd,skill_id);
|
||||
if (!skill_get_inf(skill_id)) //Only recalculate for passive skills.
|
||||
clif_addskill(sd,id);
|
||||
if( !skill_get_inf(id) ) //Only recalculate for passive skills.
|
||||
status_calc_pc(sd, SCO_NONE);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
default: //Unknown flag?
|
||||
return 0;
|
||||
}
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
/*==========================================
|
||||
* Append a card to an item ?
|
||||
@ -5485,8 +5429,8 @@ int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 sk
|
||||
int cooldown = 0, cooldownlen = ARRAYLENGTH(sd->skillcooldown);
|
||||
|
||||
if (!idx) return 0;
|
||||
if (skill_db[idx]->cooldown[skill_lv - 1])
|
||||
cooldown = skill_db[idx]->cooldown[skill_lv - 1];
|
||||
if (skill_db[idx].cooldown[skill_lv - 1])
|
||||
cooldown = skill_db[idx].cooldown[skill_lv - 1];
|
||||
|
||||
ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == skill_id);
|
||||
if (i < cooldownlen) {
|
||||
@ -5499,23 +5443,24 @@ int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 sk
|
||||
/*==========================================
|
||||
* Return player sd skill_lv learned for given skill
|
||||
*------------------------------------------*/
|
||||
uint8 pc_checkskill(struct map_session_data *sd, uint16 skill_id)
|
||||
uint8 pc_checkskill(struct map_session_data *sd,uint16 skill_id)
|
||||
{
|
||||
uint16 i = 0, idx = 0;
|
||||
if (sd == NULL)
|
||||
return 0;
|
||||
if ((idx = skill_get_index(skill_id)) == 0) {
|
||||
ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id);
|
||||
return 0;
|
||||
}
|
||||
if (SKILL_CHK_GUILD(skill_id) ) {
|
||||
if(sd == NULL) return 0;
|
||||
if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) {
|
||||
struct guild *g;
|
||||
|
||||
if( sd->status.guild_id>0 && (g=sd->guild)!=NULL)
|
||||
return guild_checkskill(g,skill_id);
|
||||
return 0;
|
||||
} else if(skill_id >= ARRAYLENGTH(sd->status.skill) ) {
|
||||
ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id);
|
||||
return 0;
|
||||
}
|
||||
return sd->status.skill[idx].lv;
|
||||
|
||||
if(sd->status.skill[skill_id].id == skill_id)
|
||||
return (sd->status.skill[skill_id].lv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6687,57 +6632,52 @@ int pc_statusup2(struct map_session_data* sd, int type, int val)
|
||||
* Update skill_lv for player sd
|
||||
* Skill point allocation
|
||||
*------------------------------------------*/
|
||||
void pc_skillup(struct map_session_data *sd,uint16 skill_id)
|
||||
int pc_skillup(struct map_session_data *sd,uint16 skill_id)
|
||||
{
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
nullpo_ret(sd);
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
if (!idx) {
|
||||
if (skill_id)
|
||||
ShowError("pc_skillup: Player attempts to level up invalid skill '%d'\n", skill_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Level up guild skill
|
||||
if (SKILL_CHK_GUILD(skill_id)) {
|
||||
if( skill_id >= GD_SKILLBASE && skill_id < GD_SKILLBASE+MAX_GUILDSKILL )
|
||||
{
|
||||
guild_skillup(sd, skill_id);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
// Level up homunculus skill
|
||||
else if (sd->hd && SKILL_CHK_HOMUN(skill_id)) {
|
||||
hom_skillup(sd->hd, skill_id);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if( sd->status.skill_point > 0 &&
|
||||
sd->status.skill[idx].id &&
|
||||
sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
|
||||
sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_) )
|
||||
{
|
||||
int lv, range, upgradable;
|
||||
sd->status.skill[idx].lv++;
|
||||
sd->status.skill_point--;
|
||||
if( !skill_get_inf(skill_id) )
|
||||
status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
|
||||
else if( sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) )
|
||||
pc_calc_skilltree(sd); // Required to grant all TK Ranker skills.
|
||||
else
|
||||
pc_check_skilltree(sd); // Check if a new skill can Lvlup
|
||||
|
||||
lv = sd->status.skill[idx].lv;
|
||||
range = skill_get_range2(&sd->bl, skill_id, lv);
|
||||
upgradable = (lv < skill_tree_get_max(sd->status.skill[idx].id, sd->status.class_)) ? 1 : 0;
|
||||
clif_skillup(sd,skill_id,lv,range,upgradable);
|
||||
clif_updatestatus(sd,SP_SKILLPOINT);
|
||||
if( skill_id == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */
|
||||
clif_updatestatus(sd,SP_CARTINFO);
|
||||
if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
|
||||
clif_skillinfoblock(sd);
|
||||
}
|
||||
else
|
||||
ShowDebug("Skill Level up failed. ID:%d idx:%d (CID=%d. AID=%d)\n", skill_id, idx, sd->status.char_id, sd->status.account_id);
|
||||
if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd )
|
||||
{
|
||||
hom_skillup(sd->hd, skill_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(skill_id >= MAX_SKILL )
|
||||
return 0;
|
||||
|
||||
if( sd->status.skill_point > 0 &&
|
||||
sd->status.skill[skill_id].id &&
|
||||
sd->status.skill[skill_id].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
|
||||
sd->status.skill[skill_id].lv < skill_tree_get_max(skill_id, sd->status.class_) )
|
||||
{
|
||||
int lv,range, upgradable;
|
||||
sd->status.skill[skill_id].lv++;
|
||||
sd->status.skill_point--;
|
||||
if( !skill_get_inf(skill_id) )
|
||||
status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
|
||||
else if( sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) )
|
||||
pc_calc_skilltree(sd); // Required to grant all TK Ranker skills.
|
||||
else
|
||||
pc_check_skilltree(sd, skill_id); // Check if a new skill can Lvlup
|
||||
|
||||
lv = sd->status.skill[skill_id].lv;
|
||||
range = skill_get_range2(&sd->bl, skill_id, lv);
|
||||
upgradable = (lv < skill_tree_get_max(sd->status.skill[skill_id].id, sd->status.class_)) ? 1 : 0;
|
||||
clif_skillup(sd,skill_id,lv,range,upgradable);
|
||||
clif_updatestatus(sd,SP_SKILLPOINT);
|
||||
if( skill_id == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */
|
||||
clif_updatestatus(sd,SP_CARTINFO);
|
||||
if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
|
||||
clif_skillinfoblock(sd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@ -6749,7 +6689,7 @@ int pc_allskillup(struct map_session_data *sd)
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
for (i = 0; i < MAX_SKILL; i++) {
|
||||
for(i=0;i<MAX_SKILL;i++){
|
||||
if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
|
||||
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
@ -6758,23 +6698,34 @@ int pc_allskillup(struct map_session_data *sd)
|
||||
}
|
||||
}
|
||||
|
||||
if (!pc_grant_allskills(sd, true)) {
|
||||
uint16 sk_id;
|
||||
for (i = 0; i < MAX_SKILL_TREE && (sk_id = skill_tree[pc_class2idx(sd->status.class_)][i].id) > 0;i++){
|
||||
int inf2 = 0;
|
||||
uint16 sk_idx = 0;
|
||||
if (!sk_id || !(sk_idx = skill_get_index(sk_id)))
|
||||
continue;
|
||||
inf2 = skill_get_inf2(sk_id);
|
||||
if (pc_has_permission(sd, PC_PERM_ALL_SKILL))
|
||||
{ //Get ALL skills except npc/guild ones. [Skotlex]
|
||||
//and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
|
||||
for(i=0;i<MAX_SKILL;i++){
|
||||
switch( i ) {
|
||||
case SG_DEVIL:
|
||||
case MO_TRIPLEATTACK:
|
||||
case RG_SNATCHER:
|
||||
continue;
|
||||
default:
|
||||
if( !(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) )
|
||||
if ( ( sd->status.skill[i].lv = skill_get_max(i) ) )//Nonexistant skills should return a max of 0 anyway.
|
||||
sd->status.skill[i].id = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int id;
|
||||
for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0;i++){
|
||||
int inf2 = skill_get_inf2(id);
|
||||
if (
|
||||
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
|
||||
(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
|
||||
sk_id == SG_DEVIL
|
||||
id==SG_DEVIL
|
||||
)
|
||||
continue; //Cannot be learned normally.
|
||||
|
||||
sd->status.skill[sk_idx].id = sk_id;
|
||||
sd->status.skill[sk_idx].lv = skill_tree_get_max(sk_id, sd->status.class_); // celest
|
||||
sd->status.skill[id].id = id;
|
||||
sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_); // celest
|
||||
}
|
||||
}
|
||||
status_calc_pc(sd,SCO_NONE);
|
||||
@ -6814,8 +6765,8 @@ int pc_resetlvl(struct map_session_data* sd,int type)
|
||||
if(sd->status.class_ == JOB_NOVICE_HIGH) {
|
||||
sd->status.status_point=100; // not 88 [celest]
|
||||
// give platinum skills upon changing
|
||||
pc_skill(sd,NV_FIRSTAID,1,ADDSKILL_PERMANENT);
|
||||
pc_skill(sd,NV_TRICKDEAD,1,ADDSKILL_PERMANENT);
|
||||
pc_skill(sd,142,1,0);
|
||||
pc_skill(sd,143,1,0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6989,11 +6940,9 @@ int pc_resetskill(struct map_session_data* sd, int flag)
|
||||
|
||||
for( i = 1; i < MAX_SKILL; i++ )
|
||||
{
|
||||
uint8 lv = sd->status.skill[i].lv;
|
||||
int lv = sd->status.skill[i].lv;
|
||||
int inf2;
|
||||
uint16 skill_id = skill_idx2id(i);
|
||||
if (lv == 0 || skill_id == 0)
|
||||
continue;
|
||||
if (lv < 1) continue;
|
||||
|
||||
inf2 = skill_get_inf2(i);
|
||||
|
||||
@ -7001,7 +6950,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
|
||||
continue;
|
||||
|
||||
// Don't reset trick dead if not a novice/baby
|
||||
if( skill_id == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
|
||||
if( i == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
|
||||
{
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
@ -7009,13 +6958,13 @@ int pc_resetskill(struct map_session_data* sd, int flag)
|
||||
}
|
||||
|
||||
// do not reset basic skill
|
||||
if( skill_id == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
|
||||
if( i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
|
||||
continue;
|
||||
|
||||
if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED )
|
||||
continue;
|
||||
|
||||
if( flag&4 && !skill_ischangesex(skill_id) )
|
||||
if( flag&4 && !skill_ischangesex(i) )
|
||||
continue;
|
||||
|
||||
if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn )
|
||||
@ -8064,26 +8013,26 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
|
||||
pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
|
||||
}
|
||||
|
||||
if(sd->cloneskill_idx > 0) {
|
||||
if(sd->cloneskill_idx >= 0) {
|
||||
if( sd->status.skill[sd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
|
||||
sd->status.skill[sd->cloneskill_idx].id = 0;
|
||||
sd->status.skill[sd->cloneskill_idx].lv = 0;
|
||||
sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
|
||||
clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM));
|
||||
}
|
||||
sd->cloneskill_idx = 0;
|
||||
sd->cloneskill_idx = -1;
|
||||
pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM, 0);
|
||||
pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM_LV, 0);
|
||||
}
|
||||
|
||||
if(sd->reproduceskill_idx > 0) {
|
||||
if(sd->reproduceskill_idx >= 0) {
|
||||
if( sd->status.skill[sd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
|
||||
sd->status.skill[sd->reproduceskill_idx].id = 0;
|
||||
sd->status.skill[sd->reproduceskill_idx].lv = 0;
|
||||
sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
|
||||
clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
|
||||
}
|
||||
sd->reproduceskill_idx = 0;
|
||||
sd->reproduceskill_idx = -1;
|
||||
pc_setglobalreg(sd,SKILL_VAR_REPRODUCE,0);
|
||||
pc_setglobalreg(sd,SKILL_VAR_REPRODUCE_LV,0);
|
||||
}
|
||||
@ -11334,32 +11283,6 @@ uint64 pc_generate_unique_id(struct map_session_data *sd) {
|
||||
return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validating skill from player after logged on
|
||||
* @param sd
|
||||
**/
|
||||
void pc_validate_skill(struct map_session_data *sd) {
|
||||
if (sd) {
|
||||
uint16 i = 0, count = 0;
|
||||
struct s_skill tmp_skills[MAX_SKILL] = {{ 0 }};
|
||||
|
||||
memcpy(tmp_skills, sd->status.skill, sizeof(sd->status.skill));
|
||||
memset(sd->status.skill, 0, sizeof(sd->status.skill));
|
||||
|
||||
for (i = 0; i < MAX_SKILL; i++) {
|
||||
uint16 idx = 0;
|
||||
if (tmp_skills[i].id == 0 || tmp_skills[i].lv == 0)
|
||||
continue;
|
||||
if ((idx = skill_get_index(tmp_skills[i].id))) {
|
||||
memcpy(&sd->status.skill[idx], &tmp_skills[i], sizeof(tmp_skills[i]));
|
||||
count++;
|
||||
}
|
||||
else
|
||||
ShowWarning("pc_validate_skill: Removing invalid skill '%d' from player (AID=%d CID=%d).\n", tmp_skills[i].id, sd->status.account_id, sd->status.char_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* pc Init/Terminate
|
||||
*------------------------------------------*/
|
||||
|
28
src/map/pc.h
28
src/map/pc.h
@ -437,7 +437,7 @@ struct map_session_data {
|
||||
|
||||
short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
|
||||
|
||||
int8 spiritball, spiritball_old;
|
||||
short spiritball, spiritball_old;
|
||||
int spirit_timer[MAX_SPIRITBALL];
|
||||
short talisman[ELE_POISON+1]; // There are actually 5 talisman Fire, Ice, Wind, Earth & Poison maybe because its color violet.
|
||||
int talisman_timer[ELE_POISON+1][10];
|
||||
@ -657,8 +657,6 @@ enum weapon_type {
|
||||
W_DOUBLE_SA, // sword + axe
|
||||
};
|
||||
|
||||
#define WEAPON_TYPE_ALL ((1<<MAX_WEAPON_TYPE)-1)
|
||||
|
||||
enum ammo_type {
|
||||
A_ARROW = 1,
|
||||
A_DAGGER, //2
|
||||
@ -916,15 +914,7 @@ void pc_bonus2(struct map_session_data *sd, int type, int type2, int val);
|
||||
void pc_bonus3(struct map_session_data *sd, int type, int type2, int type3, int val);
|
||||
void pc_bonus4(struct map_session_data *sd, int type, int type2, int type3, int type4, int val);
|
||||
void pc_bonus5(struct map_session_data *sd, int type, int type2, int type3, int type4, int type5, int val);
|
||||
|
||||
enum e_addskill_type {
|
||||
ADDSKILL_PERMANENT = 0, ///< Permanent skill. Remove the skill if level is 0
|
||||
ADDSKILL_TEMP = 1, ///< Temporary skill. If player learned the skill and the given level is higher, level will be replaced and learned level will be palced in skill flag. `flag = learned + SKILL_FLAG_REPLACED_LV_0; learned_level = level;`
|
||||
ADDSKILL_TEMP_ADDLEVEL = 2, ///< Like PCSKILL_TEMP, except the level will be stacked. `learned_level += level`. The flag is used to store original learned level
|
||||
ADDSKILL_PERMANENT_GRANTED = 3, ///< Grant permanent skill, ignore skill tree and learned level
|
||||
};
|
||||
|
||||
bool pc_skill(struct map_session_data *sd, uint16 skill_id, int level, enum e_addskill_type type);
|
||||
int pc_skill(struct map_session_data *sd, int id, int level, int flag);
|
||||
|
||||
int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip);
|
||||
|
||||
@ -951,7 +941,7 @@ int pc_need_status_point(struct map_session_data *,int,int);
|
||||
int pc_maxparameterincrease(struct map_session_data*,int);
|
||||
bool pc_statusup(struct map_session_data*,int,int);
|
||||
int pc_statusup2(struct map_session_data*,int,int);
|
||||
void pc_skillup(struct map_session_data*,uint16 skill_id);
|
||||
int pc_skillup(struct map_session_data*,uint16 skill_id);
|
||||
int pc_allskillup(struct map_session_data*);
|
||||
int pc_resetlvl(struct map_session_data*,int type);
|
||||
int pc_resetstate(struct map_session_data*);
|
||||
@ -1036,12 +1026,12 @@ int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex
|
||||
const char * job_name(int class_);
|
||||
|
||||
struct skill_tree_entry {
|
||||
uint16 id;
|
||||
uint8 max;
|
||||
uint8 joblv;
|
||||
short id;
|
||||
unsigned char max;
|
||||
unsigned char joblv;
|
||||
struct {
|
||||
uint16 id;
|
||||
uint8 lv;
|
||||
short id;
|
||||
unsigned char lv;
|
||||
} need[MAX_PC_SKILL_REQUIRE];
|
||||
}; // Celest
|
||||
extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
|
||||
@ -1144,8 +1134,6 @@ bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short inde
|
||||
|
||||
int pc_autotrade_timer(int tid, unsigned int tick, int id, intptr_t data);
|
||||
|
||||
void pc_validate_skill(struct map_session_data *sd);
|
||||
|
||||
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
|
||||
int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type);
|
||||
#endif
|
||||
|
@ -8604,25 +8604,53 @@ BUILDIN_FUNC(skill)
|
||||
{
|
||||
int id;
|
||||
int level;
|
||||
int flag = ADDSKILL_TEMP;
|
||||
int flag = 1;
|
||||
TBL_PC* sd;
|
||||
struct script_data *data;
|
||||
const char* command = script_getfuncname(st);
|
||||
|
||||
sd = script_rid2sd(st);
|
||||
if( sd == NULL )
|
||||
return 0;// no player attached, report source
|
||||
|
||||
if (strcmpi(command, "addtoskill") == 0)
|
||||
flag = ADDSKILL_TEMP_ADDLEVEL;
|
||||
|
||||
data = script_getdata(st, 2);
|
||||
get_val(st, data); // Convert into value in case of a variable
|
||||
id = ( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
|
||||
level = script_getnum(st,3);
|
||||
if( script_hasdata(st,4) )
|
||||
flag = script_getnum(st,4);
|
||||
pc_skill(sd, id, level, (enum e_addskill_type)flag);
|
||||
pc_skill(sd, id, level, flag);
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/// Changes the level of a player skill.
|
||||
/// like skill, but <flag> defaults to 2
|
||||
///
|
||||
/// addtoskill <skill id>,<amount>,<flag>
|
||||
/// addtoskill <skill id>,<amount>
|
||||
/// addtoskill "<skill name>",<amount>,<flag>
|
||||
/// addtoskill "<skill name>",<amount>
|
||||
///
|
||||
/// @see skill
|
||||
BUILDIN_FUNC(addtoskill)
|
||||
{
|
||||
int id;
|
||||
int level;
|
||||
int flag = 2;
|
||||
TBL_PC* sd;
|
||||
struct script_data *data;
|
||||
|
||||
sd = script_rid2sd(st);
|
||||
if( sd == NULL )
|
||||
return 0;// no player attached, report source
|
||||
|
||||
data = script_getdata(st, 2);
|
||||
get_val(st, data); // Convert into value in case of a variable
|
||||
id = ( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
|
||||
level = script_getnum(st,3);
|
||||
if( script_hasdata(st,4) )
|
||||
flag = script_getnum(st,4);
|
||||
pc_skill(sd, id, level, flag);
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -19348,7 +19376,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(autobonus2,"sii??"),
|
||||
BUILDIN_DEF(autobonus3,"siiv?"),
|
||||
BUILDIN_DEF(skill,"vi?"),
|
||||
BUILDIN_DEF2(skill,"addtoskill","vi?"), // [Valaris]
|
||||
BUILDIN_DEF(addtoskill,"vi?"), // [Valaris]
|
||||
BUILDIN_DEF(guildskill,"vi"),
|
||||
BUILDIN_DEF(getskilllv,"v"),
|
||||
BUILDIN_DEF(getgdskilllv,"iv"),
|
||||
|
836
src/map/skill.c
836
src/map/skill.c
File diff suppressed because it is too large
Load Diff
168
src/map/skill.h
168
src/map/skill.h
@ -13,14 +13,14 @@ struct skill_unit;
|
||||
struct skill_unit_group;
|
||||
struct status_change_entry;
|
||||
|
||||
#define MAX_SKILL_DB MAX_SKILL /// Max Skill DB
|
||||
#define MAX_SKILL_PRODUCE_DB 270 /// Max Produce DB
|
||||
#define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements
|
||||
#define MAX_SKILL_ARROW_DB 150 /// Max Arrow Creation DB
|
||||
#define MAX_ARROW_RESULT 5 /// Max Arrow results/created
|
||||
#define MAX_SKILL_ABRA_DB 160 /// Max Skill list of Abracadabra DB
|
||||
#define MAX_SKILL_IMPROVISE_DB 30 /// Max Skill for Improvise
|
||||
#define MAX_SKILL_LEVEL 10 /// Max Skill Level (for skill_db storage)
|
||||
#define MAX_MOBSKILL_LEVEL 100 /// Max monster skill level (on skill usage)
|
||||
#define MAX_SKILL_LEVEL 100 /// Max Skill Level
|
||||
#define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
|
||||
#define SKILL_NAME_LENGTH 31 /// Max Skill Name length
|
||||
#define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
|
||||
@ -111,116 +111,80 @@ enum e_skill_display {
|
||||
#define MAX_SKILL_ITEM_REQUIRE 10 /// Maximum required items
|
||||
#define MAX_SKILL_STATUS_REQUIRE 3 /// Maximum required statuses
|
||||
#define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
|
||||
|
||||
/// Single skill requirement. !TODO: Cleanup the variable types
|
||||
struct skill_condition {
|
||||
int16 hp; ///< HP cost
|
||||
int16 mhp; ///< Max HP to trigger
|
||||
int16 sp; /// SP cost
|
||||
int16 hp_rate; /// HP cost (%)
|
||||
int16 sp_rate; /// SP cost (%)
|
||||
uint32 zeny; /// Zeny cost
|
||||
uint32 weapon; /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
|
||||
uint16 ammo; /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
|
||||
int8 ammo_qty; /// Amount of ammo
|
||||
uint8 state; /// State/condition. @see enum e_require_state
|
||||
int8 spiritball; /// Spiritball cost
|
||||
uint16 itemid[MAX_SKILL_ITEM_REQUIRE]; /// Required item
|
||||
uint16 amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
int hp, /// HP cost
|
||||
mhp, /// Max HP to trigger
|
||||
sp, /// SP cost
|
||||
hp_rate, /// HP cost (%)
|
||||
sp_rate, /// SP cost (%)
|
||||
ammo, /// Ammo type
|
||||
ammo_qty, /// Amount of ammo
|
||||
weapon, /// Weapon type
|
||||
zeny, /// Zeny cost
|
||||
state, /// State/condition
|
||||
spiritball, /// Spiritball cost
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
|
||||
amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
};
|
||||
|
||||
/// Skill requirement structure. !TODO: Cleanup the variable types that use array [MAX_SKILL_LEVEL]
|
||||
struct s_skill_require {
|
||||
int hp[MAX_SKILL_LEVEL]; ///< HP cost
|
||||
int mhp[MAX_SKILL_LEVEL]; ///< Max HP to trigger
|
||||
int sp[MAX_SKILL_LEVEL]; /// SP cost
|
||||
int hp_rate[MAX_SKILL_LEVEL]; /// HP cost (%)
|
||||
int sp_rate[MAX_SKILL_LEVEL]; /// SP cost (%)
|
||||
int zeny[MAX_SKILL_LEVEL]; /// Zeny cost
|
||||
uint32 weapon; /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
|
||||
uint16 ammo; /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
|
||||
int ammo_qty[MAX_SKILL_LEVEL]; /// Amount of ammo
|
||||
uint8 state; /// State/condition. @see enum e_require_state
|
||||
int spiritball[MAX_SKILL_LEVEL]; /// Spiritball cost
|
||||
int itemid[MAX_SKILL_ITEM_REQUIRE]; /// Required item
|
||||
int amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
int hp[MAX_SKILL_LEVEL], /// HP cost
|
||||
mhp[MAX_SKILL_LEVEL], /// Max HP to trigger
|
||||
sp[MAX_SKILL_LEVEL], /// SP cost
|
||||
hp_rate[MAX_SKILL_LEVEL], /// HP cost (%)
|
||||
sp_rate[MAX_SKILL_LEVEL], /// SP cost (%)
|
||||
zeny[MAX_SKILL_LEVEL], /// Zeny cost
|
||||
weapon, /// Weapon type
|
||||
ammo, /// Ammo type
|
||||
ammo_qty[MAX_SKILL_LEVEL], /// Amount of ammo
|
||||
state, /// State/condition
|
||||
spiritball[MAX_SKILL_LEVEL], /// Spiritball cost
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
|
||||
amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
};
|
||||
|
||||
/// Database skills. !TODO: Cleanup the variable types that use array [MAX_SKILL_LEVEL]
|
||||
/// Database skills
|
||||
struct s_skill_db {
|
||||
// skill_db.txt
|
||||
uint16 nameid; ///< Skill ID
|
||||
char name[SKILL_NAME_LENGTH]; ///< AEGIS_Name
|
||||
char desc[SKILL_DESC_LENGTH]; ///< English Name
|
||||
int range[MAX_SKILL_LEVEL]; ///< Range
|
||||
int8 hit; ///< Hit type
|
||||
uint8 inf; ///< Inf: 0- passive, 1- enemy, 2- place, 4- self, 16- friend, 32- trap
|
||||
int element[MAX_SKILL_LEVEL]; ///< Element
|
||||
uint8 nk; ///< Damage properties
|
||||
int splash[MAX_SKILL_LEVEL]; ///< Splash effect
|
||||
uint8 max; ///< Max level
|
||||
int num[MAX_SKILL_LEVEL]; ///< Number of hit
|
||||
bool castcancel; ///< Cancel cast when being hit
|
||||
int16 cast_def_rate; ///< Def rate during cast a skill
|
||||
uint16 skill_type; ///< Skill type
|
||||
int blewcount[MAX_SKILL_LEVEL]; ///< Blew count
|
||||
uint32 inf2; ///<
|
||||
uint32 inf3; ///<
|
||||
int maxcount[MAX_SKILL_LEVEL]; ///< Max number skill can be casted in same map
|
||||
|
||||
// skill_castnodex_db.txt
|
||||
uint8 castnodex; ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
|
||||
uint8 delaynodex; ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
|
||||
|
||||
// skill_nocast_db.txt
|
||||
uint32 nocast; ///< Skill cannot be casted at this zone
|
||||
|
||||
// skill_unit_db.txt
|
||||
uint16 unit_id[2]; ///< Unit ID. @see enum s_skill_unit_id
|
||||
int unit_layout_type[MAX_SKILL_LEVEL]; ///< Layout type. -1 is special layout, others are square with lenght*width: (val*2+1)^2
|
||||
int unit_range[MAX_SKILL_LEVEL]; ///< Unit cell effect range
|
||||
int16 unit_interval; ///< Interval
|
||||
uint32 unit_target; ///< Unit target. @see enum e_battle_check_target
|
||||
uint32 unit_flag; ///< Unit flags. @see enum e_skill_unit_flag
|
||||
|
||||
// skill_cast_db.txt
|
||||
int cast[MAX_SKILL_LEVEL]; ///< Variable casttime
|
||||
char name[SKILL_NAME_LENGTH];
|
||||
char desc[SKILL_DESC_LENGTH];
|
||||
int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
|
||||
int num[MAX_SKILL_LEVEL];
|
||||
int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL];
|
||||
#ifdef RENEWAL_CAST
|
||||
int fixed_cast[MAX_SKILL_LEVEL]; ///< If -1 means 20% than 'cast'
|
||||
int fixed_cast[MAX_SKILL_LEVEL];
|
||||
#endif
|
||||
int walkdelay[MAX_SKILL_LEVEL]; ///< Delay to walk after casting
|
||||
int delay[MAX_SKILL_LEVEL]; ///< Global delay (delay before reusing all skills)
|
||||
int cooldown[MAX_SKILL_LEVEL]; ///< Cooldown (delay before reusing same skill)
|
||||
int upkeep_time[MAX_SKILL_LEVEL]; ///< Duration
|
||||
int upkeep_time2[MAX_SKILL_LEVEL]; ///< Duration2
|
||||
|
||||
// skill_require_db.txt
|
||||
struct s_skill_require require; ///< Skill requirement
|
||||
|
||||
// skill_nonearnpc_db.txt
|
||||
int upkeep_time[MAX_SKILL_LEVEL],upkeep_time2[MAX_SKILL_LEVEL],cooldown[MAX_SKILL_LEVEL];
|
||||
int castcancel,cast_def_rate;
|
||||
int inf2,maxcount[MAX_SKILL_LEVEL],skill_type,inf3;
|
||||
int blewcount[MAX_SKILL_LEVEL];
|
||||
struct s_skill_require require;
|
||||
int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL];
|
||||
int32 nocast;
|
||||
int unit_id[2];
|
||||
int unit_layout_type[MAX_SKILL_LEVEL];
|
||||
int unit_range[MAX_SKILL_LEVEL];
|
||||
int unit_interval;
|
||||
int unit_target;
|
||||
int unit_flag;
|
||||
uint8 unit_nonearnpc_range; //additional range for UF_NONEARNPC or INF2_NO_NEARNPC [Cydh]
|
||||
uint8 unit_nonearnpc_type; //type of NPC [Cydh]
|
||||
|
||||
// skill_damage_db.txt
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
struct s_skill_damage damage;
|
||||
#endif
|
||||
|
||||
// skill_copyable_db.txt
|
||||
struct s_copyable { // [Cydh]
|
||||
uint8 option;
|
||||
uint16 joballowed, req_opt;
|
||||
} copyable;
|
||||
};
|
||||
extern struct s_skill_db **skill_db;
|
||||
extern struct s_skill_db skill_db[MAX_SKILL_DB];
|
||||
|
||||
#define MAX_SKILL_UNIT_LAYOUT 52
|
||||
#define MAX_SKILL_UNIT_LAYOUT2 17
|
||||
@ -297,7 +261,7 @@ struct skill_unit_group_tickset {
|
||||
};
|
||||
|
||||
|
||||
enum e_skill_unit_flag {
|
||||
enum {
|
||||
UF_DEFNOTENEMY = 0x00001, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
UF_NOREITERATION = 0x00002, // Spell cannot be stacked
|
||||
UF_NOFOOTSET = 0x00004, // Spell cannot be cast near/on targets
|
||||
@ -357,9 +321,7 @@ const char* skill_get_desc( uint16 skill_id ); // [Skotlex]
|
||||
int skill_tree_get_max( uint16 skill_id, int b_class ); // Celest
|
||||
|
||||
// Accessor to the skills database
|
||||
int skill_get_index_( uint16 skill_id, bool check_db );
|
||||
#define skill_get_index(skill_id) skill_get_index_((skill_id),false) /// Get skill index from skill_id (common usage on source)
|
||||
#define skill_get_index2(skill_id) skill_get_index_((skill_id),true) /// Get skill index from skill_id (used when reading skill_db files)
|
||||
int skill_get_index( uint16 skill_id );
|
||||
int skill_get_type( uint16 skill_id );
|
||||
int skill_get_hit( uint16 skill_id );
|
||||
int skill_get_inf( uint16 skill_id );
|
||||
@ -375,7 +337,7 @@ int skill_get_delay( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_time( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_time2( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_castnodex( uint16 skill_id );
|
||||
int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_castdef( uint16 skill_id );
|
||||
int skill_get_nocast( uint16 skill_id );
|
||||
int skill_get_unit_id(uint16 skill_id,int flag);
|
||||
@ -405,9 +367,6 @@ int skill_get_itemid( uint16 skill_id, int idx );
|
||||
int skill_get_itemqty( uint16 skill_id, int idx );
|
||||
|
||||
int skill_name2id(const char* name);
|
||||
uint16 skill_idx2id(uint16 idx);
|
||||
|
||||
uint16 SKILL_MAX_DB(void);
|
||||
|
||||
int skill_isammotype(struct map_session_data *sd, unsigned short skill_id);
|
||||
int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data);
|
||||
@ -1856,7 +1815,7 @@ enum e_skill {
|
||||
};
|
||||
|
||||
/// The client view ids for land skills.
|
||||
enum s_skill_unit_id {
|
||||
enum {
|
||||
UNT_SAFETYWALL = 0x7e,
|
||||
UNT_FIREWALL,
|
||||
UNT_WARP_WAITING,
|
||||
@ -2096,9 +2055,4 @@ enum e_skill_damage_caster {
|
||||
/// Variable name of copied skill level by Reproduce
|
||||
#define SKILL_VAR_REPRODUCE_LV "REPRODUCE_SKILL_LV"
|
||||
|
||||
#define SKILL_CHK_HOMUN(skill_id) ( (skill_id) >= HM_SKILLBASE && (skill_id) < HM_SKILLBASE+MAX_HOMUNSKILL )
|
||||
#define SKILL_CHK_MERC(skill_id) ( (skill_id) >= MC_SKILLBASE && (skill_id) < MC_SKILLBASE+MAX_MERCSKILL )
|
||||
#define SKILL_CHK_ELEM(skill_id) ( (skill_id) >= EL_SKILLBASE && (skill_id) < EL_SKILLBASE+MAX_ELEMENTALSKILL )
|
||||
#define SKILL_CHK_GUILD(skill_id) ( (skill_id) >= GD_SKILLBASE && (skill_id) < GD_SKILLBASE+MAX_GUILDSKILL )
|
||||
|
||||
#endif /* _SKILL_H_ */
|
||||
|
@ -154,11 +154,11 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
|
||||
{
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
if( idx == 0 ) {
|
||||
ShowError("set_sc: Unsupported skill id %d (SC: %d. Icon: %d)\n", skill_id, sc, icon);
|
||||
ShowError("set_sc: Unsupported skill id %d\n", skill_id);
|
||||
return;
|
||||
}
|
||||
if( sc < 0 || sc >= SC_MAX ) {
|
||||
ShowError("set_sc: Unsupported status change id %d (Skill: %d. Icon: %d)\n", sc, skill_id, icon);
|
||||
ShowError("set_sc: Unsupported status change id %d\n", sc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -172,16 +172,6 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
|
||||
SkillStatusChangeTable[idx] = sc;
|
||||
}
|
||||
|
||||
static void set_sc_with_vfx_noskill(sc_type sc, int icon, unsigned flag) {
|
||||
if (sc > SC_NONE && sc < SC_MAX) {
|
||||
if (StatusIconChangeTable[sc] == SI_BLANK)
|
||||
StatusIconChangeTable[sc] = icon;
|
||||
StatusChangeFlagTable[sc] |= flag;
|
||||
}
|
||||
if (icon > SI_BLANK && icon < SI_MAX)
|
||||
StatusRelevantBLTypes[icon] |= BL_SCEFFECT;
|
||||
}
|
||||
|
||||
void initChangeTables(void)
|
||||
{
|
||||
int i;
|
||||
@ -801,6 +791,8 @@ void initChangeTables(void)
|
||||
set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
|
||||
|
||||
set_sc( ALL_FULL_THROTTLE , SC_FULL_THROTTLE , SI_FULL_THROTTLE , SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
|
||||
set_sc_with_vfx( SC_MOONSTAR , SC_MOONSTAR , SI_MOONSTAR , SCB_NONE );
|
||||
set_sc_with_vfx( SC_SUPER_STAR , SC_SUPER_STAR , SI_SUPER_STAR , SCB_NONE );
|
||||
|
||||
/* Rebellion */
|
||||
add_sc( RL_MASS_SPIRAL , SC_BLEEDING );
|
||||
@ -814,26 +806,24 @@ void initChangeTables(void)
|
||||
set_sc_with_vfx( RL_C_MARKER , SC_C_MARKER , SI_C_MARKER , SCB_FLEE );
|
||||
set_sc_with_vfx( RL_AM_BLAST , SC_ANTI_M_BLAST , SI_ANTI_M_BLAST , SCB_NONE );
|
||||
|
||||
set_sc_with_vfx_noskill( SC_MOONSTAR , SI_MOONSTAR , SCB_NONE );
|
||||
set_sc_with_vfx_noskill( SC_SUPER_STAR , SI_SUPER_STAR , SCB_NONE );
|
||||
set_sc_with_vfx_noskill( SC_ALL_RIDING , SI_ALL_RIDING , SCB_SPEED );
|
||||
set_sc_with_vfx( SC_ALL_RIDING , SC_ALL_RIDING , SI_ALL_RIDING , SCB_SPEED );
|
||||
|
||||
/* Storing the target job rather than simply SC_SPIRIT simplifies code later on */
|
||||
SkillStatusChangeTable[skill_get_index(SL_ALCHEMIST)] = (sc_type)MAPID_ALCHEMIST,
|
||||
SkillStatusChangeTable[skill_get_index(SL_MONK)] = (sc_type)MAPID_MONK,
|
||||
SkillStatusChangeTable[skill_get_index(SL_STAR)] = (sc_type)MAPID_STAR_GLADIATOR,
|
||||
SkillStatusChangeTable[skill_get_index(SL_SAGE)] = (sc_type)MAPID_SAGE,
|
||||
SkillStatusChangeTable[skill_get_index(SL_CRUSADER)] = (sc_type)MAPID_CRUSADER,
|
||||
SkillStatusChangeTable[skill_get_index(SL_SUPERNOVICE)] = (sc_type)MAPID_SUPER_NOVICE,
|
||||
SkillStatusChangeTable[skill_get_index(SL_KNIGHT)] = (sc_type)MAPID_KNIGHT,
|
||||
SkillStatusChangeTable[skill_get_index(SL_WIZARD)] = (sc_type)MAPID_WIZARD,
|
||||
SkillStatusChangeTable[skill_get_index(SL_PRIEST)] = (sc_type)MAPID_PRIEST,
|
||||
SkillStatusChangeTable[skill_get_index(SL_BARDDANCER)] = (sc_type)MAPID_BARDDANCER,
|
||||
SkillStatusChangeTable[skill_get_index(SL_ROGUE)] = (sc_type)MAPID_ROGUE,
|
||||
SkillStatusChangeTable[skill_get_index(SL_ASSASIN)] = (sc_type)MAPID_ASSASSIN,
|
||||
SkillStatusChangeTable[skill_get_index(SL_BLACKSMITH)] = (sc_type)MAPID_BLACKSMITH,
|
||||
SkillStatusChangeTable[skill_get_index(SL_HUNTER)] = (sc_type)MAPID_HUNTER,
|
||||
SkillStatusChangeTable[skill_get_index(SL_SOULLINKER)] = (sc_type)MAPID_SOUL_LINKER,
|
||||
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
|
||||
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
|
||||
SkillStatusChangeTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
|
||||
SkillStatusChangeTable[SL_SAGE] = (sc_type)MAPID_SAGE,
|
||||
SkillStatusChangeTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
|
||||
SkillStatusChangeTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
|
||||
SkillStatusChangeTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
|
||||
SkillStatusChangeTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
|
||||
SkillStatusChangeTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
|
||||
SkillStatusChangeTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
|
||||
SkillStatusChangeTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
|
||||
SkillStatusChangeTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
|
||||
SkillStatusChangeTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
|
||||
SkillStatusChangeTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
|
||||
SkillStatusChangeTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
|
||||
|
||||
/* Status that don't have a skill associated */
|
||||
StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
|
||||
|
@ -1796,7 +1796,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
|
||||
// Moved here to prevent Suffragium from ending if skill fails
|
||||
#ifndef RENEWAL_CAST
|
||||
if (!(skill_get_castnodex(skill_id)&2))
|
||||
if (!(skill_get_castnodex(skill_id, skill_lv)&2))
|
||||
casttime = skill_castfix_sc(src, casttime);
|
||||
#else
|
||||
casttime = skill_vfcastfix(src, casttime, skill_id, skill_lv);
|
||||
@ -2013,7 +2013,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
|
||||
// Moved here to prevent Suffragium from ending if skill fails
|
||||
#ifndef RENEWAL_CAST
|
||||
if (!(skill_get_castnodex(skill_id)&2))
|
||||
if (!(skill_get_castnodex(skill_id, skill_lv)&2))
|
||||
casttime = skill_castfix_sc(src, casttime);
|
||||
#else
|
||||
casttime = skill_vfcastfix(src, casttime, skill_id, skill_lv );
|
||||
@ -2035,11 +2035,11 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
// }
|
||||
// }
|
||||
|
||||
ud->skill_id = skill_id;
|
||||
ud->skill_lv = skill_lv;
|
||||
ud->skillx = skill_x;
|
||||
ud->skilly = skill_y;
|
||||
ud->skilltarget = 0;
|
||||
ud->skill_id = skill_id;
|
||||
ud->skill_lv = skill_lv;
|
||||
ud->skillx = skill_x;
|
||||
ud->skilly = skill_y;
|
||||
ud->skilltarget = 0;
|
||||
|
||||
if( sc ) {
|
||||
// These 3 status do not stack, so it's efficient to use if-else
|
||||
|
Loading…
x
Reference in New Issue
Block a user