Merge branch 'master' into update/skills_Spirit_Handler

This commit is contained in:
Atemo 2024-03-25 20:27:12 +01:00
commit fc53e2e6dc
61 changed files with 89430 additions and 34197 deletions

View File

@ -2,6 +2,11 @@
#line 4 "scanner.c"
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4267 )
#endif
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
@ -2365,3 +2370,7 @@ void libconfig_yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
#line 192 "scanner.l"
#ifdef _MSC_VER
#pragma warning( pop )
#endif

View File

@ -134,3 +134,9 @@ min_shop_buy: 1
// Minimum sell price of items at a normal shop
// Officially items can be sold for 0 Zeny
min_shop_sell: 0
// Should items that reduce damage from element/race count all monster damage as physical? (Note 1)
// Officially "Asprika" (god item) reduces all monsters damage rather than just physical damage
// Shaman Hat on the other hand doesn't reduce monster damage at all (reduces magical damage in PVP)
// This only affects items with bonus3 bSubEle and bonus3 bSubRace.
cardfix_monster_physical: yes

View File

@ -240,6 +240,7 @@ Body:
bypass_stat_onclone: true
bypass_max_stat: true
macro_register: true
trade_unconditional: true
#all_permission: true
Footer:

View File

@ -1610,5 +1610,8 @@ map: 3@vrpop
// Depth biosphere 2nd floor
map: bl_depth2
// Fantasy Series Sonic Collaboration - Dr. Eggman's Secret Base
map: 1@vrsn
//------------------------- Clone Maps ---------------------------
//------------------------- Extra Maps ---------------------------

Binary file not shown.

View File

@ -1240,6 +1240,7 @@ t_garden
2@vrpop
3@vrpop
bl_depth2
1@vrsn
//======================================================================================
// - Other/Extra maps -

View File

@ -20587,16 +20587,7 @@ Body:
EquipLevelMin: 94
Script: |
bonus bMdef,5;
bonus3 bSubEle,Ele_Neutral,30,BF_SHORT;
bonus3 bSubEle,Ele_Water,30,BF_SHORT;
bonus3 bSubEle,Ele_Earth,30,BF_SHORT;
bonus3 bSubEle,Ele_Fire,30,BF_SHORT;
bonus3 bSubEle,Ele_Wind,30,BF_SHORT;
bonus3 bSubEle,Ele_Poison,30,BF_SHORT;
bonus3 bSubEle,Ele_Holy,30,BF_SHORT;
bonus3 bSubEle,Ele_Dark,30,BF_SHORT;
bonus3 bSubEle,Ele_Ghost,30,BF_SHORT;
bonus3 bSubEle,Ele_Undead,30,BF_SHORT;
bonus3 bSubEle,Ele_All,30,BF_WEAPON;
bonus bFlee,30;
skill "AL_TELEPORT",1;
bonus bUnbreakableGarment;

View File

@ -2049,21 +2049,21 @@ Body:
- Id: 200032
Group: Goal_Level
Name: The start of another adventure!
Condition: " BaseLevel == 100 "
Condition: " BaseLevel >= 100 "
Rewards:
Item: Rebeginer_Box_100
Score: 10
- Id: 200033
Group: Goal_Level
Name: With a new mind!(1)
Condition: " BaseLevel == 170 && (Class >= JOB_RUNE_KNIGHT && Class <= JOB_GUILLOTINE_CROSS_T) "
Condition: " BaseLevel >= 170 && (Class >= JOB_RUNE_KNIGHT && Class <= JOB_GUILLOTINE_CROSS_T) "
Rewards:
Item: Costume_Ticket
Score: 50
- Id: 200034
Group: Goal_Level
Name: With a new mind!(2)
Condition: " BaseLevel == 170 && (Class >= JOB_ROYAL_GUARD && Class <= JOB_SHADOW_CHASER_T) "
Condition: " BaseLevel >= 170 && (Class >= JOB_ROYAL_GUARD && Class <= JOB_SHADOW_CHASER_T) "
Rewards:
Item: Costume_Ticket
Score: 50

View File

@ -35943,14 +35943,14 @@ Body:
bonus bVariableCastrate,-5;
- Combos:
- Combo:
- aegis_300457 # 300457
- Grey_Icewind_Card
- aegis_300455 # 300455
Script: |
.@r_shoes = getequiprefinerycnt(EQI_SHOES);
bonus2 bAddSize,Size_Large,10+3*(.@r_shoes/2);
- Combos:
- Combo:
- aegis_300458 # 300458
- Icewind_Card
- aegis_300455 # 300455
Script: |
.@r_shoes = getequiprefinerycnt(EQI_SHOES);
@ -46814,7 +46814,8 @@ Body:
bonus2 bSkillAtk,"EM_ELEMENTAL_BUSTER_WIND",2*.@sum;
bonus2 bSkillAtk,"EM_ELEMENTAL_BUSTER_POISON",2*.@sum;
bonus2 bSkillAtk,"EM_ELEMENTAL_BUSTER_GROUND",2*.@sum;
if (getskilllv("EM_ELEMENTAL_BUSTER") > 0) {
.@class_ = geteleminfo(ELEMINFO_CLASS);
if (getskilllv("EM_ELEMENTAL_BUSTER") > 0 && .@class_ >= 20816 && .@class_ <= 20820) {
bonus4 bAutoSpellOnSkill,"EM_DIAMOND_STORM","EM_ELEMENTAL_BUSTER",getskilllv("EM_ELEMENTAL_BUSTER"),1000;
}
}
@ -46835,7 +46836,8 @@ Body:
bonus2 bSkillAtk,"EM_ELEMENTAL_BUSTER_WIND",2*.@sum;
bonus2 bSkillAtk,"EM_ELEMENTAL_BUSTER_POISON",2*.@sum;
bonus2 bSkillAtk,"EM_ELEMENTAL_BUSTER_GROUND",2*.@sum;
if (getskilllv("EM_ELEMENTAL_BUSTER") > 0 && geteleminfo(0) > 0) {
.@class_ = geteleminfo(ELEMINFO_CLASS);
if (getskilllv("EM_ELEMENTAL_BUSTER") > 0 && .@class_ >= 20816 && .@class_ <= 20820) {
bonus4 bAutoSpellOnSkill,"EM_TERRA_DRIVE","EM_ELEMENTAL_BUSTER",getskilllv("EM_ELEMENTAL_BUSTER"),1000;
}
}
@ -48064,3 +48066,639 @@ Body:
- Improve_Orb_Cri # 29539
Script: |
bonus2 bAddRace,RC_All,6;
- Combos:
- Combo:
- Signet_Of_Pow3 # 312984
- Star_Cluster_Of_Pow3 # 310676
Script: |
bonus2 bAddRace,RC_All,10;
bonus2 bAddRace,RC_Player_Human,-10;
bonus2 bAddRace,RC_Player_Doram,-10;
- Combos:
- Combo:
- Signet_Of_Pow4 # 312985
- Star_Cluster_Of_Pow3 # 310676
Script: |
bonus2 bAddRace,RC_All,15;
bonus2 bAddRace,RC_Player_Human,-15;
bonus2 bAddRace,RC_Player_Doram,-15;
- Combos:
- Combo:
- Signet_Of_Pow5 # 312986
- Star_Cluster_Of_Pow3 # 310676
Script: |
bonus2 bAddRace,RC_All,20;
bonus2 bAddRace,RC_Player_Human,-20;
bonus2 bAddRace,RC_Player_Doram,-20;
- Combos:
- Combo:
- Signet_Of_Con3 # 312989
- Star_Cluster_Of_Con3 # 310682
Script: |
bonus2 bAddRace,RC_All,10;
bonus2 bAddRace,RC_Player_Human,-10;
bonus2 bAddRace,RC_Player_Doram,-10;
- Combos:
- Combo:
- Signet_Of_Con4 # 312990
- Star_Cluster_Of_Con3 # 310682
Script: |
bonus2 bAddRace,RC_All,15;
bonus2 bAddRace,RC_Player_Human,-15;
bonus2 bAddRace,RC_Player_Doram,-15;
- Combos:
- Combo:
- Signet_Of_Con5 # 312991
- Star_Cluster_Of_Con3 # 310682
Script: |
bonus2 bAddRace,RC_All,20;
bonus2 bAddRace,RC_Player_Human,-20;
bonus2 bAddRace,RC_Player_Doram,-20;
- Combos:
- Combo:
- Signet_Of_Spl3 # 312994
- Star_Cluster_Of_Spl3 # 310688
Script: |
bonus2 bMagicAddRace,RC_All,10;
bonus2 bMagicAddRace,RC_Player_Human,-10;
bonus2 bMagicAddRace,RC_Player_Doram,-10;
- Combos:
- Combo:
- Signet_Of_Spl4 # 312995
- Star_Cluster_Of_Spl3 # 310688
Script: |
bonus2 bMagicAddRace,RC_All,15;
bonus2 bMagicAddRace,RC_Player_Human,-15;
bonus2 bMagicAddRace,RC_Player_Doram,-15;
- Combos:
- Combo:
- Signet_Of_Spl5 # 312996
- Star_Cluster_Of_Spl3 # 310688
Script: |
bonus2 bMagicAddRace,RC_All,20;
bonus2 bMagicAddRace,RC_Player_Human,-20;
bonus2 bMagicAddRace,RC_Player_Doram,-20;
- Combos:
- Combo:
- Signet_Of_Sta3 # 312999
- Star_Cluster_Of_Sta3 # 310679
Script: |
bonus bMaxHPrate,5;
- Combos:
- Combo:
- Signet_Of_Sta4 # 313000
- Star_Cluster_Of_Sta3 # 310679
Script: |
bonus bMaxHPrate,7;
- Combos:
- Combo:
- Signet_Of_Sta5 # 313001
- Star_Cluster_Of_Sta3 # 310679
Script: |
bonus bMaxHPrate,10;
- Combos:
- Combo:
- Signet_Of_Crt3 # 313004
- Star_Cluster_Of_Crt3 # 310685
Script: |
bonus2 bAddRace,RC_All,10;
bonus2 bAddRace,RC_Player_Human,-10;
bonus2 bAddRace,RC_Player_Doram,-10;
- Combos:
- Combo:
- Signet_Of_Crt4 # 313005
- Star_Cluster_Of_Crt3 # 310685
Script: |
bonus2 bAddRace,RC_All,15;
bonus2 bAddRace,RC_Player_Human,-15;
bonus2 bAddRace,RC_Player_Doram,-15;
- Combos:
- Combo:
- Signet_Of_Crt5 # 313006
- Star_Cluster_Of_Crt3 # 310685
Script: |
bonus2 bAddRace,RC_All,20;
bonus2 bAddRace,RC_Player_Human,-20;
bonus2 bAddRace,RC_Player_Doram,-20;
- Combos:
- Combo:
- Signet_Of_Wis3 # 313009
- Star_Cluster_Of_Wis3 # 310691
Script: |
bonus bMaxSPrate,5;
- Combos:
- Combo:
- Signet_Of_Wis4 # 313010
- Star_Cluster_Of_Wis3 # 310691
Script: |
bonus bMaxSPrate,7;
- Combos:
- Combo:
- Signet_Of_Wis5 # 313011
- Star_Cluster_Of_Wis3 # 310691
Script: |
bonus bMaxSPrate,10;
- Combos:
- Combo:
- Life_of_Spring_Pow # 313012
- Star_Armor_Of_Pow # 450169
Script: |
bonus2 bAddEle,Ele_All,2;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus2 bAddEle,Ele_All,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Spring_Sta # 313013
- Star_Armor_Of_Sta # 450170
Script: |
.@r_armor = getequiprefinerycnt(EQI_ARMOR);
bonus bMaxHPrate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bMaxHPrate,(.@r_armor/2);
bonus bRes,20*(.@r_armor/2);
}
- Combos:
- Combo:
- Life_of_Spring_Crt # 313014
- Star_Suit_Of_Crt # 450172
Script: |
bonus bCritAtkRate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bCritAtkRate,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Summer_Con # 313015
- Star_Suit_Of_Con # 450171
Script: |
bonus2 bAddEle,Ele_All,2;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus2 bAddEle,Ele_All,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Summer_Sta # 313016
- Star_Armor_Of_Sta # 450170
Script: |
.@r_armor = getequiprefinerycnt(EQI_ARMOR);
bonus bMaxHPrate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bMaxHPrate,(.@r_armor/2);
bonus bRes,20*(.@r_armor/2);
}
- Combos:
- Combo:
- Life_of_Summer_Crt # 313017
- Star_Suit_Of_Crt # 450172
Script: |
bonus bCritAtkRate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bCritAtkRate,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Autumn_Spl # 313018
- Star_Robe_Of_Spl # 450173
Script: |
bonus2 bMagicAddEle,Ele_All,2;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus2 bMagicAddEle,Ele_All,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Autumn_Sta # 313019
- Star_Armor_Of_Sta # 450170
Script: |
.@r_armor = getequiprefinerycnt(EQI_ARMOR);
bonus bMaxHPrate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bMaxHPrate,(.@r_armor/2);
bonus bRes,20*(.@r_armor/2);
}
- Combos:
- Combo:
- Life_of_Autumn_Wis # 313020
- Star_Robe_Of_Wis # 450174
Script: |
.@r_armor = getequiprefinerycnt(EQI_ARMOR);
bonus bDelayrate,-3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bDelayrate,-2*(.@r_armor/2);
bonus bMaxSPrate,(.@r_armor/2);
}
- Combos:
- Combo:
- Life_of_Winter_Pow # 313021
- Star_Armor_Of_Pow # 450169
Script: |
bonus bCritAtkRate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bCritAtkRate,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Winter_Con # 313022
- Star_Suit_Of_Con # 450171
Script: |
bonus bCritAtkRate,3;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus bCritAtkRate,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Life_of_Winter_Crt # 313023
- Star_Suit_Of_Crt # 450172
Script: |
bonus2 bAddEle,Ele_All,2;
if (getenchantgrade(EQI_ARMOR)>=ENCHANTGRADE_A) {
bonus2 bAddEle,Ele_All,3*(getequiprefinerycnt(EQI_ARMOR)/2);
}
- Combos:
- Combo:
- Star_Cluster_Of_Str1 # 313024
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,3;
bonus2 bAddClass,Class_Boss,3;
- Combos:
- Combo:
- Star_Cluster_Of_Str2 # 313025
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,6;
bonus2 bAddClass,Class_Boss,6;
- Combos:
- Combo:
- Star_Cluster_Of_Str3 # 313026
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,9;
bonus2 bAddClass,Class_Boss,9;
- Combos:
- Combo:
- Star_Cluster_Of_Str4 # 313027
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,12;
bonus2 bAddClass,Class_Boss,12;
- Combos:
- Combo:
- Star_Cluster_Of_Str5 # 313028
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,15;
bonus2 bAddClass,Class_Boss,15;
- Combos:
- Combo:
- Star_Cluster_Of_Luk1 # 313029
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,3;
bonus2 bAddClass,Class_Boss,3;
- Combos:
- Combo:
- Star_Cluster_Of_Luk2 # 313030
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,6;
bonus2 bAddClass,Class_Boss,6;
- Combos:
- Combo:
- Star_Cluster_Of_Luk3 # 313031
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,9;
bonus2 bAddClass,Class_Boss,9;
- Combos:
- Combo:
- Star_Cluster_Of_Luk4 # 313032
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,12;
bonus2 bAddClass,Class_Boss,12;
- Combos:
- Combo:
- Star_Cluster_Of_Luk5 # 313033
- Token_Of_Life # 312981
Script: |
bonus2 bAddClass,Class_Normal,15;
bonus2 bAddClass,Class_Boss,15;
- Combos:
- Combo:
- Star_Cluster_Of_Int1 # 313034
- Token_Of_Life # 312981
Script: |
bonus2 bMagicAddClass,Class_Normal,3;
bonus2 bMagicAddClass,Class_Boss,3;
- Combos:
- Combo:
- Star_Cluster_Of_Int2 # 313035
- Token_Of_Life # 312981
Script: |
bonus2 bMagicAddClass,Class_Normal,6;
bonus2 bMagicAddClass,Class_Boss,6;
- Combos:
- Combo:
- Star_Cluster_Of_Int3 # 313036
- Token_Of_Life # 312981
Script: |
bonus2 bMagicAddClass,Class_Normal,9;
bonus2 bMagicAddClass,Class_Boss,9;
- Combos:
- Combo:
- Star_Cluster_Of_Int4 # 313037
- Token_Of_Life # 312981
Script: |
bonus2 bMagicAddClass,Class_Normal,12;
bonus2 bMagicAddClass,Class_Boss,12;
- Combos:
- Combo:
- Star_Cluster_Of_Int5 # 313038
- Token_Of_Life # 312981
Script: |
bonus2 bMagicAddClass,Class_Normal,15;
bonus2 bMagicAddClass,Class_Boss,15;
- Combos:
- Combo:
- Star_Cluster_Of_Res1 # 313039
- Token_Of_Life # 312981
Script: |
bonus bMaxHPrate,1;
bonus bMaxSPrate,1;
- Combos:
- Combo:
- Star_Cluster_Of_Res2 # 313040
- Token_Of_Life # 312981
Script: |
bonus bMaxHPrate,2;
bonus bMaxSPrate,2;
- Combos:
- Combo:
- Star_Cluster_Of_Res3 # 313041
- Token_Of_Life # 312981
Script: |
bonus bMaxHPrate,3;
bonus bMaxSPrate,3;
- Combos:
- Combo:
- Star_Cluster_Of_Res4 # 313042
- Token_Of_Life # 312981
Script: |
bonus bMaxHPrate,4;
bonus bMaxSPrate,4;
- Combos:
- Combo:
- Star_Cluster_Of_Res5 # 313043
- Token_Of_Life # 312981
Script: |
bonus bMaxHPrate,5;
bonus bMaxSPrate,5;
- Combos:
- Combo:
- aegis_313059 # 313059
- Runeknight_Top3 # 310881
Script: |
bonus2 bAddSize,Size_All,3*(getskilllv("DK_TWOHANDDEF")/2);
- Combos:
- Combo:
- aegis_313059 # 313059
- Runeknight_Middle3 # 310882
Script: |
bonus2 bSkillAtk,"DK_HACKANDSLASHER",10;
- Combos:
- Combo:
- aegis_313059 # 313059
- Runeknight_Bottom3 # 310883
Script: |
bonus bCRate,3;
bonus2 bSkillAtk,"DK_STORMSLASH",15;
- Combos:
- Combo:
- aegis_313060 # 313060
- Royalguard_Top3 # 310887
Script: |
bonus2 bSkillAtk,"IG_CROSS_RAIN",15;
- Combos:
- Combo:
- aegis_313060 # 313060
- Royalguard_Middle3 # 310888
Script: |
bonus2 bMagicAddSize,Size_All,10;
- Combos:
- Combo:
- aegis_313060 # 313060
- Royalguard_Bottom3 # 310889
Script: |
bonus2 bMagicAddEle,Ele_All,3*(getskilllv("IG_SHIELD_MASTERY")/2);
- Combos:
- Combo:
- aegis_313061 # 313061
- aegis_311463 # 311463
Script: |
bonus2 bSkillAtk,"NW_THE_VIGILANTE_AT_NIGHT",10;
- Combos:
- Combo:
- aegis_313061 # 313061
- aegis_311464 # 311464
Script: |
bonus2 bSkillAtk,"NW_SPIRAL_SHOOTING",15;
- Combos:
- Combo:
- aegis_313061 # 313061
- aegis_311465 # 311465
Script: |
bonus2 bSkillAtk,"NW_MAGAZINE_FOR_ONE",10;
- Combos:
- Combo:
- FuriousCirclet_WH # 400608
- StormBow_Furious # 700100
Script: |
bonus2 bSkillAtk,"WH_GALESTORM",15;
- Combos:
- Combo:
- FuriousCirclet_WH # 400608
- TornadoBow_Furious # 700101
Script: |
bonus2 bSkillAtk,"WH_CRESCIVE_BOLT",15;
- Combos:
- Combo:
- FuriousCirclet_CD # 400609
- SaintBook_Furious # 540086
Script: |
bonus2 bSkillAtk,"CD_PETITIO",15;
- Combos:
- Combo:
- FuriousCirclet_CD # 400609
- SaintWand_Furious # 550141
Script: |
bonus2 bSkillAtk,"CD_FRAMEN",15;
- Combos:
- Combo:
- FuriousCirclet_SKE # 400610
- SunBook_Furious # 540087
Script: |
bonus2 bSkillAtk,"SKE_NOON_BLAST",15;
- Combos:
- Combo:
- FuriousCirclet_SKE # 400610
- MoonBook_Furious # 540088
Script: |
bonus2 bSkillAtk,"SKE_MIDNIGHT_KICK",15;
- Combos:
- Combo:
- Signet_Of_Spring # 490483
- Circul_Of_Life_Spring # 480349
Script: |
.@val = 5+3*(getequiprefinerycnt(EQI_GARMENT)/2);
bonus2 bAddRace,RC_All,.@val;
bonus2 bAddRace,RC_Player_Human,-.@val;
bonus2 bAddRace,RC_Player_Doram,-.@val;
bonus bDelayrate,-10;
- Combos:
- Combo:
- Signet_Of_Summer # 490484
- Circul_Of_Life_Summer # 480350
Script: |
.@val = 5+3*(getequiprefinerycnt(EQI_GARMENT)/2);
bonus2 bAddRace,RC_All,.@val;
bonus2 bAddRace,RC_Player_Human,-.@val;
bonus2 bAddRace,RC_Player_Doram,-.@val;
bonus bDelayrate,-10;
- Combos:
- Combo:
- Signet_Of_Autumn # 490485
- Circul_Of_Life_Autumn # 480351
Script: |
.@val = 5+3*(getequiprefinerycnt(EQI_GARMENT)/2);
bonus2 bMagicAddRace,RC_All,.@val;
bonus2 bMagicAddRace,RC_Player_Human,-.@val;
bonus2 bMagicAddRace,RC_Player_Doram,-.@val;
bonus bDelayrate,-10;
- Combos:
- Combo:
- Signet_Of_Winter # 490486
- Circul_Of_Life_Winter # 480352
Script: |
.@val = 5+3*(getequiprefinerycnt(EQI_GARMENT)/2);
bonus2 bAddRace,RC_All,.@val;
bonus2 bAddRace,RC_Player_Human,-.@val;
bonus2 bAddRace,RC_Player_Doram,-.@val;
bonus bDelayrate,-10;
- Combos:
- Combo:
- SaintBook_Furious # 540086
- FuriousBoots # 470265
Script: |
autobonus "{ .@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES); bonus2 bSkillAtk,\"AB_DUPLELIGHT_MELEE\",(15*.@sum); bonus2 bSkillAtk,\"AB_DUPLELIGHT_MAGIC\",(15*.@sum); }",70,10000,BF_WEAPON;
- Combos:
- Combo:
- SunBook_Furious # 540087
- FuriousBoots # 470265
Script: |
bonus bDelayrate,-10;
- Combos:
- Combo:
- MoonBook_Furious # 540088
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus2 bSkillAtk,"SKE_MIDNIGHT_KICK",15;
bonus2 bSkillAtk,"SKE_DAWN_BREAK",.@sum*2;
- Combos:
- Combo:
- SaintWand_Furious # 550141
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus bDelayrate,-10;
bonus2 bSkillAtk,"CD_FRAMEN",.@sum;
- Combos:
- Combo:
- StormBow_Furious # 700100
- FuriousBoots # 470265
Script: |
bonus2 bSkillUseSP,"WH_GALESTORM",20;
- Combos:
- Combo:
- TornadoBow_Furious # 700101
- FuriousBoots # 470265
Script: |
bonus bDelayrate,-10;
- Combos:
- Combo:
- FuriousCirclet_DK # 400628
- Slayer_Furious # 600059
Script: |
bonus2 bSkillAtk,"DK_HACKANDSLASHER",15;
- Combos:
- Combo:
- FuriousCirclet_DK # 400628
- Trident_Furious # 630045
Script: |
bonus2 bSkillAtk,"DK_MADNESS_CRUSHER",15;
- Combos:
- Combo:
- FuriousCirclet_ABC # 400629
- Demonius_Furious # 510150
Script: |
bonus2 bSkillAtk,"ABC_DEFT_STAB",15;
- Combos:
- Combo:
- FuriousCirclet_ABC # 400629
- Demonsword_Furious # 510151
Script: |
bonus2 bSkillAtk,"ABC_ABYSS_SQUARE",15;
- Combos:
- Combo:
- FuriousCirclet_SH # 400630
- Foxtail_Furious # 550143
Script: |
bonus2 bSkillAtk,"SH_HOGOGONG_STRIKE",15;
- Combos:
- Combo:
- FuriousCirclet_SH # 400630
- Setaria_Furious # 550144
Script: |
bonus2 bSkillAtk,"SH_HYUN_ROKS_BREEZE",15;
- Combos:
- Combo:
- Demonius_Furious # 510150
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus2 bSkillAtk,"ABC_DEFT_STAB",.@sum;
- Combos:
- Combo:
- Demonsword_Furious # 510151
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus2 bSkillAtk,"ABC_ABYSS_SQUARE",.@sum;
- Combos:
- Combo:
- Foxtail_Furious # 550143
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus2 bSkillAtk,"SH_HOGOGONG_STRIKE",.@sum;
- Combos:
- Combo:
- Setaria_Furious # 550144
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus2 bSkillAtk,"SH_HYUN_ROKS_BREEZE",.@sum;
- Combos:
- Combo:
- Slayer_Furious # 600059
- FuriousBoots # 470265
Script: |
bonus2 bSkillAtk,"DK_HACKANDSLASHER",15;
- Combos:
- Combo:
- Trident_Furious # 630045
- FuriousBoots # 470265
Script: |
.@sum = getequiprefinerycnt(EQI_HAND_R)+getequiprefinerycnt(EQI_SHOES);
bonus2 bSkillAtk,"DK_MADNESS_CRUSHER",.@sum;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
# This file is a part of rAthena.
# Copyright(C) 2022 rAthena Development Team
# Copyright(C) 2024 rAthena Development Team
# https://rathena.org - https://github.com/rathena
#
# This program is free software: you can redistribute it and/or modify
@ -159,77 +159,153 @@ Body:
RentalHours: 1
- Group: 9
Items:
- Item: Red_Potion
Amount: 10
- Item: Red_Potion
Amount: 5
- Item: Red_Potion
- Item: Red_Potion
Amount: 3
RentalHours: 1
- Group: 10
Items:
- Item: Guard_
- Item: Guard_
- Item: Guard_
- Group: 11
Items:
- Item: Orange_Potion
Amount: 800
- Item: Boost_Armor_Box
- Item: Minus_Status_Box_
Groups:
- Group: 0
Items:
- Item: Atker_Plate
- Item: Atker_Manteau
- Item: Atker_Greave
- Item: Atker_Ring
- Item: Boost_Up_1
Amount: 3
- Item: Minus_Str
Amount: 6
- Group: 1
Items:
- Item: Ran_Suits
- Item: Ran_Manteau
- Item: Ran_Boots
- Item: Ran_Brooch
- Item: Boost_Up_1
Amount: 3
- Item: Minus_Agi
Amount: 6
- Group: 2
Items:
- Item: Ele_Robe
- Item: Ele_Muffler
- Item: Ele_Shoes
- Item: Ele_Earing
- Item: Boost_Up_1
Amount: 3
- Item: Minus_Vit
Amount: 6
- Group: 3
Items:
- Item: Defn_Robe
- Item: Defn_Muffler
- Item: Defn_Shoes
- Item: Defn_Earing
- Item: Boost_Up_1
Amount: 3
- Item: Special_Coin_Pack
- Item: Minus_Int
Amount: 6
- Group: 4
Items:
- Item: Minus_Dex
Amount: 6
- Group: 5
Items:
- Item: Minus_Luk
Amount: 6
- Group: 6
Items:
- Item: Minus_Str
- Item: Minus_Agi
- Item: Minus_Vit
- Item: Minus_Int
- Item: Minus_Dex
- Item: Minus_Luk
- Item: Alchemist_Box_
Groups:
- Group: 0
Items:
- Item: EP17_1_EVT39
Amount: 3
- Item: EP17_1_EVT02
Amount: 18
- Item: Fire_Bottle
Amount: 50
- Group: 1
Items:
- Item: BarMealTicket
Amount: 20
- Item: Acid_Bottle
Amount: 50
- Group: 2
Items:
- Item: Ep18_Amethyst_Fragment
Amount: 20
- Item: MenEater_Plant_Bottle
Amount: 50
- Group: 3
Items:
- Item: Ep19_Snow_Flower
Amount: 20
- Item: Coating_Bottle
Amount: 50
- Group: 4
Items:
- Item: Mini_Bottle
Amount: 50
- Item: FullPene_Select_Box
Groups:
- Group: 0
Items:
- Item: FullPene_Earring_Box
- Group: 1
Items:
- Item: FullPene_Pendant_Box
- Group: 2
Items:
- Item: FullPene_Armor_Box
- Group: 3
Items:
- Item: FullPene_Shoes_Box
- Item: FullTemp_Select_Box
Groups:
- Group: 0
Items:
- Item: FullTemp_Earring_Box
- Group: 1
Items:
- Item: FullTemp_Pendant_Box
- Group: 2
Items:
- Item: FullTemp_Armor_Box
- Group: 3
Items:
- Item: FullTemp_Shoes_Box
- Item: Durable_Select_Box
Groups:
- Group: 0
Items:
- Item: Durable_Weapon_Box
- Group: 1
Items:
- Item: Durable_Shield_Box
- Item: Clever_Select_Box
Groups:
- Group: 0
Items:
- Item: Clever_Weapon_Box
- Group: 1
Items:
- Item: Clever_Shield_Box
- Item: OS_Helm_Box_
Groups:
- Group: 0
Items:
- Item: Ignis_CapK
- Group: 1
Items:
- Item: Phantom_Cap
- Group: 2
Items:
- Item: Stripe_Hat
- Group: 3
Items:
- Item: Clock_Casket_RD
- Group: 4
Items:
- Item: Large_Sorcerer_Crown
- Group: 5
Items:
- Item: Scorpio_Diadem_K
- Group: 6
Items:
- Item: Sagittarius_DiademK
- Item: Shadow_R_M_Box_
Groups:
- Group: 0
Items:
- Item: Class_Sha_R_M_Melee
- Group: 1
Items:
- Item: Class_Sha_R_M_Magic
- Group: 2
Items:
- Item: Skill_Sha_R_M_Melee
- Group: 3
Items:
- Item: Skill_Sha_R_M_Magic
- Item: Metal_W_Box
Groups:
- Group: 0
@ -326,206 +402,581 @@ Body:
- Group: 3
Items:
- Item: C_School_Bag_PU
- Item: aegis_101470
- Item: Special_Coin_Pack
Groups:
- Group: 0
Items:
- Item: Minus_Str
Amount: 6
- Item: EP17_1_EVT39
Amount: 3
- Item: EP17_1_EVT02
Amount: 18
- Group: 1
Items:
- Item: Minus_Agi
Amount: 6
- Item: BarMealTicket
Amount: 20
- Group: 2
Items:
- Item: Minus_Vit
Amount: 6
- Item: Ep18_Amethyst_Fragment
Amount: 20
- Group: 3
Items:
- Item: Minus_Int
Amount: 6
- Item: Ep19_Snow_Flower
Amount: 20
- Item: Boost_Armor_Box
Groups:
- Group: 0
Items:
- Item: Atker_Plate
- Item: Atker_Manteau
- Item: Atker_Greave
- Item: Atker_Ring
- Item: Boost_Up_1
Amount: 3
- Group: 1
Items:
- Item: Ran_Suits
- Item: Ran_Manteau
- Item: Ran_Boots
- Item: Ran_Brooch
- Item: Boost_Up_1
Amount: 3
- Group: 2
Items:
- Item: Ele_Robe
- Item: Ele_Muffler
- Item: Ele_Shoes
- Item: Ele_Earing
- Item: Boost_Up_1
Amount: 3
- Group: 3
Items:
- Item: Defn_Robe
- Item: Defn_Muffler
- Item: Defn_Shoes
- Item: Defn_Earing
- Item: Boost_Up_1
Amount: 3
- Item: AllMighty_Select_Box
Groups:
- Group: 0
Items:
- Item: AllMighty_Earring_Box
- Group: 1
Items:
- Item: AllMighty_Pendant_Box
- Item: TrueGem_Select_Box
Groups:
- Group: 0
Items:
- Item: TrueGem_Earring_Box
- Group: 1
Items:
- Item: TrueGem_Pendant_Box
- Group: 2
Items:
- Item: TrueGem_Shoes_Box
- Group: 3
Items:
- Item: TrueGem_Armor_Box
- Item: PerfectSize_Select_Box
Groups:
- Group: 0
Items:
- Item: PerfectSize_Weapon_Box
- Group: 1
Items:
- Item: PerfectSize_Armor_Box
- Item: Mammoth_Select_Box
Groups:
- Group: 0
Items:
- Item: Mammoth_Earring_Box
- Group: 1
Items:
- Item: Mammoth_Pendant_Box
- Group: 2
Items:
- Item: Mammoth_Armor_Box
- Group: 3
Items:
- Item: Mammoth_Shoes_Box
- Item: SpellCaster_Select_Box
Groups:
- Group: 0
Items:
- Item: SpellCaster_Earring_Box
- Group: 1
Items:
- Item: SpellCaster_Pendant_Box
- Group: 2
Items:
- Item: SpellCaster_Armor_Box
- Group: 3
Items:
- Item: SpellCaster_Shoes_Box
- Item: Absorb_Select_Box
Groups:
- Group: 0
Items:
- Item: Absorb_Weapon_Box
- Group: 1
Items:
- Item: Absorb_Shield_Box
- Item: R_Bearers_Select_Box
Groups:
- Group: 0
Items:
- Item: R_Bearers_Earring_Box
- Group: 1
Items:
- Item: R_Bearers_Pendant_Box
- Group: 2
Items:
- Item: R_Bearers_Armor_Box
- Group: 3
Items:
- Item: R_Bearers_Shoes_Box
- Item: Hasty_Select_Box
Groups:
- Group: 0
Items:
- Item: Hasty_Weapon_Box
- Group: 1
Items:
- Item: Hasty_Shield_Box
- Item: MAutoSpell_Select_Box
Groups:
- Group: 0
Items:
- Item: MAutoSpell_Earring_Box
- Group: 1
Items:
- Item: MAutoSpell_Pendant_Box
- Group: 2
Items:
- Item: MAutoSpell_Armor_Box
- Group: 3
Items:
- Item: MAutoSpell_Shoes_Box
- Item: Infinity_Select_Box
Groups:
- Group: 0
Items:
- Item: Infinity_Weapon_Box
- Group: 1
Items:
- Item: Infinity_Shield_Box
- Item: EXP_Select_Box
Groups:
- Group: 0
Items:
- Item: EXP_Weapon_Box
- Group: 1
Items:
- Item: EXP_Shield_Box
- Item: M_Blitz_Select_Box
Groups:
- Group: 0
Items:
- Item: M_Blitz_Weapon_Box
- Group: 1
Items:
- Item: M_Blitz_Shield_Box
- Item: GoodnEvil_Circlet_Box
Groups:
- Group: 0
Items:
- Item: GoodnEvil_Circlet_NW
- Group: 1
Items:
- Item: GoodnEvil_Circlet_NW2
- Group: 2
Items:
- Item: GoodnEvil_Circlet_NW3
- Group: 3
Items:
- Item: GoodnEvil_Circlet_NW4
- Group: 4
Items:
- Item: Minus_Dex
Amount: 6
- Item: GoodnEvil_Circlet_NW5
- Item: Hero_Weapon_Up_S_Box
Groups:
- Group: 0
Items:
- Item: Hero_Weapon_Up_Box_1
- Group: 1
Items:
- Item: Hero_Weapon_Up_Box_2
- Group: 2
Items:
- Item: Hero_Weapon_Up_Box_3
- Group: 3
Items:
- Item: Hero_Weapon_Up_Box_4
- Group: 4
Items:
- Item: Hero_Weapon_Up_Box_5
- Group: 5
Items:
- Item: Minus_Luk
Amount: 6
- Group: 6
Items:
- Item: Minus_Str
- Item: Minus_Agi
- Item: Minus_Vit
- Item: Minus_Int
- Item: Minus_Dex
- Item: Minus_Luk
- Item: aegis_101471
- Item: Hero_Weapon_Up_Box_6
- Item: Hero_Weapon_Hammer_S
Groups:
- Group: 0
Items:
- Item: Fire_Bottle
Amount: 50
- Item: Hero_Weapon_Hammer_1
- Group: 1
Items:
- Item: Acid_Bottle
Amount: 50
- Item: Hero_Weapon_Hammer_2
- Group: 2
Items:
- Item: MenEater_Plant_Bottle
Amount: 50
- Item: Hero_Weapon_Hammer_3
- Group: 3
Items:
- Item: Coating_Bottle
Amount: 50
- Item: Hero_Weapon_Hammer_4
- Group: 4
Items:
- Item: Mini_Bottle
Amount: 50
- Item: aegis_101542
Groups:
- Group: 0
Items:
- Item: aegis_101543
- Group: 1
Items:
- Item: aegis_101544
- Group: 2
Items:
- Item: aegis_101545
- Group: 3
Items:
- Item: aegis_101546
- Item: aegis_101547
Groups:
- Group: 0
Items:
- Item: aegis_101548
- Group: 1
Items:
- Item: aegis_101549
- Group: 2
Items:
- Item: aegis_101550
- Group: 3
Items:
- Item: aegis_101551
- Item: aegis_101552
Groups:
- Group: 0
Items:
- Item: aegis_101553
- Group: 1
Items:
- Item: aegis_101554
- Item: aegis_101555
Groups:
- Group: 0
Items:
- Item: aegis_101556
- Group: 1
Items:
- Item: aegis_101557
- Item: aegis_101563
Groups:
- Group: 0
Items:
- Item: Ignis_CapK
- Group: 1
Items:
- Item: Phantom_Cap
- Group: 2
Items:
- Item: Stripe_Hat
- Group: 3
Items:
- Item: Clock_Casket_RD
- Group: 4
Items:
- Item: Large_Sorcerer_Crown
- Item: Hero_Weapon_Hammer_5
- Group: 5
Items:
- Item: Scorpio_Diadem_K
- Group: 6
Items:
- Item: Sagittarius_DiademK
- Item: aegis_101565
- Item: Hero_Weapon_Hammer_6
- Item: aegis_102215
Groups:
- Group: 0
Items:
- Item: Class_Sha_R_M_Melee
- Item: Bio_Weapon_Refine_Cube
- Group: 1
Items:
- Item: Class_Sha_R_M_Magic
- Item: Old_Refine_Cube
- Group: 2
Items:
- Item: Skill_Sha_R_M_Melee
- Group: 3
Items:
- Item: Skill_Sha_R_M_Magic
- Item: aegis_101654
- Item: Geffen_Refine_Cube
- Item: aegis_102216
Groups:
- Group: 0
Items:
- Item: aegis_101655
- Item: Bio_Helm_Refine_Cube
- Group: 1
Items:
- Item: aegis_101656
- Item: aegis_101657
Groups:
- Group: 0
Items:
- Item: aegis_101658
- Group: 1
Items:
- Item: aegis_101659
- Item: Circlet_Refine_Cube
- Group: 2
Items:
- Item: aegis_101660
- Item: Auto_Armor_Refine_Cube
- Group: 3
Items:
- Item: aegis_101661
- Item: aegis_101662
- Item: Racecap_Refine_Cube
- Group: 4
Items:
- Item: OS_Weapon_Refine_Cube
- Group: 5
Items:
- Item: Temporal_Refine_Cube
- Item: Hero_Weapon_S_Box_1
Groups:
- Group: 0
Items:
- Item: aegis_101663
- Item: Royal_Bow_K
Refine: 11
- Group: 1
Items:
- Item: aegis_101664
- Item: aegis_101727
Groups:
- Group: 0
Items:
- Item: aegis_101717
- Group: 1
Items:
- Item: aegis_101718
- Item: Shadow_Staff_K
Refine: 11
- Group: 2
Items:
- Item: aegis_101719
- Item: Iron_Nail_K
Refine: 11
- Group: 3
Items:
- Item: aegis_101720
- Item: aegis_101728
- Item: Blue_Crystal_Staff
Refine: 11
- Group: 4
Items:
- Item: Freezing_Rod
Refine: 11
- Group: 5
Items:
- Item: Ancient_Hero_Boots
Refine: 11
- Item: Hero_Weapon_S_Box_2
Groups:
- Group: 0
Items:
- Item: aegis_101721
- Item: Sword_Of_Bluefire
Refine: 11
- Group: 1
Items:
- Item: aegis_101722
- Item: Iron_Staff
Refine: 11
- Group: 2
Items:
- Item: aegis_101723
- Item: Oriental_Sword
Refine: 11
- Group: 3
Items:
- Item: aegis_101724
- Item: aegis_101729
- Item: Fog_Dew_Sword
Refine: 11
- Group: 4
Items:
- Item: Sharp_Wind_Sword
Refine: 11
- Group: 5
Items:
- Item: Humma_Clear
Refine: 11
- Item: Hero_Weapon_S_Box_3
Groups:
- Group: 0
Items:
- Item: aegis_101725
- Item: Narcis_Bow
Refine: 11
- Group: 1
Items:
- Item: aegis_101726
- Item: Magic_Sword
Refine: 11
- Group: 2
Items:
- Item: Avenger
Refine: 11
- Group: 3
Items:
- Item: Undine_Spear_K
Refine: 11
- Group: 4
Items:
- Item: Demon_Hunting_Bible_K
Refine: 11
- Group: 5
Items:
- Item: Shiver_Katar_K
Refine: 11
- Item: Hero_Weapon_S_Box_4
Groups:
- Group: 0
Items:
- Item: OneSkyOneSun
Refine: 11
- Group: 1
Items:
- Item: SoulWeight
Refine: 11
- Group: 2
Items:
- Item: MeawFoxtail
Refine: 11
- Group: 3
Items:
- Item: Freedom_Stick
Refine: 11
- Group: 4
Items:
- Item: Blessed_Knife
Refine: 11
- Item: Hero_Weapon_S_Box_5
Groups:
- Group: 0
Items:
- Item: Dragonic_Slayer
Refine: 11
- Group: 1
Items:
- Item: Light_Blade
Refine: 11
- Group: 2
Items:
- Item: Slate_Sword
Refine: 11
- Group: 3
Items:
- Item: Trumpet_Shell_K
Refine: 11
- Group: 4
Items:
- Item: Barb_Wire_K
Refine: 11
- Group: 5
Items:
- Item: Meteor_Striker
Refine: 11
- Item: Hero_Weapon_S_Box_6
Groups:
- Group: 0
Items:
- Item: Saint_Hall
Refine: 11
- Group: 1
Items:
- Item: Ray_Knuckle
Refine: 11
- Group: 2
Items:
- Item: Blade_Katar
Refine: 11
- Group: 3
Items:
- Item: Fatalist
Refine: 11
- Group: 4
Items:
- Item: Scalet_Dragon_L_Bow
Refine: 11
- Item: Hero_Weapon_S_Box_7
Groups:
- Group: 0
Items:
- Item: Crimson_Rose
Refine: 11
- Group: 1
Items:
- Item: Master_Soul_Rifle
Refine: 11
- Group: 2
Items:
- Item: Demon_S_Shot
Refine: 11
- Group: 3
Items:
- Item: Golden_L_Launcher
Refine: 11
- Group: 4
Items:
- Item: The_Black_Gatling
Refine: 11
- Item: 2023_Spring_Select
Groups:
- Group: 0
Items:
- Item: C_Lop_Bunny_Cloak
- Group: 1
Items:
- Item: C_Heart_Chiffon_Rabbit
- Group: 2
Items:
- Item: C_Teaparty_Wonderland
- Group: 3
Items:
- Item: C_Chocolat_Rabbit_Hair
- Item: RO_Concert_Scroll2
Groups:
- Group: 0
Items:
- Item: C_Headset_OST
- Group: 1
Items:
- Item: C_Music_Decoration
- Group: 2
Items:
- Item: C_Whistle
- Item: 21th_Costume_Select
Groups:
- Group: 0
Items:
- Item: C_Ocean_Color_Long
- Group: 1
Items:
- Item: C_Aqua_Fin_Decoration
- Group: 2
Items:
- Item: C_Sailor_Cap
- Item: Cinnamon_Costume_Box
Groups:
- Group: 0
Items:
- Item: C_Cinnamon2
- Group: 1
Items:
- Item: C_Cinnamon
- Group: 2
Items:
- Item: C_JP_EV16
- Group: 3
Items:
- Item: C_JP_EV17
- Item: IsgardCrown_Box
Groups:
- Group: 0
Items:
- Item: Glacier_Helm_1
- Group: 1
Items:
- Item: Glacier_Helm_2
- Group: 2
Items:
- Item: Glacier_Helm_3
- Item: AceCard_Box
Groups:
- Group: 0
Items:
- Item: Heart_Ace_Melee
- Group: 1
Items:
- Item: Spade_Ace_Melee
- Group: 2
Items:
- Item: Diamond_Ace_Range
- Group: 3
Items:
- Item: Clover_Ace_Defense
- Item: Loki_Coin_Box
Groups:
- Group: 0
Items:
- Item: Loki_Coin
Amount: 10
- Group: 1
Items:
- Item: Loki_Coin_2
Amount: 10
- Group: 2
Items:
- Item: Loki_Coin_3
Amount: 10
- Group: 3
Items:
- Item: Loki_Coin_4
Amount: 10
- Item: Loki_Advice_Box
Groups:
- Group: 0
Items:
- Item: Loki_Advice
Amount: 10
- Group: 1
Items:
- Item: Loki_Advice_2
Amount: 10
- Group: 2
Items:
- Item: Loki_Advice_3
Amount: 10
- Group: 3
Items:
- Item: Loki_Advice_4
Amount: 10
- Item: 2023_Xmas_Costume
Groups:
- Group: 0
Items:
- Item: C_SnowmanHat
- Group: 1
Items:
- Item: C_WinterNightBells
- Group: 2
Items:
- Item: C_SantaTeddyBear
- Item: 10AllMighty_Select_Box
Groups:
- Group: 0
Items:
- Item: S_AllMighty_Earring
Refine: 10
- Group: 1
Items:
- Item: S_AllMighty_Pendant
Refine: 10
- Item: Sonic_Costume_Pack
Groups:
- Group: 0
Items:
- Item: C_Super_Sonic_Mini
- Group: 1
Items:
- Item: C_Chaos_Emerald

File diff suppressed because it is too large Load Diff

View File

@ -100897,6 +100897,8 @@ Body:
- Item: Plasma_R2_Card
Rate: 1
StealProtected: true
# - Id: 20695
# AegisName: E_GARLING
- Id: 20696
AegisName: EP17_2_CHILD_ADMIN1
Name: Child Admin Beta
@ -106578,12 +106580,204 @@ Body:
# AegisName: VR_MD_TILBY2
# - Id: 22164
# AegisName: VR_MD_RAINBOW
# - Id: 22166
# AegisName: HEADSTONE1
# - Id: 22167
# AegisName: HEADSTONE2
# - Id: 22168
# AegisName: HEADSTONE3
# - Id: 22169
# AegisName: HEADSTONE4
# - Id: 22170
# AegisName: HEADSTONE0
# - Id: 22171
# AegisName: MD_COMMON_BOSS
# - Id: 22172
# AegisName: E_MANANANGGAL
# - Id: 22173
# AegisName: E_WAKWAK
# - Id: 22174
# AegisName: MD_PRI_RIGEL
# - Id: 22175
# AegisName: MD_PRI_RIGEL_AC
# - Id: 22176
# AegisName: MD_PRI_RIGEL_ACS
# - Id: 22177
# AegisName: MD_PRI_DRAGON_1
# - Id: 22178
# AegisName: MD_PRI_DRAGON_2
# - Id: 22179
# AegisName: MD_PRI_DRAGON_3
# - Id: 22180
# AegisName: MD_PRI_DRAGON_4
# - Id: 22181
# AegisName: MD_COMMON_P
# - Id: 22182
# AegisName: MD_COMMON_SG
# - Id: 22183
# AegisName: MD_MANASTORM
# - Id: 22184
# AegisName: MD_MANABARRIER
# - Id: 22185
# AegisName: DARK_LORD2
# - Id: 22186
# AegisName: E_NF_BUG
# - Id: 22187
# AegisName: E_NF_FLY
# - Id: 22188
# AegisName: E_NF_SMALLRAT
# - Id: 22189
# AegisName: E_NF_BIGRAT
# - Id: 22192
# AegisName: SPIRIT_G_LAND_S
# - Id: 22193
# AegisName: SPIRIT_G_LAND_M
# - Id: 22194
# AegisName: SPIRIT_G_LAND_L
# - Id: 22195
# AegisName: SPIRIT_G_LAND_SL
# - Id: 22196
# AegisName: SPIRIT_B_FLAME_S
# - Id: 22197
# AegisName: SPIRIT_B_FLAME_M
# - Id: 22198
# AegisName: SPIRIT_B_FLAME_L
# - Id: 22199
# AegisName: SPIRIT_B_FLAME_SL
# - Id: 22200
# AegisName: SPIRIT_S_WIND_S
# - Id: 22201
# AegisName: SPIRIT_S_WIND_M
# - Id: 22202
# AegisName: SPIRIT_S_WIND_L
# - Id: 22203
# AegisName: SPIRIT_S_WIND_SL
# - Id: 22204
# AegisName: SPIRIT_I_WATER_S
# - Id: 22205
# AegisName: SPIRIT_I_WATER_M
# - Id: 22206
# AegisName: SPIRIT_I_WATER_L
# - Id: 22207
# AegisName: SPIRIT_I_WATER_SL
# - Id: 22208
# AegisName: SPIRIT_C_LAND_S
# - Id: 22209
# AegisName: SPIRIT_C_LAND_M
# - Id: 22210
# AegisName: SPIRIT_C_LAND_L
# - Id: 22211
# AegisName: SPIRIT_C_LAND_SL
# - Id: 22212
# AegisName: SPIRIT_C_FLAME_S
# - Id: 22213
# AegisName: SPIRIT_C_FLAME_M
# - Id: 22214
# AegisName: SPIRIT_C_FLAME_L
# - Id: 22215
# AegisName: SPIRIT_C_FLAME_SL
# - Id: 22216
# AegisName: SPIRIT_H_WATER_S
# - Id: 22217
# AegisName: SPIRIT_H_WATER_M
# - Id: 22218
# AegisName: SPIRIT_H_WATER_L
# - Id: 22219
# AegisName: SPIRIT_H_WATER_SL
# - Id: 22220
# AegisName: SPIRIT_D_WIND_S
# - Id: 22221
# AegisName: SPIRIT_D_WIND_M
# - Id: 22222
# AegisName: SPIRIT_D_WIND_L
# - Id: 22223
# AegisName: SPIRIT_D_WIND_SL
# - Id: 22224
# AegisName: SPIRIT_R_FLAME_S
# - Id: 22225
# AegisName: SPIRIT_R_FLAME_M
# - Id: 22226
# AegisName: SPIRIT_R_FLAME_L
# - Id: 22227
# AegisName: SPIRIT_R_FLAME_SL
# - Id: 22228
# AegisName: SPIRIT_F_LAND_S
# - Id: 22229
# AegisName: SPIRIT_F_LAND_M
# - Id: 22230
# AegisName: SPIRIT_F_LAND_L
# - Id: 22231
# AegisName: SPIRIT_F_LAND_SL
# - Id: 22232
# AegisName: SPIRIT_C_WATER_S
# - Id: 22233
# AegisName: SPIRIT_C_WATER_M
# - Id: 22234
# AegisName: SPIRIT_C_WATER_L
# - Id: 22235
# AegisName: SPIRIT_C_WATER_SL
# - Id: 22236
# AegisName: SPIRIT_C_WIND_S
# - Id: 22237
# AegisName: SPIRIT_C_WIND_M
# - Id: 22238
# AegisName: SPIRIT_C_WIND_L
# - Id: 22239
# AegisName: SPIRIT_C_WIND_SL
# - Id: 22240
# AegisName: VR_SONIC_WALK
# - Id: 22241
# AegisName: VR_SONIC_SPIN
# - Id: 22242
# AegisName: VR_TALES
# - Id: 22243
# AegisName: VR_MD_METALSONIC
# - Id: 22244
# AegisName: VR_MD_KNUCKLES
# - Id: 22245
# AegisName: VR_MD_DREGG1
# - Id: 22246
# AegisName: VR_MD_DREGG2
# - Id: 22247
# AegisName: VR_MD_MEGALITH_SONIC
# - Id: 22248
# AegisName: VR_MD_SPORE_SONIC
# - Id: 22249
# AegisName: VR_MD_SAVAGE_SONIC
# - Id: 22250
# AegisName: VR_MD_ANGELING_SONIC
# - Id: 22251
# AegisName: VR_MD_HEATER_SONIC
# - Id: 22252
# AegisName: BIO_DUNEYRR
# - Id: 22253
# AegisName: BIO_NAGA
# - Id: 22254
# AegisName: BIO_ANCIENT_TREE
# - Id: 22255
# AegisName: BIO_DOLLOCARIS
# - Id: 22256
# AegisName: BIO_ICE_GARGOYLE
# - Id: 22257
# AegisName: BIO_FLAME_GHOST
# - Id: 22258
# AegisName: BIO_ACIDUS_
# - Id: 22259
# AegisName: BIO_MOROCC_1
# - Id: 22260
# AegisName: BIO_SALAMANDER
# - Id: 22261
# AegisName: BIO_MOSKILLO
# - Id: 22262
# AegisName: 2311_EV_BLACK_BEAR
# - Id: 22263
# AegisName: 2311_EV_GOLD_PIG
# - Id: 22297
# AegisName: 2401_EV_DRAGORING
# - Id: 22298
# AegisName: 2401_EV_IMOOGI
# - Id: 22299
# AegisName: VR_CHAO
# - Id: 22328
# AegisName: DESERT_WOLF_RAC
# - Id: 22329

File diff suppressed because it is too large Load Diff

View File

@ -10125,6 +10125,7 @@ Body:
FixedCastTime: 700
CastTimeFlags:
IgnoreDex: true
IgnoreItemBonus: true
Requires:
SpCost:
- Level: 1
@ -34930,17 +34931,7 @@ Body:
Time: 2000
- Level: 5
Time: 1000
Cooldown:
- Level: 1
Time: 30000
- Level: 2
Time: 60000
- Level: 3
Time: 90000
- Level: 4
Time: 120000
- Level: 5
Time: 150000
Cooldown: 60000
Requires:
SpCost:
- Level: 1
@ -34965,7 +34956,7 @@ Body:
Critical: true
Range: 1
Hit: Multi_Hit
HitCount: 2
HitCount: 3
Element: Weapon
Requires:
SpCost: 1
@ -35442,7 +35433,7 @@ Body:
Element: Water
CastCancel: true
CastTime: 3000
AfterCastActDelay: 250
AfterCastActDelay: 750
Duration1: 4000
Cooldown: 5000
FixedCastTime: 1500
@ -35489,7 +35480,7 @@ Body:
Element: Dark
CastCancel: true
CastTime: 4000
AfterCastActDelay: 500
AfterCastActDelay: 750
Duration1: 4000
Cooldown: 4000
FixedCastTime: 1500
@ -35546,7 +35537,7 @@ Body:
Area: 4
CastCancel: true
CastTime: 4000
AfterCastActDelay: 500
AfterCastActDelay: 1000
Duration1:
- Level: 1
Time: 1200
@ -35597,7 +35588,7 @@ Body:
Description: Violent Quake Attack
MaxLevel: 5
Type: Magic
TargetType: Attack
TargetType: Ground
Range: 9
Hit: Single
HitCount: 1
@ -35674,7 +35665,7 @@ Body:
Element: Earth
CastCancel: true
CastTime: 3000
AfterCastActDelay: 250
AfterCastActDelay: 750
Duration1: 4000
Cooldown: 5000
FixedCastTime: 1500
@ -35731,7 +35722,7 @@ Body:
Area: 4
CastCancel: true
CastTime: 4000
AfterCastActDelay: 500
AfterCastActDelay: 1000
Duration1:
- Level: 1
Time: 1200
@ -35782,7 +35773,7 @@ Body:
Description: All Bloom Attack
MaxLevel: 5
Type: Magic
TargetType: Attack
TargetType: Ground
Range: 9
Hit: Single
HitCount: 1
@ -35802,7 +35793,7 @@ Body:
Description: All Bloom Attack 2
MaxLevel: 5
Type: Magic
TargetType: Attack
TargetType: Ground
Range: 9
Hit: Single
HitCount: 1
@ -35873,7 +35864,7 @@ Body:
Description: Crystal Impact Attack
MaxLevel: 5
Type: Magic
TargetType: Attack
TargetType: Ground
DamageFlags:
Splash: true
Hit: Single
@ -35893,7 +35884,7 @@ Body:
Element: Wind
CastCancel: true
CastTime: 3000
AfterCastActDelay: 250
AfterCastActDelay: 750
Duration1: 3000
Cooldown: 5000
FixedCastTime: 1500
@ -35944,7 +35935,7 @@ Body:
Element: Fire
CastCancel: true
CastTime: 3000
AfterCastActDelay: 250
AfterCastActDelay: 750
Duration1: 5000
Cooldown: 5000
FixedCastTime: 1500
@ -36012,7 +36003,7 @@ Body:
Area: 5
CastCancel: true
CastTime: 8000
AfterCastActDelay: 500
AfterCastActDelay: 1000
Duration1: 6000
Cooldown: 6000
FixedCastTime: 2000
@ -36052,7 +36043,7 @@ Body:
Description: Astral Strike Attack
MaxLevel: 10
Type: Magic
TargetType: Attack
TargetType: Ground
Range: 9
Hit: Single
HitCount: 1
@ -36071,11 +36062,11 @@ Body:
CastCancel: true
AfterCastActDelay: 300
Duration1: 300000
Cooldown: 300000
Cooldown: 60000
FixedCastTime: 4000
Requires:
SpCost: 60
ApCost: 150
ApCost: 125
Status: Climax
- Id: 5233
Name: AG_ROCK_DOWN
@ -36241,8 +36232,8 @@ Body:
TargetType: Self
DamageFlags:
Splash: true
Hit: Single
HitCount: 1
Hit: Multi_Hit
HitCount: -3
Element: Water
SplashArea:
- Level: 1
@ -36717,7 +36708,8 @@ Body:
SplashArea: 3
CastCancel: true
Duration1: 600000
Cooldown: 1000
AfterCastActDelay: 500
Cooldown: 700
Requires:
SpCost:
- Level: 1
@ -36744,6 +36736,7 @@ Body:
Element: Weapon
SplashArea: 3
CastCancel: true
AfterCastActDelay: 700
Cooldown: 1000
Requires:
SpCost:
@ -36854,16 +36847,16 @@ Body:
Toggleable: true
Hit: Single
HitCount: 1
GiveAp: 15
SplashArea: 10
CastCancel: true
CastTime: 2000
AfterCastActDelay: 500
Duration1: 60000
Cooldown: 15000
AfterCastActDelay: 300
Duration1: 40000
Cooldown: 25000
FixedCastTime: 1000
Requires:
SpCost: 60
ApCost: 35
Status:
Guard_Stance: true
Status: Guardian_S
@ -37025,7 +37018,7 @@ Body:
Range: 9
Hit: Multi_Hit
HitCount: -10
Element: Holy
Element: Neutral
CastCancel: true
CastTime: 2000
Cooldown: 5000
@ -37065,7 +37058,7 @@ Body:
Hit: Multi_Hit
HitCount: -7
Element: Weapon
GiveAp: 3
GiveAp: 5
SplashArea:
- Level: 1
Area: 2
@ -37112,7 +37105,7 @@ Body:
HitCount: 3
Element: Weapon
SplashArea: 3
GiveAp: 3
GiveAp: 5
CastCancel: true
CastTime: 1000
AfterCastActDelay: 500
@ -37152,7 +37145,7 @@ Body:
Hit: Single
HitCount: 1
Element: Holy
GiveAp: 4
GiveAp: 6
CastCancel: true
CastTime: 1000
AfterCastActDelay: 150
@ -37534,15 +37527,16 @@ Body:
Range: 9
Hit: Multi_Hit
HitCount: -10
Element: Holy
Element: Neutral
CastCancel: true
CastTime: 3000
AfterCastActDelay: 500
Duration1: 12000
Cooldown: 5000
FixedCastTime: 2000
Requires:
SpCost: 150
ApCost: 30
ApCost: 20
Unit:
Id: Pneumaticus_Procella
Range:
@ -38051,7 +38045,7 @@ Body:
IgnoreDefense: true
Range: 2
Hit: Multi_Hit
HitCount: 2
HitCount: 3
Element: Weapon
GiveAp: 2
CastCancel: true
@ -38190,7 +38184,7 @@ Body:
Area: 3
GiveAp: 3
CastCancel: true
AfterCastActDelay: 250
AfterCastActDelay: 700
Duration1:
- Level: 1
Time: 10000
@ -38863,7 +38857,7 @@ Body:
Time: 1500
- Level: 5
Time: 1000
Cooldown: 60000
Cooldown: 30000
Requires:
SpCost:
- Level: 1
@ -38894,26 +38888,27 @@ Body:
FixedCastTime: 1000
Requires:
SpCost: 100
ApCost: 150
ApCost: 120
Status: Abyss_Slayer
- Id: 5319
Name: ABC_ABYSS_STRIKE
Description: Abyss Strike
Description: Omega Abyss Strike
MaxLevel: 10
Type: Magic
TargetType: Ground
Range: 9
Hit: Single
HitCount: 1
Element: Fire
CastCancel: true
CastTime: 2000
AfterCastActDelay: 500
Duration1: 100
Cooldown: 3000
Cooldown: 700
FixedCastTime: 1000
Requires:
SpCost: 125
ApCost: 15
ApCost: 10
Unit:
Id: Dummyskill
Range: 4
@ -39028,7 +39023,7 @@ Body:
Hit: Multi_Hit
HitCount: 2
Element: Weapon
GiveAp: 1
GiveAp: 3
CastCancel: true
AfterCastActDelay: 500
Cooldown: 350
@ -39158,11 +39153,11 @@ Body:
CastCancel: true
AfterCastActDelay: 500
Duration1: 180000
Cooldown: 180000
Cooldown: 60000
FixedCastTime: 1000
Requires:
SpCost: 300
ApCost: 200
ApCost: 125
Status: CalamityGale
- Id: 5329
Name: WH_HAWKBOOMERANG
@ -39223,7 +39218,7 @@ Body:
CastCancel: true
CastTime: 3500
AfterCastActDelay: 500
Cooldown: 1200
Cooldown: 700
FixedCastTime: 500
Requires:
SpCost:
@ -40915,7 +40910,7 @@ Body:
GiveAp: 5
CastCancel: true
CastTime: 4000
AfterCastActDelay: 500
AfterCastActDelay: 700
Duration1: 3000
Duration2: 10000
Cooldown: 2000
@ -40954,7 +40949,7 @@ Body:
GiveAp: 5
CastCancel: true
CastTime: 4000
AfterCastActDelay: 500
AfterCastActDelay: 700
Duration1: 3000
Duration2: 20000
Cooldown: 2000
@ -40993,7 +40988,7 @@ Body:
GiveAp: 5
CastCancel: true
CastTime: 4000
AfterCastActDelay: 500
AfterCastActDelay: 700
Duration1: 3000
Duration2: 20000
Cooldown: 2000
@ -41074,7 +41069,7 @@ Body:
CastTime: 3000
AfterCastActDelay: 500
Duration1: 1500000
Cooldown: 900000
Cooldown: 60000
FixedCastTime: 2000
Requires:
SpCost: 100
@ -41095,7 +41090,7 @@ Body:
CastTime: 3000
AfterCastActDelay: 500
Duration1: 1500000
Cooldown: 900000
Cooldown: 60000
FixedCastTime: 2000
Requires:
SpCost: 100
@ -41116,7 +41111,7 @@ Body:
CastTime: 3000
AfterCastActDelay: 500
Duration1: 1500000
Cooldown: 900000
Cooldown: 60000
FixedCastTime: 2000
Requires:
SpCost: 100
@ -41137,7 +41132,7 @@ Body:
CastTime: 3000
AfterCastActDelay: 500
Duration1: 1500000
Cooldown: 900000
Cooldown: 60000
FixedCastTime: 2000
Requires:
SpCost: 100
@ -41158,7 +41153,7 @@ Body:
CastTime: 3000
AfterCastActDelay: 500
Duration1: 1500000
Cooldown: 900000
Cooldown: 60000
FixedCastTime: 2000
Requires:
SpCost: 100
@ -41177,11 +41172,11 @@ Body:
CastCancel: true
CastTime: 8000
AfterCastActDelay: 500
Cooldown: 5000
Cooldown: 2000
FixedCastTime: 1500
Requires:
SpCost: 140
ApCost: 30
ApCost: 15
- Id: 5381
Name: EM_ELEMENTAL_VEIL
Description: Elemental Veil
@ -41246,7 +41241,7 @@ Body:
Splash: true
Range: 1
Hit: Multi_Hit
HitCount: 2
HitCount: 5
SplashArea: 4
Requires:
SpCost: 1
@ -41871,6 +41866,473 @@ Body:
SpCost: 100
ApCost: 100
Status: Blessing_of_M_Creatures
- Id: 5401
Name: NW_P_F_I
Description: P.F.I
MaxLevel: 10
- Id: 5402
Name: NW_GRENADE_MASTERY
Description: Grenade Mastery
MaxLevel: 10
- Id: 5403
Name: NW_INTENSIVE_AIM
Description: Intensive Aim
MaxLevel: 1
Type: Weapon
TargetType: Self
DamageFlags:
NoDamage: true
Hit: Single
HitCount: 1
Duration1: -1
Requires:
SpCost:
- Level: 1
Amount: 10
Status: Intensive_Aim
- Id: 5404
Name: NW_GRENADE_FRAGMENT
Description: Grenade Fragment
MaxLevel: 7
Type: Weapon
TargetType: Self
DamageFlags:
NoDamage: true
Hit: Single
HitCount: 1
Duration1: 300000
Cooldown: 2000
Requires:
SpCost: 50
- Id: 5405
Name: NW_THE_VIGILANTE_AT_NIGHT
Description: The Vigilante at Night
MaxLevel: 5
Type: Weapon
TargetType: Self
DamageFlags:
Splash: true
Hit: Multi_Hit
HitCount: 4
Element: Weapon
SplashArea:
- Level: 1
Area: 2
- Level: 2
Area: 2
- Level: 3
Area: 2
- Level: 4
Area: 3
- Level: 5
Area: 3
GiveAp: 2
AfterCastActDelay: 1000
Cooldown: 500
CastCancel: true
FixedCastTime: 1500
Requires:
SpCost:
- Level: 1
Amount: 72
- Level: 2
Amount: 76
- Level: 3
Amount: 80
- Level: 4
Amount: 84
- Level: 5
Amount: 88
Weapon:
Gatling: true
Shotgun: true
Ammo:
Bullet: true
AmmoAmount: 10
- Id: 5406
Name: NW_ONLY_ONE_BULLET
Description: Only One Bullet
MaxLevel: 5
Type: Weapon
TargetType: Attack
DamageFlags:
Critical: true
Range: -9
Hit: Single
HitCount: 1
Element: Weapon
GiveAp: 2
AfterCastActDelay: 500
Cooldown: 350
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost:
- Level: 1
Amount: 39
- Level: 2
Amount: 43
- Level: 3
Amount: 47
- Level: 4
Amount: 51
- Level: 5
Amount: 55
Weapon:
Revolver: true
Rifle: true
Ammo:
Bullet: true
AmmoAmount: 1
- Id: 5407
Name: NW_SPIRAL_SHOOTING
Description: Spiral Shooting
MaxLevel: 5
Type: Weapon
TargetType: Attack
DamageFlags:
Critical: true
Splash: true
Range: -9
Hit: Multi_Hit
HitCount: 1
Element: Weapon
SplashArea:
- Level: 1
Area: 2
- Level: 2
Area: 2
- Level: 3
Area: 2
- Level: 4
Area: 3
- Level: 5
Area: 3
GiveAp: 2
AfterCastActDelay: 1000
Cooldown: 500
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost:
- Level: 1
Amount: 48
- Level: 2
Amount: 53
- Level: 3
Amount: 58
- Level: 4
Amount: 63
- Level: 5
Amount: 68
Weapon:
Grenade: true
Rifle: true
Ammo:
Bullet: true
AmmoAmount: 6
- Id: 5408
Name: NW_MAGAZINE_FOR_ONE
Description: Magazine for One
MaxLevel: 5
Type: Weapon
TargetType: Attack
DamageFlags:
Critical: true
Range: -9
Hit: Multi_Hit
HitCount: 6
Element: Weapon
GiveAp: 2
AfterCastActDelay: 1000
Cooldown: 500
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost:
- Level: 1
Amount: 42
- Level: 2
Amount: 46
- Level: 3
Amount: 50
- Level: 4
Amount: 54
- Level: 5
Amount: 58
Weapon:
Revolver: true
Gatling: true
Ammo:
Bullet: true
AmmoAmount: 6
- Id: 5409
Name: NW_WILD_FIRE
Description: Wild Fire
MaxLevel: 5
Type: Weapon
TargetType: Ground
Range: -9
Hit: Single
HitCount: -3
Element: Weapon
DamageFlags:
Splash: true
SplashArea:
- Level: 1
Area: 2
- Level: 2
Area: 2
- Level: 3
Area: 2
- Level: 4
Area: 3
- Level: 5
Area: 3
GiveAp: 2
AfterCastActDelay: 1000
Cooldown: 500
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost:
- Level: 1
Amount: 51
- Level: 2
Amount: 55
- Level: 3
Amount: 59
- Level: 4
Amount: 63
- Level: 5
Amount: 67
Weapon:
Shotgun: true
Grenade: true
Ammo:
Bullet: true
AmmoAmount: 5
- Id: 5410
Name: NW_BASIC_GRENADE
Description: Basic Grenade
MaxLevel: 5
Type: Weapon
TargetType: Ground
Range: -9
Hit: Single
HitCount: -2
Element: Weapon
DamageFlags:
Splash: true
SplashArea:
- Level: 1
Area: 1
- Level: 2
Area: 1
- Level: 3
Area: 1
- Level: 4
Area: 2
- Level: 5
Area: 2
GiveAp: 2
Cooldown: 300
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost:
- Level: 1
Amount: 36
- Level: 2
Amount: 42
- Level: 3
Amount: 48
- Level: 4
Amount: 54
- Level: 5
Amount: 60
ItemCost:
- Item: Nw_Grenade
Amount: 1
- Id: 5411
Name: NW_HASTY_FIRE_IN_THE_HOLE
Description: Hasty Fire in the Hole
MaxLevel: 5
Type: Weapon
TargetType: Ground
Range: -9
Hit: Multi_Hit
HitCount: -2
Element: Weapon
DamageFlags:
Splash: true
SplashArea: 2
GiveAp: 3
Cooldown: 1000
CastCancel: true
FixedCastTime: 1000
AfterCastActDelay: 1500
Requires:
SpCost:
- Level: 1
Amount: 50
- Level: 2
Amount: 53
- Level: 3
Amount: 56
- Level: 4
Amount: 59
- Level: 5
Amount: 62
ItemCost:
- Item: Nw_Grenade
Amount: 3
- Id: 5412
Name: NW_GRENADES_DROPPING
Description: Grenades Dropping
MaxLevel: 5
Type: Weapon
TargetType: Ground
Range: -9
Hit: Multi_Hit
HitCount: 3
Element: Weapon
DamageFlags:
Splash: true
SplashArea:
- Level: 1
Area: 5
- Level: 2
Area: 5
- Level: 3
Area: 5
- Level: 4
Area: 4
- Level: 5
Area: 4
GiveAp: 5
Cooldown: 4500
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost:
- Level: 1
Amount: 60
- Level: 2
Amount: 66
- Level: 3
Amount: 72
- Level: 4
Amount: 78
- Level: 5
Amount: 84
ItemCost:
- Item: Nw_Grenade
Amount: 15
Duration1: 4000
Duration2: 100
Unit:
Id: Grenades_Dropping
Layout: 0
Range:
- Level: 1
Size: 1
- Level: 2
Size: 1
- Level: 3
Size: 1
- Level: 4
Size: 2
- Level: 5
Size: 2
Interval: 250
Target: Enemy
Flag:
NoOverlap: true
PathCheck: true
- Id: 5413
Name: NW_AUTO_FIRING_LAUNCHER
Description: Auto Firing Launcher
MaxLevel: 5
Type: Weapon
TargetType: Self
DamageFlags:
NoDamage: true
Duration1:
- Level: 1
Time: 120000
- Level: 2
Time: 150000
- Level: 3
Time: 180000
- Level: 4
Time: 210000
- Level: 5
Time: 240000
Cooldown: 30000
CastCancel: true
FixedCastTime: 3000
Requires:
SpCost:
- Level: 1
Amount: 90
- Level: 2
Amount: 100
- Level: 3
Amount: 110
- Level: 4
Amount: 120
- Level: 5
Amount: 130
Status: Auto_Firing_Launcher
- Id: 5414
Name: NW_HIDDEN_CARD
Description: Hidden Card
MaxLevel: 10
Type: Weapon
TargetType: Self
DamageFlags:
NoDamage: true
Duration1: 300000
Cooldown: 60000
CastCancel: true
FixedCastTime: 2000
Requires:
SpCost: 150
ApCost: 150
Status: Hidden_Card
- Id: 5415
Name: NW_MISSION_BOMBARD
Description: Mission Bombard
MaxLevel: 10
Type: Weapon
TargetType: Ground
Range: -9
Hit: Multi_Hit
HitCount: -3
Element: Weapon
DamageFlags:
Splash: true
SplashArea: 4
Cooldown: 10000
CastCancel: true
FixedCastTime: 1000
Requires:
SpCost: 100
ApCost: 35
ItemCost:
- Item: Nw_Grenade
Amount: 15
Duration1: 10000
Unit:
Id: Mission_Bombard
Layout: 0
Range: 2
Interval: 250
Target: Enemy
Flag:
NoOverlap: true
PathCheck: true
- Id: 5449
Name: HN_SELFSTUDY_TATICS
Description: Self Study Tactics
@ -42651,6 +43113,16 @@ Body:
SpCost: 150
ApCost: 150
Status: Rulebreak
- Id: 5496
Name: NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING
Description: The Vigilante At Night Gun Gatling
MaxLevel: 5
CastCancel: true
- Id: 5497
Name: NW_THE_VIGILANTE_AT_NIGHT_GUN_SHOTGUN
Description: The Vigilante At Night Gun Shotgun
MaxLevel: 5
CastCancel: true
- Id: 6001
Name: DK_DRAGONIC_BREATH
Description: Dragonic Breath
@ -42863,7 +43335,7 @@ Body:
- Level: 10
Area: 3
CastCancel: true
AfterCastActDelay: 250
AfterCastActDelay: 700
Cooldown: 500
Requires:
SpCost:

View File

@ -7864,6 +7864,95 @@ Body:
Royal_Guard: true
Royal_Guard_T: true
Imperial_Guard: true
- Job: Night_Watch
Inherit:
Novice: true
Gunslinger: true
Rebellion: true
Tree:
- Name: NW_P_F_I
MaxLevel: 10
- Name: NW_GRENADE_MASTERY
MaxLevel: 10
- Name: NW_INTENSIVE_AIM
MaxLevel: 1
Requires:
- Name: NW_P_F_I
Level: 1
- Name: NW_HIDDEN_CARD
MaxLevel: 10
Requires:
- Name: NW_P_F_I
Level: 5
- Name: NW_INTENSIVE_AIM
Level: 1
- Name: NW_BASIC_GRENADE
MaxLevel: 5
Requires:
- Name: NW_GRENADE_MASTERY
Level: 3
- Name: NW_GRENADE_FRAGMENT
MaxLevel: 7
Requires:
- Name: NW_GRENADE_MASTERY
Level: 1
- Name: NW_THE_VIGILANTE_AT_NIGHT
MaxLevel: 5
Requires:
- Name: NW_P_F_I
Level: 3
- Name: NW_INTENSIVE_AIM
Level: 1
- Name: NW_ONLY_ONE_BULLET
MaxLevel: 5
Requires:
- Name: NW_P_F_I
Level: 3
- Name: NW_INTENSIVE_AIM
Level: 1
- Name: NW_SPIRAL_SHOOTING
MaxLevel: 5
Requires:
- Name: NW_P_F_I
Level: 3
- Name: NW_INTENSIVE_AIM
Level: 1
- Name: NW_MAGAZINE_FOR_ONE
MaxLevel: 5
Requires:
- Name: NW_P_F_I
Level: 3
- Name: NW_INTENSIVE_AIM
Level: 1
- Name: NW_WILD_FIRE
MaxLevel: 5
Requires:
- Name: NW_P_F_I
Level: 3
- Name: NW_INTENSIVE_AIM
Level: 1
- Name: NW_HASTY_FIRE_IN_THE_HOLE
MaxLevel: 5
Requires:
- Name: NW_BASIC_GRENADE
Level: 3
- Name: NW_GRENADES_DROPPING
MaxLevel: 5
Requires:
- Name: NW_HASTY_FIRE_IN_THE_HOLE
Level: 3
- Name: NW_AUTO_FIRING_LAUNCHER
MaxLevel: 5
Requires:
- Name: NW_GRENADES_DROPPING
Level: 3
- Name: NW_MISSION_BOMBARD
MaxLevel: 10
Requires:
- Name: NW_GRENADE_MASTERY
Level: 5
- Name: NW_GRENADES_DROPPING
Level: 3
- Job: Hyper_Novice
Inherit:
Novice: true

View File

@ -7894,6 +7894,8 @@ Body:
BlEffect: true
DisplayPc: true
SendVal1: true
NoDispell: true
NoClearance: true
- Status: Shadow_Weapon
Icon: EFST_SHADOW_WEAPON
DurationLookup: SHC_ENCHANTING_SHADOW
@ -7939,6 +7941,9 @@ Body:
Flags:
BlEffect: true
DisplayPc: true
NoBanishingBuster: true
NoDispell: true
NoClearance: true
- Status: Ultimate_S
Icon: EFST_ULTIMATE_S
DurationLookup: IG_ULTIMATE_SACRIFICE
@ -8751,6 +8756,10 @@ Body:
DurationLookup: MT_RUSH_QUAKE
CalcFlags:
All: true
Flags:
NoDispell: true
NoBanishingBuster: true
NoClearance: true
- Status: G_LIFEPOTION
Icon: EFST_G_LIFEPOTION
Flags:
@ -8785,6 +8794,99 @@ Body:
- Status: Rulebreak
Icon: EFST_RULEBREAK
DurationLookup: HN_RULEBREAK
- Status: Intensive_Aim
Icon: EFST_INTENSIVE_AIM
States:
NoMove: true
CalcFlags:
Batk: true
Hit: true
Cri: true
Flags:
BlEffect: true
DisplayPc: true
SendVal1: true
NoSave: true
NoBanishingBuster: true
NoDispell: true
NoClearance: true
- Status: Intensive_Aim_Count
Icon: EFST_INTENSIVE_AIM_COUNT
Flags:
DisplayPc: true
SendVal1: true
NoSave: true
NoBanishingBuster: true
NoDispell: true
NoClearance: true
- Status: Grenade_Fragment_1
Icon: EFST_GRENADE_FRAGMENT_1
DurationLookup: NW_GRENADE_FRAGMENT
EndOnStart:
Grenade_Fragment_2: true
Grenade_Fragment_3: true
Grenade_Fragment_4: true
Grenade_Fragment_5: true
Grenade_Fragment_6: true
- Status: Grenade_Fragment_2
Icon: EFST_GRENADE_FRAGMENT_2
DurationLookup: NW_GRENADE_FRAGMENT
EndOnStart:
Grenade_Fragment_1: true
Grenade_Fragment_3: true
Grenade_Fragment_4: true
Grenade_Fragment_5: true
Grenade_Fragment_6: true
- Status: Grenade_Fragment_3
Icon: EFST_GRENADE_FRAGMENT_3
DurationLookup: NW_GRENADE_FRAGMENT
EndOnStart:
Grenade_Fragment_1: true
Grenade_Fragment_2: true
Grenade_Fragment_4: true
Grenade_Fragment_5: true
Grenade_Fragment_6: true
- Status: Grenade_Fragment_4
Icon: EFST_GRENADE_FRAGMENT_4
DurationLookup: NW_GRENADE_FRAGMENT
EndOnStart:
Grenade_Fragment_1: true
Grenade_Fragment_2: true
Grenade_Fragment_3: true
Grenade_Fragment_5: true
Grenade_Fragment_6: true
- Status: Grenade_Fragment_5
Icon: EFST_GRENADE_FRAGMENT_5
DurationLookup: NW_GRENADE_FRAGMENT
EndOnStart:
Grenade_Fragment_1: true
Grenade_Fragment_2: true
Grenade_Fragment_3: true
Grenade_Fragment_4: true
Grenade_Fragment_6: true
- Status: Grenade_Fragment_6
Icon: EFST_GRENADE_FRAGMENT_6
DurationLookup: NW_GRENADE_FRAGMENT
EndOnStart:
Grenade_Fragment_1: true
Grenade_Fragment_2: true
Grenade_Fragment_3: true
Grenade_Fragment_4: true
Grenade_Fragment_5: true
- Status: Auto_Firing_Launcher
Icon: EFST_AUTO_FIRING_LAUNCHEREFST
DurationLookup: NW_AUTO_FIRING_LAUNCHER
Flags:
SendVal1: true
- Status: Hidden_Card
Icon: EFST_HIDDEN_CARD
DurationLookup: NW_HIDDEN_CARD
CalcFlags:
All: true
Flags:
NoBanishingBuster: true
NoDispell: true
NoClearance: true
- Status: Hogogong
Icon: EFST_HOGOGONG
DurationLookup: SH_HOWLING_OF_CHUL_HO

View File

@ -125,6 +125,12 @@ item delay, etc).
---------------------------------------
*trade_unconditional
Allows player to ignore the trade conditions of items (drop, trade, sell, cart, storage/gstorage, mail and auction).
---------------------------------------
======================
| 3. Command-related |
======================

View File

@ -20,11 +20,30 @@ Title: Quest title.
TimeLimit: Amount of time before the quest expires.
Use a number followed by "d" for day(s), "h" for hour(s), "mn" for minute(s), and "s" for second(s).
Specifying with "+" will mark how long until the quest expires.
Specifying without "+" will mark the exact time the quest expires. Format: "d" (optional), [0-23]"h" (required), [0-59]"mn" (optional), [0-59]"s" (optional).
Use a number followed by "d" for day(s), "h" for hour(s), "mn" for minute(s), and "s" for second(s).
Format: "d" (optional), [0-23]"h" (optional), [0-59]"mn" (optional), [0-59]"s" (optional).
Please note the number before "d" only shifts the exact timer to the given day(s).
Example:
- Id: 2069
Title: Tierra Gorge Battle
# The quest expires 5 minutes after being taken.
TimeLimit: +5mn
Specifying without "+" will mark the exact time the quest expires.
Use a number followed by "d" for day(s) to shift the exact timer to the given day(s) or use the days of the week to set the expiration day,
and "h" for hour(s), "mn" for minute(s), and "s" for second(s).
Format: [days of the week] or "d" (optionals), [0-23]"h" (optional), [0-59]"mn" (optional), [0-59]"s" (optional).
Examples:
- Id: 9419
Title: Attack Sky Fortress Invading Prontera
# The quest expires 3 days after being taken at 4am.
TimeLimit: 3d 4h
- Id: 5965
Title: "[Standby] Devil's Special"
# The quest expires Monday at 4am.
TimeLimit: Monday 4h
---------------------------------------

View File

@ -8966,8 +8966,9 @@ Get info of elemental of attached player or player by char_id.
Other info can be obtained by 'getunitdata' command.
Valid types are:
0: Elemental ID
1: Elemental Game ID
ELEMINFO_ID Elemental ID (ID unique to elementals unit type)
ELEMINFO_GAMEID Elemental Game ID
ELEMINFO_CLASS Elemental Class (ID defined in elemental_db.yml)
---------------------------------------
\\
@ -11412,3 +11413,37 @@ Example:
autoloot(10000); // 100.00%
---------------------------------------
*setdialogalign(<align>);
Set vertical or horizontal align in NPC dialog.
Valid aligns:
- horizontal align:
DIALOG_ALIGN_LEFT
DIALOG_ALIGN_CENTER
DIALOG_ALIGN_RIGHT
- vertical align:
DIALOG_ALIGN_TOP
DIALOG_ALIGN_MIDDLE
DIALOG_ALIGN_BOTTOM
---------------------------------------
*setdialogsize(<width>, <height>)
Set size for NPC dialog in pixels.
---------------------------------------
*setdialogpos(<x>, <y>)
Set position for NPC dialog in pixels.
---------------------------------------
*setdialogpospercent(<x>, <y>)
Set position for NPC dialog in screen size percent.
---------------------------------------

View File

@ -2831,9 +2831,10 @@ void char_config_split_startpoint( char* w1_value, char* w2_value, struct s_poin
lineitem = strtok(w2_value, ":");
while (lineitem != NULL && (*count) < MAX_STARTPOINT) {
int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE);
bool error;
size_t n = sv_split( lineitem, strlen( lineitem ), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE, error );
if (n + 1 < fields_length) {
if( error || ( n + 1 ) < fields_length ){
ShowDebug("%s: not enough arguments for %s! Skipping...\n", w1_value, lineitem);
lineitem = strtok(NULL, ":"); //next lineitem
continue;
@ -2867,9 +2868,10 @@ void char_config_split_startitem(char *w1_value, char *w2_value, struct startite
lineitem = strtok(w2_value, ":");
while (lineitem != NULL && i < MAX_STARTITEM) {
int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE);
bool error;
size_t n = sv_split( lineitem, strlen( lineitem ), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE, error );
if (n + 1 < fields_length) {
if( error || ( n + 1 ) < fields_length ){
ShowDebug("%s: not enough arguments for %s! Skipping...\n", w1_value, lineitem);
lineitem = strtok(NULL, ":"); //next lineitem
continue;

View File

@ -340,9 +340,8 @@ int Core::start( int argc, char **argv ){
char *p1;
if((p1 = strrchr(argv[0], '/')) != NULL || (p1 = strrchr(argv[0], '\\')) != NULL ){
char *pwd = NULL; //path working directory
int n=0;
SERVER_NAME = ++p1;
n = p1-argv[0]; //calc dir name len
size_t n = p1-argv[0]; //calc dir name len
pwd = safestrncpy((char*)malloc(n + 1), argv[0], n);
if(chdir(pwd) != 0)
ShowError("Couldn't change working directory to %s for %s, runtime will probably fail",pwd,SERVER_NAME);

View File

@ -4,20 +4,30 @@
#ifndef PACKETS_HPP
#define PACKETS_HPP
#include <functional>
#include <unordered_map>
#include <common/cbasetypes.hpp>
#include <common/mmo.hpp>
#include <common/showmsg.hpp>
#include <common/socket.hpp>
#include <common/utilities.hpp>
#pragma warning( push )
#pragma warning( disable : 4200 )
#define DEFINE_PACKET_HEADER( name, id ) const int16 HEADER_##name = id
#define DEFINE_PACKET_ID( name, id ) DEFINE_PACKET_HEADER( name, id )
// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
#pragma pack( push, 1 )
#endif
struct PACKET{
int16 packetType;
int16 packetLength;
} __attribute__((packed));
struct PACKET_CA_LOGIN{
int16 packetType;
uint32 version;
@ -209,4 +219,88 @@ DEFINE_PACKET_HEADER( TC_RESULT, 0xae3 );
#pragma warning( pop )
template <typename sessiontype> class PacketDatabase{
private:
struct s_packet_info{
bool fixed;
int16 size;
std::function<bool ( int fd, sessiontype& sd )> func;
};
std::unordered_map<int16, s_packet_info> infos;
public:
void add( int16 packetType, bool fixed, int16 size, std::function<bool ( int fd, sessiontype& sd )> func ){
if( fixed ){
if( size < 2 ){
ShowError( "Definition for packet 0x%04x is invalid. Minimum size for a fixed length packet is 2 bytes.\n", packetType );
return;
}
}else{
if( size < 4 ){
ShowError( "Definition for packet 0x%04x is invalid. Minimum size for a dynamic length packet is 2 bytes.\n", packetType );
return;
}
}
s_packet_info& info = infos[packetType];
info.fixed = fixed;
info.size = size;
info.func = func;
}
bool handle( int fd, sessiontype& sd ){
int16 remaining = static_cast<int16>( RFIFOREST( fd ) );
if( remaining < 2 ){
ShowError( "Did not receive enough bytes to process a packet\n" );
set_eof( fd );
return false;
}
PACKET* p = (PACKET*)RFIFOP( fd, 0 );
s_packet_info* info = rathena::util::umap_find( this->infos, p->packetType );
if( info == nullptr ){
ShowError( "Received unknown packet 0x%04x\n", p->packetType );
set_eof( fd );
return false;
}
if( info->fixed ){
if( remaining < info->size ){
ShowError( "Invalid size %hd for packet 0x%04x with fixed size of %hd\n", remaining, p->packetType, info->size );
set_eof( fd );
return false;
}
bool ret = info->func( fd, sd );
RFIFOSKIP( fd, info->size );
return ret;
}else{
if( remaining < info->size ){
ShowError( "Invalid size %hd for packet 0x%04x with dynamic minimum size of %hd\n", remaining, p->packetType, info->size );
set_eof( fd );
return false;
}
if( remaining < p->packetLength ){
ShowError( "Invalid size %hd for packet 0x%04x with dynamic size of %hd\n", remaining, p->packetType, p->packetLength );
set_eof( fd );
return false;
}
bool ret = info->func( fd, sd );
RFIFOSKIP( fd, p->packetLength );
return ret;
}
}
};
#endif /* PACKETS_HPP */

View File

@ -61,7 +61,7 @@ char console_log_filepath[32] = "./log/unknown.log";
char s_[SBUF_SIZE]; \
StringBuf *d_; \
char *v_; \
int l_; \
size_t l_; \
} buf ={"",NULL,NULL,0}; \
//define NEWBUF
@ -210,7 +210,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
if( !is_console(handle) && stdout_with_ansisequence )
{
WriteFile(handle, BUFVAL(tempbuf), BUFLEN(tempbuf), &written, 0);
WriteFile( handle, BUFVAL( tempbuf ), (DWORD)BUFLEN( tempbuf ), &written, 0 );
return 0;
}

View File

@ -1696,10 +1696,7 @@ void send_shortlist_add_fd(int fd)
// Do pending network sends and eof handling from the shortlist.
void send_shortlist_do_sends()
{
int i;
for( i = send_shortlist_count-1; i >= 0; --i )
{
for( int i = static_cast<int>( send_shortlist_count - 1 ); i >= 0; --i ){
int fd = send_shortlist_array[i];
int idx = fd/32;
int bit = fd%32;

View File

@ -3,6 +3,8 @@
#include "strlib.hpp"
#include <algorithm>
#include <stdlib.h>
#include "cbasetypes.hpp"
@ -348,8 +350,7 @@ bool bin2hex(char* output, unsigned char* input, size_t count)
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if already done, -1 on error.
int sv_parse_next(struct s_svstate* sv)
{
int sv_parse_next( s_svstate& sv ){
enum {
START_OF_FIELD,
PARSING_FIELD,
@ -358,19 +359,11 @@ int sv_parse_next(struct s_svstate* sv)
TERMINATE,
END
} state;
const char* str;
int len;
enum e_svopt opt;
char delim;
int i;
if( sv == NULL )
return -1;// error
str = sv->str;
len = sv->len;
opt = sv->opt;
delim = sv->delim;
const char* str = sv.str;
size_t len = sv.len;
int opt = sv.opt;
char delim = sv.delim;
// check opt
if( delim == '\n' && (opt&(SV_TERMINATE_CRLF|SV_TERMINATE_LF)) )
@ -384,9 +377,9 @@ int sv_parse_next(struct s_svstate* sv)
return -1;// error
}
if( sv->done || str == NULL )
if( sv.done || str == NULL )
{
sv->done = true;
sv.done = true;
return 0;// nothing to parse
}
@ -397,10 +390,10 @@ int sv_parse_next(struct s_svstate* sv)
((opt&SV_TERMINATE_CR) && str[i] == '\r') || \
((opt&SV_TERMINATE_CRLF) && i+1 < len && str[i] == '\r' && str[i+1] == '\n') )
#define IS_C_ESCAPE() ( (opt&SV_ESCAPE_C) && str[i] == '\\' )
#define SET_FIELD_START() sv->start = i
#define SET_FIELD_END() sv->end = i
#define SET_FIELD_START() sv.start = i
#define SET_FIELD_END() sv.end = i
i = sv->off;
size_t i = sv.off;
state = START_OF_FIELD;
while( state != END )
{
@ -480,14 +473,14 @@ int sv_parse_next(struct s_svstate* sv)
else
++i;// CR or LF
#endif
sv->done = true;
sv.done = true;
state = END;
break;
}
}
if( IS_END() )
sv->done = true;
sv->off = i;
sv.done = true;
sv.off = i;
#undef IS_END
#undef IS_DELIM
@ -520,15 +513,20 @@ int sv_parse_next(struct s_svstate* sv)
/// @param npos Size of the pos array
/// @param opt Options that determine the parsing behaviour
/// @return Number of fields found in the string or -1 if an error occured
int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt)
{
struct s_svstate sv;
int count;
size_t sv_parse( const char* str, size_t len, size_t startoff, char delim, size_t* out_pos, size_t npos, int opt, bool& error ){
// initialize
if( out_pos == NULL ) npos = 0;
for( count = 0; count < npos; ++count )
out_pos[count] = -1;
error = false;
if( out_pos == nullptr ){
npos = 0;
}
for( size_t i = 0; i < npos; ++i ){
out_pos[i] = -1;
}
s_svstate sv = {};
sv.str = str;
sv.len = len;
sv.off = startoff;
@ -536,18 +534,34 @@ int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, i
sv.delim = delim;
sv.done = false;
// parse
count = 0;
if( npos > 0 ) out_pos[0] = startoff;
while( !sv.done )
{
++count;
if( sv_parse_next(&sv) <= 0 )
return -1;// error
if( npos > count*2 ) out_pos[count*2] = sv.start;
if( npos > count*2+1 ) out_pos[count*2+1] = sv.end;
if( npos > 0 ){
out_pos[0] = startoff;
}
if( npos > 1 ) out_pos[1] = sv.off;
// parse
size_t count = 0;
while( !sv.done ){
++count;
if( sv_parse_next( sv ) <= 0 ){
error = true;
return 0;
}
if( npos > count * 2 ){
out_pos[count * 2] = sv.start;
}
if( npos > count * 2 + 1 ){
out_pos[count * 2 + 1] = sv.end;
}
}
if( npos > 1 ){
out_pos[1] = sv.off;
}
return count;
}
@ -570,18 +584,21 @@ int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, i
/// @param nfields Size of the field array
/// @param opt Options that determine the parsing behaviour
/// @return Number of fields found in the string or -1 if an error occured
int sv_split(char* str, int len, int startoff, char delim, char** out_fields, size_t nfields, enum e_svopt opt)
{
int pos[1024];
int done;
char* end;
int ret = sv_parse(str, len, startoff, delim, pos, ARRAYLENGTH(pos), opt);
size_t sv_split( char* str, size_t len, size_t startoff, char delim, char** out_fields, size_t nfields, int opt, bool& error ){
if( out_fields == nullptr || nfields <= 0 ){
return 0; // nothing to do
}
if( ret == -1 || out_fields == NULL || nfields <= 0 )
return ret; // nothing to do
size_t pos[1024];
size_t ret = sv_parse( str, len, startoff, delim, pos, ARRAYLENGTH( pos ), opt, error );
// An error occurred
if( error ){
return 0;
}
// next line
end = str + pos[1];
char* end = str + pos[1];
if( end[0] == '\0' )
{
*out_fields = end;
@ -614,7 +631,7 @@ int sv_split(char* str, int len, int startoff, char delim, char** out_fields, si
// fields
size_t i = 2;
done = 0;
size_t done = 0;
while( done < ret && nfields > 0 )
{
if( i < ARRAYLENGTH(pos) )
@ -630,7 +647,13 @@ int sv_split(char* str, int len, int startoff, char delim, char** out_fields, si
}
else
{// get more fields
sv_parse(str, len, pos[i-1] + 1, delim, pos, ARRAYLENGTH(pos), opt);
sv_parse( str, len, pos[i - 1] + 1, delim, pos, ARRAYLENGTH( pos ), opt, error );
// An error occurred
if( error ){
return 0;
}
i = 2;
}
}
@ -862,13 +885,11 @@ const char* skip_escaped_c(const char* p)
* @param silent : should we display error if file not found ?
* @return true on success, false if file could not be opened
*/
bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current), bool silent)
{
bool sv_readdb( const char* directory, const char* filename, char delim, size_t mincols, size_t maxcols, size_t maxrows, bool (*parseproc)( char* fields[], size_t columns, size_t current ), bool silent ){
FILE* fp;
int lines = 0;
int entries = 0;
size_t entries = 0;
char** fields; // buffer for fields ([0] is reserved)
int columns, nb_cols;
char path[1024], *line;
const short colsize=512;
@ -883,13 +904,12 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc
}
// allocate enough memory for the maximum requested amount of columns plus the reserved one
nb_cols = maxcols+1;
size_t nb_cols = maxcols + 1;
fields = (char**)aMalloc(nb_cols*sizeof(char*));
line = (char*)aMalloc(nb_cols*colsize);
// process rows one by one
while( fgets(line, maxcols*colsize, fp) )
{
while( fgets( line, static_cast<int>( maxcols * colsize ), fp ) ){
char *match;
lines++;
@ -903,7 +923,13 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc
if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
continue;
columns = sv_split(line, strlen(line), 0, delim, fields, nb_cols, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
bool error;
size_t columns = sv_split( line, strlen( line ), 0, delim, fields, nb_cols, SV_TERMINATE_LF|SV_TERMINATE_CRLF, error );
if( error ){
ShowError( "sv_readdb: error in line %d of \"%s\".\n", lines, path );
continue;
}
if( columns < mincols )
{
@ -965,53 +991,49 @@ void _StringBuf_Init(const char *file, int line, const char *func,StringBuf* sel
}
/// Appends the result of printf to the StringBuf
int _StringBuf_Printf(const char *file, int line, const char *func,StringBuf* self, const char* fmt, ...)
{
int len;
size_t _StringBuf_Printf( const char* file, int line, const char* func, StringBuf* self, const char* fmt, ... ){
va_list ap;
va_start(ap, fmt);
len = _StringBuf_Vprintf(file,line,func,self, fmt, ap);
size_t len = _StringBuf_Vprintf(file,line,func,self, fmt, ap);
va_end(ap);
return len;
}
/// Appends the result of vprintf to the StringBuf
int _StringBuf_Vprintf(const char *file, int line, const char *func,StringBuf* self, const char* fmt, va_list ap)
{
size_t _StringBuf_Vprintf( const char* file, int line, const char* func, StringBuf* self, const char* fmt, va_list ap ){
for(;;)
{
int n, size, off;
va_list apcopy;
/* Try to print in the allocated space. */
size = self->max_ - (self->ptr_ - self->buf_);
size_t size = self->max_ - (self->ptr_ - self->buf_);
va_copy(apcopy, ap);
n = vsnprintf(self->ptr_, size, fmt, apcopy);
int n = vsnprintf( self->ptr_, size, fmt, apcopy );
va_end(apcopy);
/* If that worked, return the length. */
if( n > -1 && n < size )
{
self->ptr_ += n;
return (int)(self->ptr_ - self->buf_);
return self->ptr_ - self->buf_;
}
/* Else try again with more space. */
self->max_ *= 2; // twice the old size
off = (int)(self->ptr_ - self->buf_);
size_t off = self->ptr_ - self->buf_;
self->buf_ = (char*)aRealloc2(self->buf_, self->max_ + 1, file, line, func);
self->ptr_ = self->buf_ + off;
}
}
/// Appends the contents of another StringBuf to the StringBuf
int _StringBuf_Append(const char *file, int line, const char *func,StringBuf* self, const StringBuf* sbuf)
size_t _StringBuf_Append(const char *file, int line, const char *func,StringBuf* self, const StringBuf* sbuf)
{
int available = self->max_ - (self->ptr_ - self->buf_);
int needed = (int)(sbuf->ptr_ - sbuf->buf_);
size_t available = self->max_ - (self->ptr_ - self->buf_);
size_t needed = sbuf->ptr_ - sbuf->buf_;
if( needed >= available )
{
int off = (int)(self->ptr_ - self->buf_);
size_t off = self->ptr_ - self->buf_;
self->max_ += needed;
self->buf_ = (char*)aRealloc2(self->buf_, self->max_ + 1, file, line, func);
self->ptr_ = self->buf_ + off;
@ -1019,26 +1041,26 @@ int _StringBuf_Append(const char *file, int line, const char *func,StringBuf* se
memcpy(self->ptr_, sbuf->buf_, needed);
self->ptr_ += needed;
return (int)(self->ptr_ - self->buf_);
return self->ptr_ - self->buf_;
}
// Appends str to the StringBuf
int _StringBuf_AppendStr(const char *file, int line, const char *func,StringBuf* self, const char* str)
size_t _StringBuf_AppendStr(const char *file, int line, const char *func,StringBuf* self, const char* str)
{
int available = self->max_ - (self->ptr_ - self->buf_);
int needed = (int)strlen(str);
size_t available = self->max_ - ( self->ptr_ - self->buf_ );
size_t needed = strlen( str );
if( needed >= available )
{// not enough space, expand the buffer (minimum expansion = 1024)
int off = (int)(self->ptr_ - self->buf_);
self->max_ += max(needed, 1024);
size_t off = self->ptr_ - self->buf_;
self->max_ += std::max( needed, static_cast<size_t>( 1024 ) );
self->buf_ = (char*)aRealloc2(self->buf_, self->max_ + 1, file, line, func);
self->ptr_ = self->buf_ + off;
}
memcpy(self->ptr_, str, needed);
self->ptr_ += needed;
return (int)(self->ptr_ - self->buf_);
return self->ptr_ - self->buf_;
}
// Returns the length of the data in the Stringbuf

View File

@ -85,11 +85,11 @@ typedef enum e_svopt
struct s_svstate
{
const char* str; //< string to parse
int len; //< string length
int off; //< current offset in the string
int start; //< where the field starts
int end; //< where the field ends
enum e_svopt opt; //< parse options
size_t len; //< string length
size_t off; //< current offset in the string
size_t start; //< where the field starts
size_t end; //< where the field ends
int opt; //< parse options
char delim; //< field delimiter
bool done; //< if all the text has been parsed
};
@ -99,14 +99,14 @@ struct s_svstate
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if done, -1 on error.
int sv_parse_next(struct s_svstate* sv);
int sv_parse_next( s_svstate& sv );
/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.
/// Other position pairs are the start and end of fields.
/// Returns the number of fields found or -1 if an error occurs.
int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt);
size_t sv_parse( const char* str, size_t len, size_t startoff, char delim, size_t* out_pos, size_t npos, int opt, bool& error );
/// Splits a delim-separated string.
/// WARNING: this function modifies the input string
@ -114,7 +114,7 @@ int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, i
/// out_fields[0] is the start of the next line.
/// Other entries are the start of fields (nul-teminated).
/// Returns the number of fields found or -1 if an error occurs.
int sv_split(char* str, int len, int startoff, char delim, char** out_fields, size_t nfields, enum e_svopt opt);
size_t sv_split( char* str, size_t len, size_t startoff, char delim, char** out_fields, size_t nfields, int opt, bool& error );
/// Escapes src to out_dest according to the format of the C compiler.
/// Returns the length of the escaped string.
@ -132,7 +132,7 @@ const char* skip_escaped_c(const char* p);
/// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row.
/// Tracks the progress of the operation (current line number, number of successfully processed rows).
/// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read.
bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current), bool silent);
bool sv_readdb( const char* directory, const char* filename, char delim, size_t mincols, size_t maxcols, size_t maxrows, bool (*parseproc)( char* fields[], size_t columns, size_t current ), bool silent );
/// StringBuf - dynamic string
@ -140,7 +140,7 @@ struct StringBuf
{
char *buf_;
char *ptr_;
unsigned int max_;
size_t max_;
};
typedef struct StringBuf StringBuf;
@ -148,13 +148,13 @@ StringBuf* _StringBuf_Malloc(const char *file, int line, const char *func);
#define StringBuf_Malloc() _StringBuf_Malloc(ALC_MARK)
void _StringBuf_Init(const char *file, int line, const char *func, StringBuf* self);
#define StringBuf_Init(self) _StringBuf_Init(ALC_MARK,self)
int _StringBuf_Printf(const char *file, int line, const char *func, StringBuf* self, const char* fmt, ...);
size_t _StringBuf_Printf( const char* file, int line, const char* func, StringBuf* self, const char* fmt, ... );
#define StringBuf_Printf(self,fmt,...) _StringBuf_Printf(ALC_MARK,self,fmt, ## __VA_ARGS__)
int _StringBuf_Vprintf(const char *file, int line, const char *func,StringBuf* self, const char* fmt, va_list args);
size_t _StringBuf_Vprintf( const char* file, int line, const char* func, StringBuf* self, const char* fmt, va_list args );
#define StringBuf_Vprintf(self,fmt,args) _StringBuf_Vprintf(ALC_MARK,self,fmt,args)
int _StringBuf_Append(const char *file, int line, const char *func, StringBuf* self, const StringBuf *sbuf);
size_t _StringBuf_Append(const char *file, int line, const char *func, StringBuf* self, const StringBuf *sbuf);
#define StringBuf_Append(self,sbuf) _StringBuf_Append(ALC_MARK,self,sbuf)
int _StringBuf_AppendStr(const char *file, int line, const char *func, StringBuf* self, const char* str);
size_t _StringBuf_AppendStr(const char *file, int line, const char *func, StringBuf* self, const char* str);
#define StringBuf_AppendStr(self,str) _StringBuf_AppendStr(ALC_MARK,self,str)
int StringBuf_Length(StringBuf* self);
char* StringBuf_Value(StringBuf* self);

View File

@ -117,12 +117,12 @@ bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){
void rathena::util::string_left_pad_inplace(std::string& str, char padding, size_t num)
{
str.insert(0, min(0, num - str.length()), padding);
str.insert( 0, std::min( static_cast<size_t>( 0 ), num - str.length() ), padding );
}
std::string rathena::util::string_left_pad(const std::string& original, char padding, size_t num)
{
return std::string(num - min(num, original.length()), padding) + original;
return std::string( num - std::min( num, original.length() ), padding ) + original;
}
constexpr char base62_dictionary[] = {

View File

@ -292,7 +292,6 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
*/
int login_mmo_auth(struct login_session_data* sd, bool isServer) {
struct mmo_account acc;
int len;
char ip[16];
ip2str(session[sd->fd]->client_addr, ip);
@ -316,7 +315,7 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
}
len = strnlen(sd->userid, NAME_LENGTH);
size_t len = strnlen(sd->userid, NAME_LENGTH);
// Account creation with _M/_F
if( login_config.new_account_flag ) {

View File

@ -242,16 +242,9 @@ static void logclif_auth_failed(struct login_session_data* sd, int result) {
* @param fd: fd to parse from (client fd)
* @return 0 not enough info transmitted, 1 success
*/
static int logclif_parse_keepalive(int fd){
PACKET_CA_CONNECT_INFO_CHANGED* p = (PACKET_CA_CONNECT_INFO_CHANGED*)RFIFOP( fd, 0 );
if( RFIFOREST( fd ) < sizeof( *p ) ){
return 0;
}
RFIFOSKIP( fd, sizeof( *p ) );
return 1;
static bool logclif_parse_keepalive( int fd, struct login_session_data& ){
// Do nothing
return true;
}
/**
@ -260,28 +253,22 @@ static int logclif_parse_keepalive(int fd){
* @param fd: fd to parse from (client fd)
* @return 0 not enough info transmitted, 1 success
*/
static int logclif_parse_updclhash(int fd, struct login_session_data *sd){
static bool logclif_parse_updclhash( int fd, struct login_session_data& sd ){
PACKET_CA_EXE_HASHCHECK* p = (PACKET_CA_EXE_HASHCHECK*)RFIFOP( fd, 0 );
if( RFIFOREST( fd ) < sizeof( *p ) ){
return 0;
}
sd.has_client_hash = 1;
memcpy( sd.client_hash, p->hash, sizeof( sd.client_hash ) );
sd->has_client_hash = 1;
memcpy( sd->client_hash, p->hash, sizeof( sd->client_hash ) );
RFIFOSKIP( fd, sizeof( *p ) );
return 1;
return true;
}
template <typename P>
int logclif_parse_reqauth_raw( int fd, login_session_data& sd, char* ip ){
static bool logclif_parse_reqauth_raw( int fd, login_session_data& sd ){
P* p = (P*)RFIFOP( fd, 0 );
if( RFIFOREST( fd ) < sizeof( *p ) ){
return 0;
}
char ip[16];
uint32 ipl = session[fd]->client_addr;
ip2str( ipl, ip );
safestrncpy( sd.userid, p->username, sizeof( sd.userid ) );
sd.clienttype = p->clienttype;
@ -295,8 +282,6 @@ int logclif_parse_reqauth_raw( int fd, login_session_data& sd, char* ip ){
sd.passwdenc = 0;
RFIFOSKIP( fd, sizeof( *p ) );
int result = login_mmo_auth( &sd, false );
if( result == -1 ){
@ -305,16 +290,16 @@ int logclif_parse_reqauth_raw( int fd, login_session_data& sd, char* ip ){
logclif_auth_failed( &sd, result );
}
return 1;
return true;
}
template <typename P>
int logclif_parse_reqauth_md5( int fd, login_session_data& sd, char* ip ){
static bool logclif_parse_reqauth_md5( int fd, login_session_data& sd ){
P* p = (P*)RFIFOP( fd, 0 );
if( RFIFOREST( fd ) < sizeof( *p ) ){
return 0;
}
char ip[16];
uint32 ipl = session[fd]->client_addr;
ip2str( ipl, ip );
safestrncpy( sd.userid, p->username, sizeof( sd.userid ) );
sd.clienttype = p->clienttype;
@ -324,11 +309,9 @@ int logclif_parse_reqauth_md5( int fd, login_session_data& sd, char* ip ){
sd.passwdenc = PASSWORDENC;
RFIFOSKIP( fd, sizeof( *p ) );
if( login_config.use_md5_passwds ){
logclif_auth_failed( &sd, 3 ); // send "rejected from server"
return 0;
return false;
}
int result = login_mmo_auth( &sd, false );
@ -339,20 +322,16 @@ int logclif_parse_reqauth_md5( int fd, login_session_data& sd, char* ip ){
logclif_auth_failed( &sd, result );
}
return 1;
return true;
}
template <typename P>
int logclif_parse_reqauth_sso( int fd, login_session_data& sd, char* ip ){
static bool logclif_parse_reqauth_sso( int fd, login_session_data& sd ){
P* p = (P*)RFIFOP( fd, 0 );
if( RFIFOREST( fd ) < sizeof( *p ) ){
return 0;
}
if( RFIFOREST( fd ) < p->packetLength ){
return 0;
}
char ip[16];
uint32 ipl = session[fd]->client_addr;
ip2str( ipl, ip );
size_t token_length = p->packetLength - sizeof( *p );
@ -369,8 +348,6 @@ int logclif_parse_reqauth_sso( int fd, login_session_data& sd, char* ip ){
sd.passwdenc = 0;
RFIFOSKIP( fd, p->packetLength );
int result = login_mmo_auth( &sd, false );
if( result == -1 ){
@ -379,7 +356,17 @@ int logclif_parse_reqauth_sso( int fd, login_session_data& sd, char* ip ){
logclif_auth_failed( &sd, result );
}
return 1;
return true;
}
static void logclif_reqkey_result( int fd, struct login_session_data& sd ){
PACKET_AC_ACK_HASH* p = (PACKET_AC_ACK_HASH*)packet_buffer;
p->packetType = HEADER_AC_ACK_HASH;
p->packetLength = sizeof( *p ) + sd.md5keylen;
strncpy( p->salt, sd.md5key, sd.md5keylen );
socket_send( fd, p );
}
/**
@ -388,25 +375,13 @@ int logclif_parse_reqauth_sso( int fd, login_session_data& sd, char* ip ){
* @param sd: client session
* @return 1 success
*/
static int logclif_parse_reqkey(int fd, struct login_session_data *sd){
static bool logclif_parse_reqkey( int fd, struct login_session_data& sd ){
PACKET_CA_REQ_HASH* p_in = (PACKET_CA_REQ_HASH*)RFIFOP( fd, 0 );
if( RFIFOREST( fd ) < sizeof( *p_in ) ){
return 0;
}
sd.md5keylen = sizeof( sd.md5key );
MD5_Salt( sd.md5keylen, sd.md5key );
RFIFOSKIP( fd, sizeof( *p_in ) );
sd->md5keylen = sizeof( sd->md5key );
MD5_Salt( sd->md5keylen, sd->md5key );
PACKET_AC_ACK_HASH* p_out = (PACKET_AC_ACK_HASH*)packet_buffer;
p_out->packetType = HEADER_AC_ACK_HASH;
p_out->packetLength = sizeof( *p_out ) + sd->md5keylen;
strncpy( p_out->salt, sd->md5key, sd->md5keylen );
socket_send( fd, p_out );
logclif_reqkey_result( fd, sd );
return 1;
}
@ -485,28 +460,43 @@ static int logclif_parse_reqcharconnec(int fd, struct login_session_data *sd, ch
return 1;
}
int logclif_parse_otp_login( int fd, struct login_session_data* sd ){
PACKET_CT_AUTH* p_in = (PACKET_CT_AUTH*)RFIFOP( fd, 0 );
static void logclif_otp_result( int fd ){
PACKET_TC_RESULT p = {};
if( RFIFOREST( fd ) < sizeof( *p_in ) ){
return 0;
}
p.packetType = HEADER_TC_RESULT;
p.packetLength = sizeof( p );
p.type = 0; // normal login
safestrncpy( p.unknown1, "S1000", sizeof( p.unknown1 ) );
safestrncpy( p.unknown2, "token", sizeof( p.unknown2 ) );
RFIFOSKIP( fd, sizeof( *p_in ) );
socket_send( fd, p );
}
PACKET_TC_RESULT p_out = {};
static bool logclif_parse_otp_login( int fd, struct login_session_data& ){
PACKET_CT_AUTH* p = (PACKET_CT_AUTH*)RFIFOP( fd, 0 );
p_out.packetType = HEADER_TC_RESULT;
p_out.packetLength = sizeof( p_out );
p_out.type = 0; // normal login
safestrncpy( p_out.unknown1, "S1000", sizeof( p_out.unknown1 ) );
safestrncpy( p_out.unknown2, "token", sizeof( p_out.unknown2 ) );
socket_send( fd, p_out );
logclif_otp_result( fd );
return 1;
}
class LoginPacketDatabase : public PacketDatabase<login_session_data>{
public:
LoginPacketDatabase(){
this->add( HEADER_CA_CONNECT_INFO_CHANGED, true, sizeof( PACKET_CA_CONNECT_INFO_CHANGED ), logclif_parse_keepalive );
this->add( HEADER_CA_EXE_HASHCHECK, true, sizeof( PACKET_CA_EXE_HASHCHECK ), logclif_parse_updclhash );
this->add( HEADER_CA_LOGIN, true, sizeof( PACKET_CA_LOGIN ), logclif_parse_reqauth_raw<PACKET_CA_LOGIN> );
this->add( HEADER_CA_LOGIN_PCBANG, true, sizeof( PACKET_CA_LOGIN_PCBANG ), logclif_parse_reqauth_raw<PACKET_CA_LOGIN_PCBANG> );
this->add( HEADER_CA_LOGIN_CHANNEL, true, sizeof( PACKET_CA_LOGIN_CHANNEL ), logclif_parse_reqauth_raw<PACKET_CA_LOGIN_CHANNEL> );
this->add( HEADER_CA_LOGIN2, true, sizeof( PACKET_CA_LOGIN2 ), logclif_parse_reqauth_md5<PACKET_CA_LOGIN2> );
this->add( HEADER_CA_LOGIN3, true, sizeof( PACKET_CA_LOGIN3 ), logclif_parse_reqauth_md5<PACKET_CA_LOGIN3> );
this->add( HEADER_CA_LOGIN4, true, sizeof( PACKET_CA_LOGIN4 ), logclif_parse_reqauth_md5<PACKET_CA_LOGIN4> );
this->add( HEADER_CA_SSO_LOGIN_REQ, false, sizeof( PACKET_CA_SSO_LOGIN_REQ ), logclif_parse_reqauth_sso<PACKET_CA_SSO_LOGIN_REQ> );
this->add( HEADER_CA_REQ_HASH, true, sizeof( PACKET_CA_REQ_HASH ), logclif_parse_reqkey );
this->add( HEADER_CT_AUTH, true, sizeof( PACKET_CT_AUTH ), logclif_parse_otp_login );
}
} login_packet_db;
/**
* Entry point from client to log-server.
* Function that checks incoming command, then splits it to the correct handler.
@ -548,70 +538,21 @@ int logclif_parse(int fd) {
while( RFIFOREST(fd) >= 2 )
{
uint16 command = RFIFOW(fd,0);
int next=1;
switch( command ){
// New alive packet: used to verify if client is always alive.
case HEADER_CA_CONNECT_INFO_CHANGED:
next = logclif_parse_keepalive( fd );
break;
// client md5 hash (binary)
case HEADER_CA_EXE_HASHCHECK:
next = logclif_parse_updclhash( fd, sd );
break;
// request client login (raw password)
case HEADER_CA_LOGIN:
// S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B
next = logclif_parse_reqauth_raw<PACKET_CA_LOGIN>( fd, *sd, ip );
break;
case HEADER_CA_LOGIN_PCBANG:
// S 0277 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B
next = logclif_parse_reqauth_raw<PACKET_CA_LOGIN_PCBANG>( fd, *sd, ip );
break;
case HEADER_CA_LOGIN_CHANNEL:
// S 02b0 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B <g_isGravityID>.B
next = logclif_parse_reqauth_raw<PACKET_CA_LOGIN_CHANNEL>( fd, *sd, ip );
break;
// request client login (md5-hashed password)
case HEADER_CA_LOGIN2:
// S 01dd <version>.L <username>.24B <password hash>.16B <clienttype>.B
next = logclif_parse_reqauth_md5<PACKET_CA_LOGIN2>( fd, *sd, ip );
break;
case HEADER_CA_LOGIN3:
// S 01fa <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.B(index of the connection in the clientinfo file (+10 if the command-line contains "pc"))
next = logclif_parse_reqauth_md5<PACKET_CA_LOGIN3>( fd, *sd, ip );
break;
case HEADER_CA_LOGIN4:
// S 027c <version>.L <username>.24B <password hash>.16B <clienttype>.B <adapter address>.13B
next = logclif_parse_reqauth_md5<PACKET_CA_LOGIN4>( fd, *sd, ip );
break;
case HEADER_CA_SSO_LOGIN_REQ:
// S 0825 <packetsize>.W <version>.L <clienttype>.B <userid>.24B <password>.27B <mac>.17B <ip>.15B <token>.?B
next = logclif_parse_reqauth_sso<PACKET_CA_SSO_LOGIN_REQ>( fd, *sd, ip );
break;
// Sending request of the coding key
case HEADER_CA_REQ_HASH:
next = logclif_parse_reqkey( fd, sd );
break;
// OTP token login
case HEADER_CT_AUTH:
next = logclif_parse_otp_login( fd, sd );
break;
// Connection request of a char-server
case 0x2710: logclif_parse_reqcharconnec(fd,sd, ip); return 0; // processing will continue elsewhere
default:
ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
set_eof(fd);
return 0;
if( !login_packet_db.handle( fd, *sd ) ){
return 0;
}
break;
}
if(next==0) return 0; // avoid processing of followup packets (prev was probably incomplete)
}
return 0;
}
/// Constructor destructor
/**

View File

@ -689,6 +689,13 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
t_race2 = status_get_race2(target);
s_defele = (tsd) ? (enum e_element)status_get_element(src) : ELE_NONE;
// When the attacker is a monster, then all bonuses on BF_WEAPON will work and no bonuses on BF_MAGIC
// Does not impact the attack type
if (src && src->type == BL_MOB && battle_config.cardfix_monster_physical) {
flag |= BF_WEAPON;
flag &= ~BF_MAGIC;
}
//Official servers apply the cardfix value on a base of 1000 and round down the reduction/increase
#define APPLY_CARDFIX(damage, fix) { (damage) = (damage) - (int64)(((damage) * (1000 - max(0, fix))) / 1000); }
@ -1383,7 +1390,7 @@ bool battle_status_block_damage(struct block_list *src, struct block_list *targe
unit_set_walkdelay(target, gettick(), delay, 1);
#ifdef RENEWAL
if (sc->getSCE(SC_SHRINK))
sc_start(src, target, SC_STUN, 50, skill_lv, skill_get_time2(skill_id, skill_lv));
sc_start(target, src, SC_STUN, 50, skill_lv, skill_get_time2(skill_id, skill_lv));
#else
if (sc->getSCE(SC_SHRINK) && rnd() % 100 < 5 * sce->val1)
skill_blown(target, src, skill_get_blewcount(CR_SHRINK, 1), -1, BLOWN_NONE);
@ -1846,7 +1853,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
switch (skill_id) {
case HN_SHIELD_CHAIN_RUSH:
case HN_DOUBLEBOWLINGBASH:
damage += damage * 70 / 100;
damage += damage * 120 / 100;
break;
case HN_MEGA_SONIC_BLOW:
case HN_SPIRAL_PIERCE_MAX:
@ -2585,12 +2592,20 @@ void battle_consume_ammo(map_session_data*sd, int skill, int lv)
{
int qty = 1;
if( sd == nullptr ){
return;
}
if (!battle_config.arrow_decrement)
return;
if (skill) {
qty = skill_get_ammo_qty(skill, lv);
if (!qty) qty = 1;
if( skill == NW_MAGAZINE_FOR_ONE && sd->weapontype1 == W_GATLING ){
qty += 4;
}
}
if (sd->equip_index[EQI_AMMO] >= 0) //Qty check should have been done in skill_check_condition
@ -2621,6 +2636,7 @@ static int battle_range_type(struct block_list *src, struct block_list *target,
case BO_ACIDIFIED_ZONE_FIRE_ATK:
case BO_ACIDIFIED_ZONE_GROUND_ATK:
case BO_ACIDIFIED_ZONE_WIND_ATK:
case NW_THE_VIGILANTE_AT_NIGHT:
return BF_LONG;
case NJ_KIRIKAGE: // Cast range mimics NJ_SHADOWJUMP but damage is considered melee
case GC_CROSSIMPACT: // Cast range is 7 cells and player jumps to target but skill is considered melee
@ -2997,6 +3013,18 @@ static bool is_attack_critical(struct Damage* wd, struct block_list *src, struct
case WH_GALESTORM:
if (sc && !sc->getSCE(SC_CALAMITYGALE))
return false;
break;
case NW_ONLY_ONE_BULLET:
case NW_SPIRAL_SHOOTING:
if( sd == nullptr || sd->weapontype1 != W_RIFLE ){
return false;
}
break;
case NW_MAGAZINE_FOR_ONE:
if( sd == nullptr || sd->weapontype1 != W_REVOLVER ){
return false;
}
break;
case SH_CHUL_HO_SONIC_CLAW:
case SH_HOGOGONG_STRIKE:
if (pc_checkskill(sd, SH_COMMUNE_WITH_CHUL_HO) == 0 || !(sc && sc->getSCE(SC_TEMPORARY_COMMUNION)))
@ -3287,8 +3315,25 @@ static bool attack_ignores_def(struct Damage* wd, struct block_list *src, struct
if (sc && sc->getSCE(SC_FUSION))
return true;
if (skill_id == RK_WINDCUTTER && sd && sd->status.weapon == W_2HSWORD)
if( sd != nullptr ){
switch( skill_id ){
case RK_WINDCUTTER:
if( sd->status.weapon == W_2HSWORD ){
return true;
}
break;
case NW_THE_VIGILANTE_AT_NIGHT:
if( sd->status.weapon == W_GATLING ){
return true;
}
break;
case NW_ONLY_ONE_BULLET:
if( sd->status.weapon == W_REVOLVER ){
return true;
}
break;
}
}
if (skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS)
{ //Ignore Defense?
@ -3432,6 +3477,27 @@ int battle_get_weapon_element(struct Damage* wd, struct block_list *src, struct
if (sd && sd->flicker) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER
element = ELE_FIRE;
break;
case NW_BASIC_GRENADE:
case NW_HASTY_FIRE_IN_THE_HOLE:
case NW_GRENADES_DROPPING:
case NW_MISSION_BOMBARD:
// Night Watch Grenade Fragment elementals affecting those skills.
if( sc != nullptr ){
if( sc->getSCE( SC_GRENADE_FRAGMENT_1 ) != nullptr ){
element = ELE_WATER;
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_2 ) != nullptr ){
element = ELE_WIND;
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_3 ) != nullptr ){
element = ELE_EARTH;
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_4 ) != nullptr ){
element = ELE_FIRE;
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_5 ) != nullptr ){
element = ELE_DARK;
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_6 ) != nullptr ){
element = ELE_HOLY;
}
}
break;
}
if (sc && sc->getSCE(SC_GOLDENE_FERSE) && ((!skill_id && (rnd() % 100 < sc->getSCE(SC_GOLDENE_FERSE)->val4)) || skill_id == MH_STAHL_HORN))
@ -4196,7 +4262,7 @@ static void battle_calc_multi_attack(struct Damage* wd, struct block_list *src,s
break;
}
case ABC_FRENZY_SHOT:
if( rnd()%100 < 5 * skill_lv ){
if( rnd_chance( 5 * skill_lv, 100 ) ){
wd->div_ = 3;
}
break;
@ -4210,6 +4276,18 @@ static void battle_calc_multi_attack(struct Damage* wd, struct block_list *src,s
}
break;
#endif
case NW_SPIRAL_SHOOTING:
if (sd && sd->weapontype1 == W_GRENADE)
wd->div_ += 1;
break;
case NW_MAGAZINE_FOR_ONE:
if (sd && sd->weapontype1 == W_GATLING)
wd->div_ += 4;
break;
case NW_THE_VIGILANTE_AT_NIGHT:
if (sd && sd->weapontype1 == W_GATLING)
wd->div_ += 3;
break;
}
}
@ -5417,10 +5495,12 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
break;
case SU_LUNATICCARROTBEAT:
case SU_LUNATICCARROTBEAT2:
skillratio += 100 + 100 * skill_lv + sstatus->str * 5; // !TODO: What's the STR bonus?
RE_LVL_DMOD(100);
skillratio += 100 + 100 * skill_lv;
if (sd && pc_checkskill(sd, SU_SPIRITOFLIFE))
skillratio += skillratio * status_get_hp(src) / status_get_max_hp(src);
if (status_get_lv(src) > 99)
skillratio += sstatus->str;
RE_LVL_DMOD(100);
break;
case SU_SVG_SPIRIT:
skillratio += 150 + 150 * skill_lv;
@ -5456,7 +5536,8 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += skillratio * sc->getSCE(SC_LIGHTOFSTAR)->val2 / 100;
break;
case DK_SERVANTWEAPON_ATK:
skillratio += -100 + 500 + 400 * skill_lv + 5 * sstatus->pow;
skillratio += -100 + 600 + 850 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case DK_SERVANT_W_PHANTOM:
@ -5469,7 +5550,7 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
break;
case DK_HACKANDSLASHER:
case DK_HACKANDSLASHER_ATK:
skillratio += -100 + 200 + 750 * skill_lv;
skillratio += -100 + 350 + 820 * skill_lv;
skillratio += 7 * sstatus->pow;
RE_LVL_DMOD(100);
break;
@ -5480,7 +5561,8 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case DK_MADNESS_CRUSHER:
skillratio += -100 + 350 + 1600 * skill_lv + 10 * sstatus->pow;
skillratio += -100 + 1000 + 3800 * skill_lv;
skillratio += 10 * sstatus->pow;
if( sd != nullptr ){
int16 index = sd->equip_index[EQI_HAND_R];
@ -5493,18 +5575,25 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio *= 2;
break;
case DK_STORMSLASH:
skillratio += -100 + 200 + 400 * skill_lv + 5 * sstatus->pow;
skillratio += -100 + 300 + 750 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
if (sc && sc->getSCE(SC_GIANTGROWTH) && rnd_chance(60, 100))
skillratio *= 2;
break;
case DK_DRAGONIC_BREATH:
skillratio += -100 + 50 + 350 * skill_lv;
skillratio += 5 * sstatus->pow;
//TODO: needs official HP/SP scaling [Muh]
skillratio += sstatus->max_hp / 500 + status_get_max_sp(src) / 40;
if (sc && sc->getSCE(SC_DRAGONIC_AURA))
skillratio += sstatus->max_hp / 500 + status_get_max_sp(src) / 40;
skillratio += 7 * sstatus->pow;
if (sc && sc->getSCE(SC_DRAGONIC_AURA)) {
skillratio += 3 * sstatus->pow;
skillratio += (skill_lv * (sstatus->max_hp * 25 / 100) * 7) / 100; // Skill level x 0.07 x ((MaxHP / 4) + (MaxSP / 2))
skillratio += (skill_lv * (sstatus->max_sp * 50 / 100) * 7) / 100;
} else {
skillratio += (skill_lv * (sstatus->max_hp * 25 / 100) * 5) / 100; // Skill level x 0.05 x ((MaxHP / 4) + (MaxSP / 2))
skillratio += (skill_lv * (sstatus->max_sp * 50 / 100) * 5) / 100;
}
RE_LVL_DMOD(100);
break;
case IQ_OLEUM_SANCTUM:
@ -5518,10 +5607,11 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case IQ_EXPOSION_BLASTER:
skillratio += -100 + 2400 * skill_lv + 10 * sstatus->pow;
skillratio += -100 + 450 + 2600 * skill_lv;
skillratio += 10 * sstatus->pow;
if( tsc != nullptr && tsc->getSCE( SC_HOLY_OIL ) ){
skillratio += 350 + 1050 * skill_lv;
skillratio += 950 * skill_lv;
}
RE_LVL_DMOD(100);
@ -5543,7 +5633,8 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case IQ_THIRD_PUNISH:
skillratio += -100 + 350 + 1500 * skill_lv + 10 * sstatus->pow;
skillratio += -100 + 450 + 1800 * skill_lv;
skillratio += 10 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case IQ_THIRD_FLAME_BOMB:
@ -5564,22 +5655,22 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += skillratio * i / 100;
break;
case IG_SHIELD_SHOOTING:
skillratio += -100 + 650 + 2850 * skill_lv;
skillratio += 7 * sstatus->pow;
skillratio += skill_lv * 50 * pc_checkskill( sd, IG_SHIELD_MASTERY );
skillratio += -100 + 1000 + 3500 * skill_lv;
skillratio += 10 * sstatus->pow;
skillratio += skill_lv * 150 * pc_checkskill( sd, IG_SHIELD_MASTERY );
if (sd) { // Damage affected by the shield's weight and refine. Need official formula. [Rytech]
short index = sd->equip_index[EQI_HAND_L];
if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR) {
skillratio += (sd->inventory_data[index]->weight * 7 / 6) / 10;
skillratio += sd->inventory.u.items_inventory[index].refine * 25;
skillratio += sd->inventory.u.items_inventory[index].refine * 100;
}
}
RE_LVL_DMOD(100);
break;
case IG_OVERSLASH:
skillratio += -100 + 160 * skill_lv;
skillratio += pc_checkskill(sd, IG_SPEAR_SWORD_M) * 25 * skill_lv;
skillratio += -100 + 220 * skill_lv;
skillratio += pc_checkskill(sd, IG_SPEAR_SWORD_M) * 50 * skill_lv;
skillratio += 7 * sstatus->pow;
RE_LVL_DMOD(100);
if ((i = pc_checkskill_imperial_guard(sd, 3)) > 0)
@ -5603,7 +5694,7 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case SHC_SAVAGE_IMPACT:
skillratio += -100 + 90 * skill_lv + 5 * sstatus->pow;
skillratio += -100 + 105 * skill_lv + 5 * sstatus->pow;
if( sc != nullptr && sc->getSCE( SC_SHADOW_EXCEED ) ){
skillratio += 20 * skill_lv + 3 * sstatus->pow; // !TODO: check POW ratio
@ -5612,19 +5703,19 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case SHC_ETERNAL_SLASH:
skillratio += -100 + 265 * skill_lv + 2 * sstatus->pow;
skillratio += -100 + 300 * skill_lv + 2 * sstatus->pow;
if( sc != nullptr && sc->getSCE( SC_SHADOW_EXCEED ) ){
skillratio += 100 * skill_lv + sstatus->pow;
skillratio += 120 * skill_lv + sstatus->pow;
}
RE_LVL_DMOD(100);
break;
case SHC_SHADOW_STAB:
skillratio += -100 + 350 * skill_lv + 5 * sstatus->pow;
skillratio += -100 + 550 * skill_lv + 5 * sstatus->pow;
if( sc && sc->getSCE( SC_CLOAKINGEXCEED ) ){
skillratio += 50 * skill_lv + 2 * sstatus->pow;
skillratio += 100 * skill_lv + 2 * sstatus->pow;
}
RE_LVL_DMOD(100);
@ -5640,14 +5731,15 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case MT_AXE_STOMP:
skillratio += -100 + 400 + 950 * skill_lv + 5 * sstatus->pow;
skillratio += -100 + 450 + 1150 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case MT_MIGHTY_SMASH:
skillratio += -100 + 25 + 180 * skill_lv;
skillratio += -100 + 80 + 240 * skill_lv;
skillratio += 5 * sstatus->pow;
if (sc && sc->getSCE(SC_AXE_STOMP)) {
skillratio += 25;
skillratio += 20;
skillratio += 5 * sstatus->pow;
}
RE_LVL_DMOD(100);
@ -5663,17 +5755,17 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case MT_SPARK_BLASTER:
skillratio += -100 + 250 + 900 * skill_lv;
skillratio += -100 + 600 + 1400 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case MT_TRIPLE_LASER:
skillratio += -100 + 550 + 900 * skill_lv;
skillratio += -100 + 650 + 1150 * skill_lv;
skillratio += 12 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case ABC_ABYSS_DAGGER:
skillratio += -100 + 100 + 900 * skill_lv;
skillratio += -100 + 350 + 1400 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
break;
@ -5682,20 +5774,22 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case ABC_CHAIN_REACTION_SHOT:
skillratio += -100 + 850 * skill_lv + 15 * sstatus->con;
skillratio += -100 + 850 * skill_lv;
skillratio += 15 * sstatus->con;
RE_LVL_DMOD(100);
break;
case ABC_CHAIN_REACTION_SHOT_ATK:
skillratio += -100 + 600 + 2350 * skill_lv + 15 * sstatus->con;
skillratio += -100 + 800 + 2550 * skill_lv;
skillratio += 15 * sstatus->con;
RE_LVL_DMOD(100);
break;
case ABC_DEFT_STAB:
skillratio += -100 + 250 + 350 * skill_lv;
skillratio += 5 * sstatus->pow;
skillratio += -100 + 700 + 550 * skill_lv;
skillratio += 7 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case ABC_FRENZY_SHOT:
skillratio += -100 + 150 + 600 * skill_lv;
skillratio += -100 + 250 + 800 * skill_lv;
skillratio += 15 * sstatus->con;
RE_LVL_DMOD(100);
break;
@ -5714,17 +5808,19 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case WH_GALESTORM:
skillratio += -100 + 1000 * skill_lv + 10 * sstatus->con;
skillratio += -100 + 1350 * skill_lv;
skillratio += 10 * sstatus->con;
RE_LVL_DMOD(100);
if (sc && sc->getSCE(SC_CALAMITYGALE) && (tstatus->race == RC_BRUTE || tstatus->race == RC_FISH))
skillratio += skillratio * 50 / 100;
break;
case WH_CRESCIVE_BOLT:
skillratio += -100 + 400 + 900 * skill_lv + 5 * sstatus->con;
skillratio += -100 + 500 + 1300 * skill_lv;
skillratio += 5 * sstatus->con;
RE_LVL_DMOD(100);
if (sc) {
if (sc->getSCE(SC_CRESCIVEBOLT))
skillratio += skillratio * (10 * sc->getSCE(SC_CRESCIVEBOLT)->val1) / 100;
skillratio += skillratio * (20 * sc->getSCE(SC_CRESCIVEBOLT)->val1) / 100;
if (sc->getSCE(SC_CALAMITYGALE)) {
skillratio += skillratio * 20 / 100;
@ -5762,7 +5858,7 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case BO_EXPLOSIVE_POWDER:
skillratio += -100 + 400 + 550 * skill_lv;
skillratio += -100 + 500 + 650 * skill_lv;
skillratio += 5 * sstatus->pow;
if (sc && sc->getSCE(SC_RESEARCHREPORT))
skillratio += 100 * skill_lv;
@ -5812,16 +5908,13 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
}
break;
case TR_RHYTHMSHOOTING:
skillratio += -100 + 450 + 650 * skill_lv;
skillratio += -100 + 550 + 950 * skill_lv;
if (sd && pc_checkskill(sd, TR_STAGE_MANNER) > 0)
skillratio += 5 * sstatus->con;
if (tsc && tsc->getSCE(SC_SOUNDBLEND)) {
if (skill_lv == 4)
skillratio += 830; // Typo in skill description ?
else
skillratio += 350 + 100 * skill_lv;
skillratio += 300 + 100 * skill_lv;
skillratio += 2 * sstatus->con;
}
@ -5841,7 +5934,7 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += -100 + 50000;
break;
case HN_SPIRAL_PIERCE_MAX:
skillratio += -100 + 700 + 800 * skill_lv;
skillratio += -100 + 1000 + 1500 * skill_lv;
skillratio += pc_checkskill(sd, HN_SELFSTUDY_TATICS) * 3 * skill_lv;
skillratio += 5 * sstatus->pow;
switch (status_get_size(target)){
@ -5858,7 +5951,7 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case HN_SHIELD_CHAIN_RUSH:
skillratio += -100 + 700 + 500 * skill_lv;
skillratio += -100 + 850 + 1050 * skill_lv;
skillratio += pc_checkskill(sd, HN_SELFSTUDY_TATICS) * 3 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
@ -5872,11 +5965,90 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
RE_LVL_DMOD(100);
break;
case HN_DOUBLEBOWLINGBASH:
skillratio += -100 + 200 + 300 * skill_lv;
skillratio += -100 + 250 + 400 * skill_lv;
skillratio += pc_checkskill(sd, HN_SELFSTUDY_TATICS) * 3 * skill_lv;
skillratio += 5 * sstatus->pow;
RE_LVL_DMOD(100);
break;
case NW_HASTY_FIRE_IN_THE_HOLE:
skillratio += -100 + 1500 + 1500 * skill_lv;
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 20;
skillratio += 5 * sstatus->con;
RE_LVL_DMOD(100);
break;
case NW_BASIC_GRENADE:
skillratio += -100 + 1500 + 2100 * skill_lv;
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 50;
skillratio += 5 * sstatus->con;
RE_LVL_DMOD(100);
break;
case NW_GRENADES_DROPPING:
skillratio += -100 + 550 + 850 * skill_lv;
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 30;
skillratio += 5 * sstatus->con;
RE_LVL_DMOD(100);
break;
case NW_WILD_FIRE:
skillratio += -100 + 1500 + 3000 * skill_lv;
skillratio += 5 * sstatus->con;
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 500 * skill_lv;
if (sd && sd->weapontype1 == W_SHOTGUN)
skillratio += 200 * skill_lv;
RE_LVL_DMOD(100);
break;
case NW_MAGAZINE_FOR_ONE:
skillratio += -100 + 250 + 500 * skill_lv;
skillratio += 5 * sstatus->con;
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 100 * skill_lv;
if (sd && sd->weapontype1 == W_REVOLVER)
skillratio += 50 + 300 * skill_lv;
RE_LVL_DMOD(100);
break;
case NW_SPIRAL_SHOOTING:
skillratio += -100 + 1200 + 1700 * skill_lv;
skillratio += 5 * sstatus->con;
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 150 * skill_lv;
if (sd && sd->weapontype1 == W_RIFLE)
skillratio += 200 + 1100 * skill_lv;
RE_LVL_DMOD(100);
break;
case NW_ONLY_ONE_BULLET:
skillratio += -100 + 1200 + 3000 * skill_lv;
skillratio += 5 * sstatus->con;
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 350 * skill_lv;
if (sd && sd->weapontype1 == W_REVOLVER) {
skillratio += 400 * skill_lv;
}
RE_LVL_DMOD(100);
break;
case NW_THE_VIGILANTE_AT_NIGHT:
if (sd && sd->weapontype1 == W_GATLING) {
skillratio += -100 + 300 * skill_lv;
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 100 * skill_lv;
} else {
skillratio += -100 + 800 + 700 * skill_lv;
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 200 * skill_lv;
}
skillratio += 5 * sstatus->con;
RE_LVL_DMOD(100);
break;
case NW_MISSION_BOMBARD:
if( wd->miscflag&SKILL_ALTDMG_FLAG ){
skillratio += -100 + 5000 + 1800 * skill_lv;
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 100;
}else{
skillratio += -100 + 800 + 200 * skill_lv;
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 30;
}
skillratio += 5 * sstatus->con;
RE_LVL_DMOD(100);
break;
case SH_CHUL_HO_SONIC_CLAW:
skillratio += -100 + 850 + 1650 * skill_lv;
skillratio += 50 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
@ -6135,6 +6307,8 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
if (sc->getSCE(SC_MIRACLE))
anger_id = 2; // Always treat all monsters as star flagged monster when in miracle state
if (sc->getSCE(SC_HIDDEN_CARD) && (wd->flag&BF_LONG) == BF_LONG)
RE_ALLATK_ADDRATE(wd, sc->getSCE(SC_HIDDEN_CARD)->val3);
}
if ((wd->flag&(BF_LONG|BF_MAGIC)) == BF_LONG) {
@ -6850,10 +7024,6 @@ static struct Damage initialize_weapon_data(struct block_list *src, struct block
if (sc && sc->getSCE(SC_E_SLASH_COUNT))
wd.div_ = sc->getSCE(SC_E_SLASH_COUNT)->val1;
break;
case SHC_SHADOW_STAB:
if (wd.miscflag == 2)
wd.div_ = 3;
break;
case SHC_IMPACT_CRATER:
if (sc && sc->getSCE(SC_ROLLINGCUTTER))
wd.div_ = sc->getSCE(SC_ROLLINGCUTTER)->val1;
@ -7597,7 +7767,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if ((skill_id == MG_FIREBOLT && sc->getSCE(SC_FLAMETECHNIC_OPTION)) ||
(skill_id == MG_COLDBOLT && sc->getSCE(SC_COLD_FORCE_OPTION)) ||
(skill_id == MG_LIGHTNINGBOLT && sc->getSCE(SC_GRACE_BREEZE_OPTION)))
skillratio *= 2;
skillratio *= 5;
if (sc->getSCE(SC_SPELLFIST) && mflag & BF_SHORT) {
skillratio += (sc->getSCE(SC_SPELLFIST)->val3 * 100) + (sc->getSCE(SC_SPELLFIST)->val1 * 50 - 50) - 100; // val3 = used bolt level, val1 = used spellfist level. [Rytech]
@ -7650,7 +7820,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case WZ_EARTHSPIKE:
skillratio += 100;
if (sc && sc->getSCE(SC_EARTH_CARE_OPTION))
skillratio += skillratio * 80 / 100;
skillratio += skillratio * 800 / 100;
break;
#endif
case HW_NAPALMVULCAN:
@ -7917,7 +8087,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio += (sd ? sd->status.job_level : 0);
if (sc->getSCE(SC_DEEP_POISONING_OPTION))
skillratio += skillratio * 50 / 100;
skillratio += skillratio * 1500 / 100;
}
break;
case NPC_CLOUD_KILL:
@ -8063,7 +8233,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
break;
case AG_SOUL_VC_STRIKE:
skillratio += -100 + 250 * skill_lv + 3 * sstatus->spl;
skillratio += -100 + 300 * skill_lv + 3 * sstatus->spl;
RE_LVL_DMOD(100);
break;
case AG_STRANTUM_TREMOR:
@ -8122,7 +8292,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
RE_LVL_DMOD(100);
break;
case AG_ROCK_DOWN:
skillratio += -100 + 1200 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 1550 * skill_lv + 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_CLIMAX ) ){
skillratio += 300 * skill_lv;
@ -8131,7 +8301,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
RE_LVL_DMOD(100);
break;
case AG_STORM_CANNON:
skillratio += -100 + 1200 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 1550 * skill_lv + 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_CLIMAX ) ){
skillratio += 300 * skill_lv;
@ -8140,15 +8310,15 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
RE_LVL_DMOD(100);
break;
case AG_CRIMSON_ARROW:
skillratio += -100 + 350 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 400 * skill_lv + 5 * sstatus->spl;
RE_LVL_DMOD(100);
break;
case AG_CRIMSON_ARROW_ATK:
skillratio += -100 + 700 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 750 * skill_lv + 5 * sstatus->spl;
RE_LVL_DMOD(100);
break;
case AG_FROZEN_SLASH:
skillratio += -100 + 400 + 900 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 450 + 950 * skill_lv + 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_CLIMAX ) ){
skillratio += 150 + 350 * skill_lv;
@ -8166,9 +8336,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
case IG_CROSS_RAIN:
if( sc && sc->getSCE( SC_HOLY_S ) ){
skillratio += -100 + ( 450 + 15 * pc_checkskill( sd, IG_SPEAR_SWORD_M ) ) * skill_lv;
skillratio += -100 + ( 650 + 15 * pc_checkskill( sd, IG_SPEAR_SWORD_M ) ) * skill_lv;
}else{
skillratio += -100 + ( 320 + 10 * pc_checkskill( sd, IG_SPEAR_SWORD_M ) ) * skill_lv;
skillratio += -100 + ( 450 + 10 * pc_checkskill( sd, IG_SPEAR_SWORD_M ) ) * skill_lv;
}
skillratio += 7 * sstatus->spl;
RE_LVL_DMOD(100);
@ -8193,9 +8363,11 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
RE_LVL_DMOD(100);
break;
case CD_FRAMEN:
skillratio += -100 + (950 + 5 * pc_checkskill(sd,CD_FIDUS_ANIMUS)) * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 1300 * skill_lv;
skillratio += 5 * pc_checkskill(sd,CD_FIDUS_ANIMUS) * skill_lv;
skillratio += 5 * sstatus->spl;
if (tstatus->race == RC_UNDEAD || tstatus->race == RC_DEMON)
skillratio += 100 * skill_lv;
skillratio += 50 * skill_lv;
RE_LVL_DMOD(100);
break;
case AG_DESTRUCTIVE_HURRICANE_CLIMAX:// Is this affected by BaseLV and SPL too??? [Rytech]
@ -8203,20 +8375,23 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
RE_LVL_DMOD(100);
break;
case ABC_ABYSS_STRIKE:
skillratio += -100 + 2200 * skill_lv + 10 * sstatus->spl;
skillratio += -100 + 2650 * skill_lv;
skillratio += 10 * sstatus->spl;
if (tstatus->race == RC_DEMON || tstatus->race == RC_ANGEL)
skillratio += 150 * skill_lv;
skillratio += 200 * skill_lv;
RE_LVL_DMOD(100);
break;
case ABC_ABYSS_SQUARE:
skillratio += -100 + ( 570 + 20 * pc_checkskill( sd, ABC_MAGIC_SWORD_M ) ) * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 750 * skill_lv;
skillratio += 40 * pc_checkskill( sd, ABC_MAGIC_SWORD_M ) * skill_lv;
skillratio += 5 * sstatus->spl;
RE_LVL_DMOD(100);
break;
case TR_METALIC_FURY:
skillratio += -100 + 2600 * skill_lv;
skillratio += -100 + 3850 * skill_lv;
// !Todo: skill affected by SPL (without SC_SOUNDBLEND) as well?
if (tsc && tsc->getSCE(SC_SOUNDBLEND)) {
skillratio += 1000 * skill_lv;
skillratio += 800 * skill_lv;
skillratio += 2 * pc_checkskill(sd, TR_STAGE_MANNER) * sstatus->spl;
}
RE_LVL_DMOD(100);
@ -8232,52 +8407,60 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
break;
case EM_DIAMOND_STORM:
skillratio += -100 + 400 + 1550 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 500 + 2400 * skill_lv;
skillratio += 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_SUMMON_ELEMENTAL_DILUVIO ) ){
skillratio += 5000 + 250 * skill_lv + 5 * sstatus->spl;
skillratio += 7300 + 200 * skill_lv;
skillratio += 5 * sstatus->spl;
}
RE_LVL_DMOD(100);
break;
case EM_LIGHTNING_LAND:
skillratio += -100 + 500 + 650 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 700 + 1100 * skill_lv;
skillratio += 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_SUMMON_ELEMENTAL_PROCELLA ) ){
skillratio += 400 * skill_lv;
skillratio += 200 * skill_lv;
}
RE_LVL_DMOD(100);
break;
case EM_VENOM_SWAMP:
skillratio += -100 + 500 + 650 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 700 + 1100 * skill_lv;
skillratio += 5 * sstatus->spl;
if( sc && sc->getSCE( SC_SUMMON_ELEMENTAL_SERPENS ) ){
skillratio += 400 * skill_lv;
skillratio += 200 * skill_lv;
}
RE_LVL_DMOD(100);
break;
case EM_CONFLAGRATION:
skillratio += -100 + 500 + 650 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 700 + 1100 * skill_lv;
skillratio += 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_SUMMON_ELEMENTAL_ARDOR ) ){
skillratio += 400 * skill_lv;
skillratio += 200 * skill_lv;
}
RE_LVL_DMOD(100);
break;
case EM_TERRA_DRIVE:
skillratio += -100 + 400 + 1550 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 500 + 2400 * skill_lv;
skillratio += 5 * sstatus->spl;
if( sc != nullptr && sc->getSCE( SC_SUMMON_ELEMENTAL_TERREMOTUS ) ){
skillratio += 5000 + 250 * skill_lv + 5 * sstatus->spl;
skillratio += 7300 + 200 * skill_lv;
skillratio += 5 * sstatus->spl;
}
RE_LVL_DMOD(100);
break;
case ABC_FROM_THE_ABYSS_ATK:
skillratio += -100 + 100 + 500 * skill_lv + 5 * sstatus->spl;
skillratio += -100 + 150 + 650 * skill_lv;
skillratio += 5 * sstatus->spl;
RE_LVL_DMOD(100);
break;
case EM_ELEMENTAL_BUSTER_FIRE:
@ -8285,7 +8468,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case EM_ELEMENTAL_BUSTER_WIND:
case EM_ELEMENTAL_BUSTER_GROUND:
case EM_ELEMENTAL_BUSTER_POISON:
skillratio += -100 + 500 + 2200 * skill_lv + 10 * sstatus->spl;
skillratio += -100 + 550 + 2650 * skill_lv;
skillratio += 10 * sstatus->spl;
if (tstatus->race == RC_FORMLESS || tstatus->race == RC_DRAGON)
skillratio += 150 * skill_lv;
RE_LVL_DMOD(100);
@ -8331,7 +8515,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
RE_LVL_DMOD(100);
break;
case HN_HELLS_DRIVE:
skillratio += -100 + 1500 + 700 * skill_lv;
skillratio += -100 + 1700 + 900 * skill_lv;
skillratio += pc_checkskill(sd, HN_SELFSTUDY_SOCERY) * 4 * skill_lv;
skillratio += 5 * sstatus->spl;
RE_LVL_DMOD(100);
@ -9800,7 +9984,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if( sc ){
if( sc->getSCE( SC_SERVANTWEAPON ) && sd->servantball > 0 && rnd() % 100 < ( 3 * sc->getSCE( SC_SERVANTWEAPON )->val1 ) ){
if( sc->getSCE( SC_SERVANTWEAPON ) && sd->servantball > 0 && rnd_chance( 5 * sc->getSCE( SC_SERVANTWEAPON )->val1, 100 ) ){
uint16 skill_id = DK_SERVANTWEAPON_ATK;
uint16 skill_lv = sc->getSCE(SC_SERVANTWEAPON)->val1;
@ -9822,7 +10006,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
sd->state.autocast = 0;
}
if( sc->getSCE(SC_ABYSSFORCEWEAPON) && sd->abyssball > 0 && rnd() % 100 < 15 ){
if( sc->getSCE(SC_ABYSSFORCEWEAPON) && sd->abyssball > 0 && rnd_chance( 25, 100 ) ){
uint16 skill_id = ABC_FROM_THE_ABYSS_ATK;
uint16 skill_lv = sc->getSCE(SC_ABYSSFORCEWEAPON)->val1;
@ -9845,6 +10029,113 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
sd->state.autocast = 0;
}
if( sc->getSCE( SC_AUTO_FIRING_LAUNCHER ) ){
uint16 skill_id;
uint16 skill_lv;
switch( sc->getSCE( SC_AUTO_FIRING_LAUNCHER )->val1 ){
case 1:
skill_id = NW_BASIC_GRENADE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 6, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
break;
case 2:
skill_id = NW_BASIC_GRENADE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 7, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
break;
case 3:
skill_id = NW_HASTY_FIRE_IN_THE_HOLE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 3, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
skill_id = NW_BASIC_GRENADE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 8, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
break;
case 4:
skill_id = NW_HASTY_FIRE_IN_THE_HOLE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 5, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
skill_id = NW_BASIC_GRENADE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 9, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
break;
case 5:
skill_id = NW_GRENADES_DROPPING;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 3, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
skill_id = NW_HASTY_FIRE_IN_THE_HOLE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 7, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
skill_id = NW_BASIC_GRENADE;
skill_lv = pc_checkskill( sd, skill_id );
if( skill_lv > 0 && rnd_chance( 10, 100 ) ){
sd->state.autocast = 1;
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
sd->state.autocast = 0;
}
break;
}
}
// Autocasted skills from super elemental supportive buffs.
if (sc->getSCE(SC_FLAMETECHNIC_OPTION) && rnd() % 100 < 7)
battle_autocast_elembuff_skill(sd, target, MG_FIREBOLT, tick, flag);
@ -10366,6 +10657,7 @@ static const struct _battle_data {
{ "delay_dependon_agi", &battle_config.delay_dependon_agi, 0, 0, 1, },
{ "skill_delay_attack_enable", &battle_config.sdelay_attack_enable, 0, 0, 1, },
{ "left_cardfix_to_right", &battle_config.left_cardfix_to_right, 0, 0, 1, },
{ "cardfix_monster_physical", &battle_config.cardfix_monster_physical, 1, 0, 1, },
{ "skill_add_range", &battle_config.skill_add_range, 0, 0, INT_MAX, },
{ "skill_out_range_consume", &battle_config.skill_out_range_consume, 1, 0, 1, },
{ "skillrange_by_distance", &battle_config.skillrange_by_distance, ~BL_PC, BL_NUL, BL_ALL, },

View File

@ -150,6 +150,7 @@ struct Battle_Config
int delay_dependon_dex, delay_dependon_agi;
int sdelay_attack_enable;
int left_cardfix_to_right;
int cardfix_monster_physical;
int skill_add_range;
int skill_out_range_consume;
int skill_amotion_leniency;

View File

@ -22716,7 +22716,7 @@ void clif_parse_stylist_close( int fd, map_session_data* sd ){
}
void clif_inventory_expansion_info( map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
nullpo_retv( sd );
struct PACKET_ZC_EXTEND_BODYITEM_SIZE p = {};
@ -22737,7 +22737,7 @@ enum class e_inventory_expansion_response : uint8{
};
void clif_inventory_expansion_response( map_session_data* sd, e_inventory_expansion_response response ){
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
nullpo_retv( sd );
struct PACKET_ZC_ACK_OPEN_MSGBOX_EXTEND_BODYITEM_SIZE p = {};
@ -22751,7 +22751,7 @@ void clif_inventory_expansion_response( map_session_data* sd, e_inventory_expans
}
void clif_parse_inventory_expansion_request( int fd, map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
// Check if player is dead or busy with other stuff
if( pc_isdead( sd ) || pc_cant_act( sd ) ){
clif_inventory_expansion_response( sd, e_inventory_expansion_response::BUSY );
@ -22820,7 +22820,7 @@ enum class e_inventory_expansion_result : uint8{
};
void clif_inventory_expansion_result( map_session_data* sd, e_inventory_expansion_result result ){
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
nullpo_retv( sd );
struct PACKET_ZC_ACK_EXTEND_BODYITEM_SIZE p = {};
@ -22837,7 +22837,7 @@ void clif_inventory_expansion_result( map_session_data* sd, e_inventory_expansio
}
void clif_parse_inventory_expansion_confirm( int fd, map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
if( sd->state.inventory_expansion_confirmation == 0 ){
return;
}
@ -22888,7 +22888,7 @@ void clif_parse_inventory_expansion_confirm( int fd, map_session_data* sd ){
}
void clif_parse_inventory_expansion_reject( int fd, map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
sd->state.inventory_expansion_confirmation = 0;
sd->state.inventory_expansion_amount = 0;
#endif
@ -25188,6 +25188,57 @@ void clif_parse_reset_skill( int fd, map_session_data* sd ){
#endif
}
void clif_set_dialog_align(map_session_data& sd, int npcid, e_say_dialog_align align)
{
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20221024
PACKET_ZC_DIALOG_TEXT_ALIGN p = {};
p.PacketType = HEADER_ZC_DIALOG_TEXT_ALIGN;
p.align = align;
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif // PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103 || PACKETVER_ZERO_NUM >= 20221024
}
void clif_set_npc_window_size(map_session_data& sd, int width, int height)
{
#if PACKETVER_MAIN_NUM >= 20220504
PACKET_ZC_DIALOG_WINDOW_SIZE p = {};
p.PacketType = HEADER_ZC_DIALOG_WINDOW_SIZE;
p.width = width;
p.height = height;
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif // PACKETVER_MAIN_NUM >= 20220504
}
void clif_set_npc_window_pos(map_session_data& sd, int x, int y)
{
#if PACKETVER_MAIN_NUM >= 20220504
PACKET_ZC_DIALOG_WINDOW_POS p = {};
p.PacketType = HEADER_ZC_DIALOG_WINDOW_POS;
p.x = x;
p.y = y;
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif // PACKETVER_MAIN_NUM >= 20220504
}
void clif_set_npc_window_pos_percent(map_session_data& sd, int x, int y)
{
#if PACKETVER_MAIN_NUM >= 20220504
PACKET_ZC_DIALOG_WINDOW_POS2 p = {};
p.PacketType = HEADER_ZC_DIALOG_WINDOW_POS2;
p.x = x;
p.y = y;
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif // PACKETVER_MAIN_NUM >= 20220504
}
/*==========================================
* Main client packet processing function
*------------------------------------------*/

View File

@ -1254,4 +1254,9 @@ void clif_macro_reporter_status(map_session_data &sd, e_macro_report_status styp
void clif_dynamicnpc_result( map_session_data& sd, e_dynamicnpc_result result );
void clif_set_dialog_align(map_session_data& sd, int npcid, e_say_dialog_align align);
void clif_set_npc_window_size(map_session_data& sd, int width, int height);
void clif_set_npc_window_pos(map_session_data& sd, int x, int y);
void clif_set_npc_window_pos_percent(map_session_data& sd, int x, int y);
#endif /* CLIF_HPP */

View File

@ -2365,7 +2365,7 @@
parseable_packet( HEADER_CZ_USE_SKILL_END, sizeof( struct PACKET_CZ_USE_SKILL_END ), clif_parse_StopUseSkillToId, 0 );
#endif
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
#if PACKETVER_MAIN_NUM >= 20181219 || PACKETVER_RE_NUM >= 20181219 || PACKETVER_ZERO_NUM >= 20181212
parseable_packet( HEADER_CZ_REQ_OPEN_MSGBOX_EXTEND_BODYITEM_SIZE, sizeof( struct PACKET_CZ_REQ_OPEN_MSGBOX_EXTEND_BODYITEM_SIZE ), clif_parse_inventory_expansion_request, 0 );
parseable_packet( HEADER_CZ_REQ_EXTEND_BODYITEM_SIZE, sizeof( struct PACKET_CZ_REQ_EXTEND_BODYITEM_SIZE ), clif_parse_inventory_expansion_confirm, 0 );
parseable_packet( HEADER_CZ_CLOSE_MSGBOX_EXTEND_BODYITEM_SIZE, sizeof( struct PACKET_CZ_CLOSE_MSGBOX_EXTEND_BODYITEM_SIZE ), clif_parse_inventory_expansion_reject, 0 );

View File

@ -3553,7 +3553,7 @@ void ItemGroupDatabase::loadingFinished() {
/** Read item forbidden by mapflag (can't equip item)
* Structure: <nameid>,<mode>
*/
static bool itemdb_read_noequip(char* str[], int columns, int current) {
static bool itemdb_read_noequip( char* str[], size_t columns, size_t current ){
t_itemid nameid;
int flag;

View File

@ -307,7 +307,6 @@ enum e_random_item_group {
IG_CARDALBUM_GARMENT,
IG_FLAMEL_CARD,
IG_SPECIAL_BOX,
IG_TRESURE_BOX_WOE_,
IG_RWC_PARTI_BOX,
IG_RWC_FINAL_COMP_BOX,
IG_GIFT_BUNDLE,
@ -2030,6 +2029,737 @@ enum e_random_item_group {
IG_DUN_VOUCHER_BOX2,
IG_BLUEBOXOFQUESTIONS,
IG_ENCHANT_STONE_BOX33,
IG_PC_BANG_COIN_BOX3,
IG_PCBANG_GIFT_BOX,
IG_PCBANG_COUPON_BOX2,
IG_PCBANG_COUPON_BOX3,
IG_CHANCE_BOX,
IG_ATTEND_3DAY_BOX,
IG_ATTEND_7DAY_BOX,
IG_ATTEND_10DAY_BOX,
IG_ATTEND_15DAY_BOX,
IG_ATTEND_20DAY_BOX,
IG_ATTEND_25DAY_BOX,
IG_GOLDPC_FIRST_BOX,
IG_TICKET_GIFT_BOX,
IG_TICKET_GIFT_BOX2,
IG_ASSORTED_SCROLL_BOX,
IG_DROOPING_KITTY_BOX,
IG_MAGESTIC_GOAT_BOX,
IG_DEVIRUCHI_CAP_BOX,
IG_EXECUTIONER_BOX,
IG_BROOD_AXE_BOX,
IG_TOMAHAWK_BOX,
IG_BOW_OF_RUDRA_BOX,
IG_CUTLAS_BOX,
IG_SOLAR_SWORD_BOX,
IG_SWORD_BREAKER_BOX,
IG_MAIL_BREAKER_BOX,
IG_MOONLIGHT_SWORD_BOX,
IG_SPANNER_BOX,
IG_WEAPON_CARD_SCROLL,
IG_ARMOR_CARD_SCROLL,
IG_HELMET_CARD_SCROLL,
IG_HOOD_CARD_SCROLL,
IG_HOOD_CARD_SCROLL2,
IG_SHOES_CARD_SCROLL,
IG_ACCY_CARD_SCROLL,
IG_WEAPON_CARD_SCROLL2,
IG_WEAPON_CARD_SCROLL3,
IG_ARMOR_CARD_SCROLL2,
IG_ACCY_CARD_SCROLL2,
IG_ASPERSIO_5_BOX30,
IG_ASPERSIO_5_BOX50,
IG_HANDCUFF_BOX,
IG_INFILTRATOR_BOX1,
IG_MURAMASA_BOX1,
IG_EXCALIBUR_BOX1,
IG_COMBAT_KNIFE_BOX1,
IG_COUNTER_DAGGER_BOX1,
IG_KAISER_KNUCKLE_BOX1,
IG_POLE_AXE_BOX1,
IG_MIGHTY_STAFF_BOX1,
IG_RIGHT_EPSILON_BOX1,
IG_BALISTAR_BOX1,
IG_DIARY_OF_SAGE_BOX1,
IG_ASURA_BOX1,
IG_APPLE_OF_ARCHER_BOX1,
IG_BUNNY_BAND_BOX1,
IG_SAHKKAT_BOX1,
IG_LORD_CIRCLET_BOX1,
IG_ELVEN_EARS_BOX1,
IG_STEEL_FLOWER_BOX1,
IG_CRITICAL_RING_BOX1,
IG_EARRING_BOX1,
IG_RING_BOX1,
IG_NECKLACE_BOX1,
IG_GLOVE_BOX1,
IG_BROOCH_BOX1,
IG_ROSARY_BOX1,
IG_SAFETY_RING_BOX1,
IG_VESPER_CORE01_BOX1,
IG_VESPER_CORE02_BOX1,
IG_VESPER_CORE03_BOX1,
IG_VESPER_CORE04_BOX1,
IG_DROOPING_KITTY_BOX1,
IG_MAGESTIC_GOAT_BOX1,
IG_DEVIRUCHI_CAP_BOX1,
IG_EXECUTIONER_BOX1,
IG_BROOD_AXE_BOX1,
IG_TOMAHAWK_BOX1,
IG_CUTLAS_BOX1,
IG_SOLAR_SWORD_BOX1,
IG_MOONLIGHT_SWORD_BOX1,
IG_SPANNER_BOX1,
IG_FREYJA_OVERCOAT_BOX,
IG_FREYJA_BOOTS_BOX,
IG_FREYJA_CAPE_BOX,
IG_FREYJA_CROWN_BOX,
IG_BRO_PACKAGE1,
IG_PECOPECO_HAIRBAND_BOX,
IG_RED_GLASSES_BOX,
IG_WHISPER_MASK_BOX,
IG_GOLD_BOX_,
IG_SILVER_BOX_,
IG_PECOPECO_HAIRBAND_BOX1,
IG_RED_GLASSES_BOX1,
IG_WHISPER_MASK_BOX1,
IG_RAMEN_HAT_BOX1,
IG_5_ANNIVERSARY_COIN_BOX,
IG_CERTIFICATE_TW_BOX,
IG_NAGAN_BOX,
IG_SKEWER_BOX,
IG_SURVIVAL_ROD_BOX,
IG_QUADRILLE_BOX,
IG_GREAT_AXE_BOX,
IG_BLOODY_ROAR_BOX,
IG_HARDBACK_BOX,
IG_IMMATERIAL_SWORD_BOX,
IG_UNHOLY_TOUCH_BOX,
IG_CLOAK_OF_SURVIVAL_BOX,
IG_MASQUERADE_BOX,
IG_ORC_HERO_HELM_BOX,
IG_EVIL_WING_EARS_BOX,
IG_DARK_BLINDFOLD_BOX,
IG_KRO_DROOPING_KITTY_BOX,
IG_CORSAIR_BOX,
IG_BLOODY_IRON_BALL_BOX,
IG_SPIRITUAL_RING_BOX,
IG_NAGAN_BOX1,
IG_SKEWER_BOX1,
IG_SURVIVAL_ROD_BOX1,
IG_QUADRILLE_BOX1,
IG_GREAT_AXE_BOX1,
IG_FIRE_BRAND_BOX1,
IG_IMMATERIAL_SWORD_BOX1,
IG_UNHOLY_TOUCH_BOX1,
IG_CLOAK_OF_SURVIVAL_BOX1,
IG_MASQUERADE_BOX1,
IG_ORC_HERO_HELM_BOX1,
IG_EVIL_WING_EARS_BOX1,
IG_DARK_BLINDFOLD_BOX1,
IG_KRO_DROOPING_KITTY_BOX1,
IG_CORSAIR_BOX1,
IG_SPIRITUAL_RING_BOX1,
IG_INDONESIA_BOX,
IG_GREEN_BOX_,
IG_RESIST_BOX1,
IG_RESIST_BOX2,
IG_STAT_BOOST1,
IG_STAT_BOOST2,
IG_STAT_BOOST3,
IG_STAT_BOOST4,
IG_OBSERVER_BOX,
IG_LUCKY_CLIP_BOX,
IG_F_LEVER_ACTION_RIFLE_BO,
IG_F_REFRESH_SHOES_BOX,
IG_F_PECOPECO_HAIRBAND_BOX,
IG_F_RED_GLASSES_BOX,
IG_F_WHISPER_MASK_BOX,
IG_F_RAMEN_HAT_BOX,
IG_F_VIGORGRA_PACKAGE3,
IG_F_VIGORGRA_PACKAGE4,
IG_NOVICE_SET_BOX,
IG_BEHOLDER_RING_BOX2,
IG_HALLOW_RING_BOX2,
IG_CLAMOROUS_RING_BOX2,
IG_CHEMICAL_RING_BOX2,
IG_INSECTICIDE_RING_BOX2,
IG_FISHER_RING_BOX2,
IG_DECUSSATE_RING_BOX2,
IG_BLOODY_RING_BOX2,
IG_SATANIC_RING_BOX2,
IG_DRAGOON_RING_BOX2,
IG_FPICTURE_DIARY_BOX,
IG_FMINI_HEART_BOX,
IG_FNEWCOMER_BOX,
IG_FKID_BOX,
IG_FMAGIC_CASTLE_BOX,
IG_FBULGING_HEAD_BOX,
IG_FPICTURE_DIARY_BOX_1M,
IG_FMINI_HEART_BOX_1M,
IG_FNEWCOMER_BOX_1M,
IG_FKID_BOX_1M,
IG_FMAGIC_CASTLE_BOX_1M,
IG_FBULGING_HEAD_BOX_1M,
IG_FHEALING_STAFF_BOX,
IG_FPRAXINUS_BOX,
IG_MUFFLER_C_BOX,
IG_VALKYRJA_S_SHIELD_C_BOX,
IG_SKUL_RING_C_BOX,
IG_S_BARRICADE_REPAIR_KIT,
IG_S_GSTONE_REPAIR_KIT,
IG_ARDOR_SCROLL,
IG_HOLY_SABER_BOX,
IG_BOOK_OF_PRAYER_BOX,
IG_PHENOMENA_WHIP_BOX,
IG_STAFF_OF_DARKNESS_BOX,
IG_MONK_KNUCKLE_BOX,
IG_MACE_OF_MADNESS_BOX,
IG_SPEAR_OF_EXCELLENT_BOX,
IG_BOW_OF_EVIL_BOX,
IG_KATAR_OF_SPEED_BOX,
IG_SS_REVOLVER_BOX,
IG_XMAS_SCROLL,
IG_FORTUNE_SWORD_BOX_I,
IG_HOUSE_AUGER_BOX_I,
IG_KAMAITACHI_BOX_I,
IG_BERSERK_GUITAR_BOX_I,
IG_DOOM_SLAYER_BOX_I,
IG_HUUMA_BLAZE_BOX_I,
IG_ODIN_S_BLESSING_BOX_I,
IG_RING_OF_F_LORD_BOX_I,
IG_RING_OF_RESON_BOX_I,
IG_BOY_S_CAP_BOX_I,
IG_ULLE_CAP_BOX_I,
IG_SPINX_HELM_BOX_I,
IG_POWER_OF_THOR_BOX,
IG_ACTI_POTION_BOX,
IG_ACTI_POTION_BOX2,
IG_HALF_ASPRIKA_BOX,
IG_HALF_BRYNHILD_BOX,
IG_SPIKED_SCARF_BOX,
IG_RAINBOW_SCARF_BOX,
IG_3D_GLASSES_BOX,
IG_CHEER_SCARF_BOX,
IG_CHEER_SCARF2_BOX,
IG_CHEER_SCARF3_BOX,
IG_CHEER_SCARF4_BOX,
IG_CHEER_SCARF6_BOX,
IG_CHEER_SCARF8_BOX,
IG_CHEER_SCARF10_BOX,
IG_CHEER_SCARF10_BOX2,
IG_RING_OF_VALKYRIE_BOX,
IG_RAPID_LIFE_WATER_BOX,
IG_LOLLI_POP_BOX,
IG_SPECIAL_BOX1,
IG_SPECIAL_BOX2,
IG_SPECIAL_BOX3,
IG_SPECIAL_BOX4,
IG_SPECIAL_BOX5,
IG_PCBANG_COUPON_BOX,
IG_B_HALTER_BOX_30DAYS,
IG_PCBANG_COUPON_BOX4,
IG_OLD_HAT_BOX,
IG_SAPA_FEAT_CERT_PACK,
IG_ARCHANGEL_WING_BOX,
IG_TRANS_BOX_DEVI,
IG_TRANS_BOX_RAY_ARCH,
IG_TRANS_BOX_MAVKA,
IG_TRANS_BOX_MARDUK,
IG_TRANS_BOX_BANSHEE,
IG_TRANS_BOX_GOLEM,
IG_UPG_REVOLVER_BOX2,
IG_UPG_TWOHAND_SWORD_BOX2,
IG_UPG_KATAR_BOX2,
IG_UPG_TWO_HANDED_AXE_BOX2,
IG_UPG_LANCE_BOX2,
IG_UPG_BOOK_BOX2,
IG_UPG_STAFF_BOX2,
IG_UPG_DAGGER_BOX2,
IG_UPG_MACE_BOX2,
IG_UPG_BOW_BOX2,
IG_GRYPHON_EGG_SCROLL,
IG_ASPD_POTION_BOX10,
IG_DRAGON_EGG_SCROLL,
IG_2011_RWC_SCROLL_KR,
IG_CHANGE_NAME_CARD_BOX2,
IG_PCBANG_COUPON_BOX5,
IG_CRU_SCROLL,
IG_EVENT_GIFT_BOX,
IG_EVENT_GIFT_BOX_,
IG_TIME_GUARDIAN_BOX,
IG_BEGINNER_KIT_BOX,
IG_MOTHER_LOVE_BOX,
IG_OLD_ORE_BOX_,
IG_BOARDING_HALTER_BOX3,
IG_UNDEAD_EGG,
IG_GIRLS_HEART,
IG_C_CENTER_POT_BOX,
IG_C_AWAKENING_POT_BOX,
IG_C_BERSERK_POT_BOX,
IG_C_WING_OF_FLY_BOX,
IG_REFINE_ORE_BOX3,
IG_GUARANTEE7_BOX,
IG_WOLFKING_SCROLL,
IG_ALMIGHTY_BOX2,
IG_HD_ELUNIUM_BOX30,
IG_HD_ORIDECON_BOX30,
IG_KINGS_GIFT,
IG_C_CENTER_POT_3D_BOX,
IG_C_AWAKENING_POT_3D_BOX,
IG_C_BERSERK_POT_3D_BOX,
IG_BM_LIMIT_PACK,
IG_GOLDENTREASUREBOX,
IG_UNLIMITED_10_BOX,
IG_XMAX_EGG_KR,
IG_C_FESTIVAL_TICKET,
IG_REFINE_ORE_BOX4,
IG_REFINE_ORE_BOX4_SET10,
IG_REFINE_ORE_BOX4_SET20,
IG_NEW_YEAR_GIFT_BOX,
IG_PCBANG_COUPON_BOX6,
IG_SEALED_D_LORD_SCROLL,
IG_STEALFIGHTER_20LV,
IG_STEALFIGHTER_25LV,
IG_KINGS_GIFT2,
IG_HAPPY_CALL_BOX,
IG_SEALED_KNIGHT_WS_SCROLL,
IG_C_WING_OF_FLY_1DAY_BOX,
IG_SILVERVINE_BOX10_,
IG_SILVERVINE_BOX110,
IG_SEALED_BERZ_SCROLL,
IG_3_LIFE_POTION_PACK,
IG_3_LIFE_POTION_10PACK,
IG_CLEARBOX_S,
IG_SEALED_KIEL_SCROLL,
IG_SEALED_GLOOM_SCROLL,
IG_REFINE_ORE_BOX5,
IG_REFINE_ORE_BOX5_SET10,
IG_ANGELING_PACKAGE,
IG_DEVILING_PACKAGE,
IG_OLD_HAT_BOX_,
IG_MEMORIAL_BOX,
IG_WET_CARDALBUM,
IG_GOLDEN_CARD,
IG_SHADOW_BOX3,
IG_11TH_S_PACKAGE,
IG_SILVERVINE_BOX10_2,
IG_SILVERVINE_BOX110_2,
IG_GEMSTONE_SHADOW_BOX,
IG_SEALED_F_BISHOP_SCROLL,
IG_HANGULDAY_BOX,
IG_3_LIFE_POTION_PACK2,
IG_3_LIFE_POTION_10PACK2,
IG_SEALED_IFRIT_SCROLL,
IG_BISCUIT_STICK_SET,
IG_PREMIUM_BOOK_BOX,
IG_LI_EMPELIUM_BOX,
IG_LI_UPG_BUCKLER_BOX,
IG_REFINE_ORE_BOX6,
IG_REFINE_ORE_BOX6_SET10,
IG_SEALED_TURTLEG_SCROLL,
IG_SEALED_BACSOJIN_SCROLL,
IG_GREED_SHADOW_BOX,
IG_HEAL_SHADOW_BOX,
IG_HIDING_SHADOW_BOX,
IG_CLOAKING_SHADOW_BOX,
IG_COSTUME_FESTIVAL_BOX2,
IG_C_WING_OF_FLY_5DAY_BOX,
IG_TELEPORT_SHADOW_BOX,
IG_STEAL_SHADOW_BOX,
IG_SEALED_PHARAOH_SCROLL,
IG_QUESTION_BOX,
IG_SEALED_M_FLOWER_SCROLL,
IG_SEALED_B_YGNIZEM_SCROLL,
IG_REFINE_ORE_BOX7,
IG_REFINE_ORE_BOX7_SET10,
IG_SEALED_APO_H_SCROLL,
IG_PC_NOMALBOX,
IG_PC_WOODENBOX,
IG_PC_GOLDENBOX,
IG_PC_PLATINUMBOX,
IG_3_LIFE_POTION_PACK4,
IG_3_LIFE_POTION_10PACK4,
IG_SEALED_DRACULA_SCROLL,
IG_BEARERS_SHADOW_BOX,
IG_VIGORGRA_PACKAGE_V4,
IG_VIGORGRA_PACKAGE_SET_V4,
IG_SEALED_B_SHECIL_SCROLL,
IG_NYANGVINE_BOX4,
IG_NYANGVINE_BOX10,
IG_NYANGVINE_BOX40,
IG_REFINE_ORE_BOX8,
IG_REFINE_ORE_BOX8_SET10,
IG_SEALED_CARD,
IG_LI_HD_ELUNIUM_BOX30,
IG_LI_HD_ORIDECON_BOX30,
IG_UNLIMITED_BOX3,
IG_UNLIMITED_10_BOX3,
IG_GUARANTEE_RELAX_SCROLL,
IG_LIMIT_MANUAL_BOX,
IG_SEALED_DRACULA_SCROLL2,
IG_3_LIFE_POTION_10PACK5,
IG_3_LIFE_POTION_PACK5,
IG_SEALED_MYSTERIOUS_EGG,
IG_SEALED_DRACULA_ALBUM,
IG_LIMIT_POWER_BOOSTER_BOX,
IG_LIMIT_POWER_BOOSTER100,
IG_SEALED_BERZ_ALBUM,
IG_SEALED_BERZ_SCROLL2,
IG_NYANGVINE_BOX200,
IG_APRILGIFTBOX,
IG_NOVEMBERGIFTBOX,
IG_SEPTEMBERGIFTBOX,
IG_REFINE_ORE_BOX9,
IG_REFINE_ORE_BOX9_SET10,
IG_2015_NEW_YEAR_SCROLL,
IG_NEW_YEAR_SHADOW_CUBE,
IG_2015GOLDPCBOX,
IG_ALMIGHTY_BOX4,
IG_ALMIGHTY100_BOX2,
IG_SEALED_SCROLL2,
IG_INVISIBLE_BOX,
IG_FREEZE_DREAM,
IG_LAPINE_DDUKDDAKBOX,
IG_GUNSLINGER_BOX,
IG_MINI_FAN_BOX,
IG_KAFRA_BOX,
IG_CANDY_BOX_MELEE,
IG_CANDY_BOX_RANGE,
IG_CANDY_BOX_MAGIC,
IG_BLOODYKNIGHT_SHIELD_BOX,
IG_E_WING_OF_FLY_3DAY_BOX,
IG_REBEGINER_BOX,
IG_REBEGINER_S_BOX,
IG_OVERWHELM_ARMOR_BOX,
IG_POWERFUL_HELM_BOX,
IG_MYSTERIOUS_PLASTIC,
IG_80LVUP,
IG_JUMPING_KIT_BOX,
IG_MAIN_LUCKY_BOX_,
IG_SILLIT_PONG_BOX,
IG_KUNAI_SCROLL_OF_FLAME,
IG_KUNAI_SCROLL_OF_ICICLE,
IG_KUNAI_SCROLL_OF_POISON,
IG_KUNAI_SCROLL_OF_SOIL,
IG_KUNAI_SCROLL_OF_WIND,
IG_C_CATPAW_7DAY_BOX_,
IG_CANNON_BALL_BOX,
IG_IRON_CANNON_BALL_BOX,
IG_SOUL_CANNON_BALL_BOX,
IG_DARK_CANNON_BALL_BOX,
IG_HOLY_CANNON_BALL_BOX,
IG_CANNON_BOX_6,
IG_MAGIC_GEAR_FUEL_BOX,
IG_REPAIRA_BOX,
IG_REPAIRB_BOX,
IG_REPAIRC_BOX,
IG_FLAME_STONE_BUNDLE,
IG_ICE_STONE_BUNDLE,
IG_WIND_STONE_BUNDLE,
IG_SHADOW_ORB_BUNDLE,
IG_CHARM_FIRE_BUNDLE,
IG_CHARM_ICE_BUNDLE,
IG_CHARM_WIND_BUNDLE,
IG_CHARM_EARTH_BUNDLE,
IG_KUNAI_SCROLL_EXPLOSIVE,
IG_GEMSTONE_BLUE,
IG_GEMSTONE_YL,
IG_GEMSTONE_RED,
IG_BULLET_CASE_FULL,
IG_BULLET_CASE_MINE,
IG_BULLET_CASE_TAIL,
IG_C_BRAID_HALF_UP_BOX,
IG_POENETENTIA_BOX3,
IG_POENETENTIA_BOX4,
IG_CHUSEOG_PRESENT_BOX,
IG_LI_NYANGVINE_BOX100_2,
IG_BARMUND_RUNE_BOX,
IG_SEALED_CARD3,
IG_LI_NYANGVINE_STONE_BOX3,
IG_RO_LIVE_SHOP_BOX,
IG_RO_LIVE_SHOP_EX_BOX,
IG_SEASON_EVT_REWARD_11,
IG_CANNON_BOX_ICE,
IG_CANNON_BOX_LIGHTNING,
IG_CANNON_BOX_STONE,
IG_CANNON_BOX_FLARE,
IG_CANNON_BOX_POISONING,
IG_KUNAI_SCROLL,
IG_KUNAI_SCROLL_NOTHING,
IG_KUNAI_SCROLL_SHADOW,
IG_KUNAI_SCROLL_HAMAYA,
IG_NW_GRENADE_BOX,
IG_SOA_CHARM_BUNDLE,
IG_SS_CHARM_BOX,
IG_SS_CHARM_F_BOX,
IG_SS_CHARM_W_BOX,
IG_SS_CHARM_G_BOX,
IG_SS_CHARM_L_BOX,
IG_PAYMENT_COSTUME_BOX1,
IG_PAYMENT_COSTUME_BOX2,
IG_2021_PROMO_PACKAGE_1,
IG_2021_PROMO_PACKAGE_2,
IG_E_BOARDING_HALTER_BOX,
IG_COSTUMEMILEAGE_PACKAGE4,
IG_COSTUMEMILEAGE_PACKAGE5,
IG_COSTUMEMILEAGE_PACKAGE6,
IG_EVT_RAGFES_BOX,
IG_KR_B_SPECIAL08,
IG_KR_B_SPECIAL05,
IG_SEASON_EVT_REWARD_12,
IG_SECURITY_CAMPAIGN_BOX,
IG_HERO_HAMMER_PACKAGE_6,
IG_HERO_UP_PACKAGE_6,
IG_HERO_TOKEN_BOX,
IG_JANUARYGIFTBOX_,
IG_FEBRUARYGIFTBOX_,
IG_MARCHGIFTBOX_,
IG_APRILGIFTBOX_,
IG_MAYGIFTBOX_,
IG_JUNEGIFTBOX_,
IG_JULYGIFTBOX_,
IG_AUGUSTGIFTBOX_,
IG_SEPTEMBERGIFTBOX_,
IG_OCTOBERGIFTBOX_,
IG_NOVEMBERGIFTBOX_,
IG_DECEMBERGIFTBOX_,
IG_SEASON_EVT_REWARD_1,
IG_2021_WINTER_EVENT_BOX1,
IG_2021_WINTER_EVENT_BOX2,
IG_ICE_F_STONE_BOX,
IG_BS_MAKING_S,
IG_MONTHLY_PACKAGE_1,
IG_MONTHLY_PACKAGE_2,
IG_MONTHLY_PACKAGE_3,
IG_MONTHLY_BUFF_PACKAGE,
IG_MONTHLY_BATTLE_PACKAGE,
IG_MD_AIRBOAT_EXPBOX,
IG_ENCHANT_TICKET_3,
IG_FAN_GREED_1HOUR_BOX,
IG_KAKAO_PLUS_BOX,
IG_COSTUMEMILEPACK_27_1,
IG_COSTUMEMILEPACK_27_2,
IG_COSTUMEMILEPACK_27_3,
IG_P_BOOSTER230_GIFT,
IG_BOOSTER230_GIFT,
IG_BOOSTER_PACK_10,
IG_BOOSTER_PACK_20,
IG_BOOSTER_PACK_40,
IG_BOOSTER_PACK_50,
IG_BOOSTER_PACK_70,
IG_BOOSTER_PACK_80,
IG_BOOSTER_PACK_110,
IG_BOOSTER_PACK_120,
IG_BOOSTER_PACK_140,
IG_BOOSTER_PACK_150,
IG_BOOSTER_PACK_170,
IG_BOOSTER_PACK_180,
IG_BOOSTER_PACK_210,
IG_BOOSTER_PACK_220,
IG_BOOSTER_PACK_240,
IG_BOOSTER_PACK_250,
IG_BOOSTER_CALL_PACKAGE,
IG_E_BOARDING_HALTER_BOX2,
IG_SHADOW_UP_BOX,
IG_VIVA_ADUL_HAT_BOX_11,
IG_EVT_MAKINGMATERIALS_BOX,
IG_LI_NYANGVINE_BOX1_28,
IG_LI_NYANGVINE_BOX2_28,
IG_LI_NYANGVINE_BOX3_28,
IG_EVT_20TH_WHITEGOLD,
IG_EVT_20TH_GOLD,
IG_EVT_20TH_SILVER,
IG_EVT_20TH_BRONZE,
IG_EVT_20TH_RETURN,
IG_EVT_20TH_RETURN2,
IG_E_CLOTH_DYE_BOX,
IG_PLAIN_RUNE_BOX5,
IG_FLAME_RUNE_BOX5,
IG_ICE_RUNE_BOX5,
IG_DEATH_RUNE_BOX5,
IG_RO_FESTIVAL_BOX,
IG_SERVICE1_M_01_BOX,
IG_SERVICE1_M_05_BOX,
IG_SERVICE1_M_07_BOX,
IG_SERVICE1_M_10_BOX,
IG_SERVICE1P_M_01_BOX,
IG_SERVICE1P_M_05_BOX,
IG_SERVICE1P_M_07_BOX,
IG_SERVICE1P_M_10_BOX,
IG_SERVICE1_F_01_BOX,
IG_SERVICE1_F_05_BOX,
IG_SERVICE1_F_07_BOX,
IG_SERVICE1_F_10_BOX,
IG_SERVICE1P_F_01_BOX,
IG_SERVICE1P_F_05_BOX,
IG_SERVICE1P_F_07_BOX,
IG_SERVICE1P_F_10_BOX,
IG_R_BEARERS_EARRING_BOX,
IG_R_BEARERS_PENDANT_BOX,
IG_R_BEARERS_ARMOR_BOX,
IG_R_BEARERS_SHOES_BOX,
IG_HASTY_WEAPON_BOX,
IG_HASTY_SHIELD_BOX,
IG_S_RELOAD_SHIELD_BOX,
IG_RO_ARENA_BOX,
IG_RO_ARENA_BOX2,
IG_HEROSRIA_GIFT,
IG_MAUTOSPELL_EARRING_BOX,
IG_MAUTOSPELL_PENDANT_BOX,
IG_MAUTOSPELL_ARMOR_BOX,
IG_MAUTOSPELL_SHOES_BOX,
IG_INFINITY_WEAPON_BOX,
IG_INFINITY_SHIELD_BOX,
IG_LUXURIOUS_BLUE_BOX,
IG_VR_BOOK_EVENT,
IG_LI_NYANGVINE_BOX1_29,
IG_LI_NYANGVINE_BOX2_29,
IG_LI_NYANGVINE_BOX3_29,
IG_EXP_WEAPON_BOX,
IG_EXP_SHIELD_BOX,
IG_M_BLITZ_WEAPON_BOX,
IG_M_BLITZ_SHIELD_BOX,
IG_CVT_WING_BOX,
IG_TEMPLE_RUNE_BOX5,
IG_VENOM_RUNE_BOX5,
IG_SOUL_RUNE_BOX5,
IG_CASH_BOOSTER_BOX,
IG_A_BUBBLE_GUM_BOX10,
IG_COSTUMEMILEPACK_29_1,
IG_COSTUMEMILEPACK_29_2,
IG_COSTUMEMILEPACK_29_3,
IG_S_BEARERS_CUBE,
IG_PENE_SET_CUBE,
IG_TEMP_SET_CUBE,
IG_JUSTICE_WEAPON_BOX,
IG_INJUSTICE_WEAPON_BOX,
IG_GOODNEVIL_HELM_BOX,
IG_F_EIN_1HDAGGER_BOX,
IG_SHADOW_SELECT_BOX_SET,
IG_REFINE_HAMMER_BOX,
IG_LI_NYANGVINE_BOX1_30,
IG_LI_NYANGVINE_BOX2_30,
IG_LI_NYANGVINE_BOX3_30,
IG_SLD_BOSS_CARD_ALBUM,
IG_COSTUMEMILEPACK_30_1,
IG_COSTUMEMILEPACK_30_2,
IG_COSTUMEMILEPACK_30_3,
IG_VIP_GIFT,
IG_VVIP_GIFT,
IG_SVIP_GIFT,
IG_2023_SPRING_COLLECTION,
IG_KR_B_SPECIAL04,
IG_LI_NYANGVINE_BOX1_31,
IG_LI_NYANGVINE_BOX2_31,
IG_LI_NYANGVINE_BOX3_31,
IG_STONE_ROBE3_BOX,
IG_RO_CONCERT_SCROLL,
IG_RO_CONCERT_SCROLL_BOX,
IG_FAN_UPGRADE_KIT_EX_10,
IG_KR_B_SPECIAL06,
IG_COSTUMEMILEPACK_31_1,
IG_COSTUMEMILEPACK_31_2,
IG_COSTUMEMILEPACK_31_3,
IG_CATPAW_1DAY_BOX,
IG_MILEAGE_COUPON,
IG_LI_NYANGVINE_BOX1_32,
IG_LI_NYANGVINE_BOX2_32,
IG_LI_NYANGVINE_BOX3_32,
IG_21TH_PRESENT_BOX,
IG_21TH_COSTUME_COLLECTION,
IG_S_ENCHANT_ESSENCE_BOX_3,
IG_SEASON_EVT_REWARD_8,
IG_COSTUMEMILEPACK_32_1,
IG_COSTUMEMILEPACK_32_2,
IG_COSTUMEMILEPACK_32_3,
IG_M_ARMOR_BOX,
IG_M_SHOES_BOX,
IG_M_PENDANT_BOX,
IG_M_EARRING_BOX,
IG_EIN_ORE_BOX,
IG_FATE_FRAGMENT_BOX,
IG_SIN_FRAGMENT_BOX,
IG_AMETHYST_FRAGMENT_BOX,
IG_SNOW_F_ORE_BOX,
IG_SCHMIDT_ANTIQUITY,
IG_SCHMIDT_ANTIQUITY2,
IG_AMDARAIS_ANTIQUITY,
IG_AMDARAIS_ANTIQUITY2,
IG_C_AMDARAIS_ANTIQUITY,
IG_C_HIMEL_ANTIQUITY,
IG_UNKNOWN_ANTIQUITY,
IG_SAKRAY_ANTIQUITY,
IG_AIRBOAT_ANTIQUITY,
IG_CELINE_KIMI_ANTIQUITY,
IG_MIGUEL_ANTIQUITY,
IG_EL_A17T_ANTIQUITY,
IG_PITAYA_BOSS_ANTIQUITY,
IG_SWEETY_ANTIQUITY,
IG_REDPEPPER_ANTIQUITY,
IG_REDPEPPER_ANTIQUITY2,
IG_DEMI_FREYJA_ANTIQUITY,
IG_JUNCEA_ANTIQUITY,
IG_AQUILA_ANTIQUITY,
IG_AQUILA_ANTIQUITY2,
IG_F_ICESLUG_ANTIQUIY,
IG_LASGAND_ANTIQUITY,
IG_LASGAND_ANTIQUITY2,
IG_THANATOS_ANTIQUITY,
IG_CINNAMON_PACK1,
IG_CINNAMON_PACK2,
IG_CINNAMON_PACK3,
IG_CINNAMON_PACK4,
IG_COS_ENCHANTSTONE_BOX1,
IG_COS_ENCHANTSTONE_BOX2,
IG_COS_ENCHANTSTONE_BOX3,
IG_T_GARDEN_EV_1,
IG_T_GARDEN_EV_2,
IG_T_GARDEN_EV_3,
IG_LI_NYANGVINE_BOX1_33,
IG_LI_NYANGVINE_BOX2_33,
IG_LI_NYANGVINE_BOX3_33,
IG_LI_NYANG_CINNA_BOX1_33,
IG_LI_NYANG_CINNA_BOX2_33,
IG_LI_NYANG_CINNA_BOX3_33,
IG_BL_DEPTH_EV_1,
IG_BL_DEPTH_EV_2,
IG_KR_B_SPECIAL09,
IG_LI_A_ELUNIUM_BOX,
IG_LI_A_ORIDECON_BOX,
IG_PRESENTBOX_EP17_2,
IG_PRESENTBOX_EP18,
IG_REFINE_EVENT_BOX,
IG_PRESENTBOX_EP19,
IG_PRESENTBOX_EP20,
IG_PRESENTBOX_GLASTHEIM,
IG_BROWN_DIA_BOX,
IG_COSTUMEMILEPACK_33_1,
IG_COSTUMEMILEPACK_33_2,
IG_COSTUMEMILEPACK_33_3,
IG_2023_XMAX_PACK_1,
IG_2023_XMAX_PACK_2,
IG_A_FORCE_BOOSTER_BOX,
IG_A_FORCE_BOOSTER_10_BOX,
IG_BROWN_DIA_BOX_3_7,
IG_2401_EV_LUNCH_BOX,
IG_BLACK_DIA_3_BOX,
IG_LI_NYANGVINE_BOX1_34,
IG_LI_NYANGVINE_BOX2_34,
IG_LI_NYANGVINE_BOX3_34,
IG_ENCHANT_STONE_BOX34,
IG_S_BADGE_PACK,
IG_SUPER_SONIC_PACK,
IG_CHAOS_EMERALD_PACK,
IG_VIP_BIRTHDAY_BOX,
IG_R_EP17_ALBUM,
IG_R_EP178_BOSS,
IG_SONIC_PREMIUM_PACK1,
IG_SONIC_PREMIUM_PACK2,
IG_S_BADGE_PACK_,
IG_SUPER_SONIC_PACK_,
IG_CHAOS_EMERALD_PACK_,
IG_MAX,
};

View File

@ -7,6 +7,7 @@
#include <common/showmsg.hpp>
#include <common/strlib.hpp>
#include <common/timer.hpp>
#include <common/utilities.hpp>
#include "atcommand.hpp"
#include "battle.hpp"
@ -18,6 +19,8 @@
#include "pc.hpp"
#include "pet.hpp"
using namespace rathena;
void mail_clear(map_session_data *sd)
{
int i;
@ -106,8 +109,36 @@ bool mail_removezeny( map_session_data *sd, bool flag ){
if( sd->mail.zeny > 0 ){
//Zeny send
if( flag ){
int64 zeny = sd->mail.zeny;
if( battle_config.mail_zeny_fee > 0 ){
int64 fee;
if( util::safe_multiplication( zeny, static_cast<decltype(fee)>( battle_config.mail_zeny_fee ), fee ) ){
return false;
}
if( fee < 0 ){
return false;
}
fee /= 100;
if( fee > MAX_ZENY ){
return false;
}
if( util::safe_addition( zeny, fee, zeny ) ){
return false;
}
if( zeny > MAX_ZENY ){
return false;
}
}
// It's possible that we don't know what the dest_id is, so it will be 0
if (pc_payzeny(sd, sd->mail.zeny + sd->mail.zeny * battle_config.mail_zeny_fee / 100, LOG_TYPE_MAIL, sd->mail.dest_id)) {
if( pc_payzeny( sd, static_cast<int32>( zeny ), LOG_TYPE_MAIL, sd->mail.dest_id ) ){
return false;
}
}else{

View File

@ -349,7 +349,7 @@ int map_addblock(struct block_list* bl)
struct map_data *mapdata = map_getmapdata(m);
if (mapdata->cell == nullptr) // Player warped to a freed map. Stop them!
if (mapdata == nullptr || mapdata->cell == nullptr) // Player warped to a freed map. Stop them!
return 1;
if( x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys )
@ -402,6 +402,8 @@ int map_delblock(struct block_list* bl)
struct map_data *mapdata = map_getmapdata(bl->m);
nullpo_ret(mapdata);
pos = bl->x/BLOCK_SIZE+(bl->y/BLOCK_SIZE)*mapdata->bxs;
if (bl->next)
@ -409,8 +411,10 @@ int map_delblock(struct block_list* bl)
if (bl->prev == &bl_head) {
//Since the head of the list, update the block_list map of []
if (bl->type == BL_MOB) {
nullpo_ret(mapdata->block_mob);
mapdata->block_mob[pos] = bl->next;
} else {
nullpo_ret(mapdata->block);
mapdata->block[pos] = bl->next;
}
} else {
@ -434,6 +438,8 @@ int map_delblock(struct block_list* bl)
*/
int map_moveblock(struct block_list *bl, int x1, int y1, t_tick tick)
{
nullpo_ret(bl);
int x0 = bl->x, y0 = bl->y;
status_change *sc = NULL;
int moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);

View File

@ -861,6 +861,18 @@ struct map_data_other_server {
uint16 port;
};
/**
* align for packet ZC_SAY_DIALOG_ALIGN
**/
enum e_say_dialog_align : uint8 {
DIALOG_ALIGN_LEFT = 0,
DIALOG_ALIGN_RIGHT = 1,
DIALOG_ALIGN_CENTER = 2,
DIALOG_ALIGN_TOP = 3,
DIALOG_ALIGN_MIDDLE = 4,
DIALOG_ALIGN_BOTTOM = 5
};
struct inter_conf {
uint32 start_status_points;
bool emblem_woe_change;

View File

@ -5736,8 +5736,7 @@ uint64 MobChatDatabase::parseBodyNode(const ryml::NodeRef& node) {
/*==========================================
* processes one mob_skill_db entry
*------------------------------------------*/
static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
{
static bool mob_parse_row_mobskilldb( char** str, size_t columns, size_t current ){
static const struct {
char str[32];
enum MobSkillState id;

View File

@ -5621,13 +5621,14 @@ int npc_parsesrcfile(const char* filepath)
// parse buffer
for ( const char* p = skip_space(buffer); p && *p ; p = skip_space(p) ) {
int pos[9];
size_t pos[9];
lines++;
// w1<TAB>w2<TAB>w3<TAB>w4
int count = sv_parse(p, len+buffer-p, 0, '\t', pos, ARRAYLENGTH(pos), (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
bool error;
size_t count = sv_parse( p, len + buffer - p, 0, '\t', pos, ARRAYLENGTH( pos ), SV_TERMINATE_LF|SV_TERMINATE_CRLF, error );
if (count < 0) {
if( error ){
ShowError("npc_parsesrcfile: Parse error in file '%s', line '%d'. Stopping...\n", filepath, strline(buffer,p-buffer));
break;
}

View File

@ -1469,6 +1469,32 @@ enum e_job_types
JT_4_HERO_SAUSAGE,
JT_4_PRINCESS_SAUSAGE,
JT_4_EP20_LASGAND = 10536,
JT_4_EP20_NYAR,
JT_4_EP20_DEVICE_BLUE,
JT_4_EP20_DEVICE_RED,
JT_4_EP20_DEVICE_BLACK,
JT_4_GACHA_MACHINE = 10545,
JT_4_VR_CHAO,
JT_4_RUNESTONE,
JT_4_EM_ARDOR,
JT_4_EM_DILUVIO,
JT_4_EM_PROCELLA,
JT_4_EM_TERREMOTUS,
JT_4_EM_SERPENS,
JT_4_SNOWDOG,
JT_1_SHADOW_RED,
JT_1_SHADOW_ORANGE,
JT_1_SHADOW_YELLOW,
JT_1_SHADOW_GREEN,
JT_1_SHADOW_BLUE,
JT_1_SHADOW_INDIGO,
JT_1_SHADOW_VIOLET,
JT_4_EVT_LAMMIR,
JT_4_EVT_SULKI,
JT_4_EVT_KKAT,
JT_ROZ_MQ_XAVIER = 13000,
JT_ROZ_MQ_MOCLORD,
JT_ROZ_MQ_SKULD,

View File

@ -1258,7 +1258,7 @@ bool pc_can_sell_item(map_session_data *sd, struct item *item, enum npc_subtype
*/
bool pc_can_give_items(map_session_data *sd)
{
return pc_has_permission(sd, PC_PERM_TRADE);
return (pc_has_permission(sd, PC_PERM_TRADE) || pc_has_permission(sd, PC_PERM_TRADE_UNCONDITIONAL));
}
/**
@ -1266,7 +1266,7 @@ bool pc_can_give_items(map_session_data *sd)
*/
bool pc_can_give_bounded_items(map_session_data *sd)
{
return pc_has_permission(sd, PC_PERM_TRADE_BOUNDED);
return (pc_has_permission(sd, PC_PERM_TRADE_BOUNDED) || pc_has_permission(sd, PC_PERM_TRADE_UNCONDITIONAL));
}
/**
@ -11157,9 +11157,15 @@ void pc_setmadogear(map_session_data *sd, bool flag, e_mado_type type)
*------------------------------------------*/
bool pc_candrop(map_session_data *sd, struct item *item)
{
if( item && ((item->expire_time || (item->bound && !pc_can_give_bounded_items(sd))) || (itemdb_ishatched_egg(item))) )
if (sd->sc.cant.drop)
return false;
if( !pc_can_give_items(sd) || sd->sc.cant.drop) //check if this GM level can drop items
if( item && itemdb_ishatched_egg(item) )
return false;
if (pc_has_permission(sd, PC_PERM_TRADE_UNCONDITIONAL)) // no restriction
return true;
if( !pc_can_give_items(sd) )
return false;
if( item && (item->expire_time || (item->bound && !pc_can_give_bounded_items(sd))) )
return false;
return (itemdb_isdropable(item, pc_get_group_level(sd)));
}
@ -14070,7 +14076,7 @@ void JobDatabase::loadingFinished() {
/**
* Read job_noenter_map.txt
**/
static bool pc_readdb_job_noenter_map(char *str[], int columns, int current) {
static bool pc_readdb_job_noenter_map( char *str[], size_t columns, size_t current ){
int class_ = -1;
int64 class_tmp;

View File

@ -50,6 +50,7 @@ enum e_pc_permission : uint32 {
PC_PERM_ATTENDANCE,
PC_PERM_MACRO_DETECT,
PC_PERM_MACRO_REGISTER,
PC_PERM_TRADE_UNCONDITIONAL,
//.. add other here
PC_PERM_MAX,
};
@ -88,6 +89,7 @@ static const struct s_pcg_permission_name {
{ "attendance",PC_PERM_ATTENDANCE },
{ "macro_detect",PC_PERM_MACRO_DETECT },
{ "macro_register",PC_PERM_MACRO_REGISTER },
{ "trade_unconditional",PC_PERM_TRADE_UNCONDITIONAL },
};
struct s_player_group{

View File

@ -28,7 +28,7 @@
using namespace rathena;
static int split_exact_quest_time(char* modif_p, int* day, int* hour, int* minute, int *second);
static int split_exact_quest_time(char* modif_p, int* week, int* day, int* hour, int* minute, int *second);
const std::string QuestDatabase::getDefaultLocation() {
return std::string(db_path) + "/quest_db.yml";
@ -81,20 +81,25 @@ uint64 QuestDatabase::parseBodyNode(const ryml::NodeRef& node) {
quest->time = static_cast<time_t>(timediff);
}
else {// '+' not found, set to specific time
int32 day, hour, minute, second;
int32 day, hour, minute, second, week;
if (split_exact_quest_time(const_cast<char *>(time.c_str()), &day, &hour, &minute, &second) == 0) {
if (split_exact_quest_time(const_cast<char *>(time.c_str()), &week, &day, &hour, &minute, &second) == 0) {
this->invalidWarning(node["TimeLimit"], "Incorrect TimeLimit format %s given, skipping.\n", time.c_str());
return 0;
}
quest->time = day * 86400 + hour * 3600 + minute * 60 + second;
if (week > 0)
quest->time = hour * 3600 + minute * 60 + second;
else
quest->time = day * 86400 + hour * 3600 + minute * 60 + second;
quest->time_at = true;
quest->time_week = week;
}
} else {
if (!exists) {
quest->time = 0;
quest->time_at = false;
quest->time_week = -1;
}
}
@ -441,8 +446,8 @@ uint64 QuestDatabase::parseBodyNode(const ryml::NodeRef& node) {
}
static int split_exact_quest_time(char* modif_p, int* day, int* hour, int* minute, int *second) {
int d = -1, h = -1, mn = -1, s = -1;
static int split_exact_quest_time(char* modif_p, int* week, int* day, int* hour, int* minute, int *second) {
int w = -1, d = -1, h = -1, mn = -1, s = -1;
nullpo_retr(0, modif_p);
@ -453,7 +458,28 @@ static int split_exact_quest_time(char* modif_p, int* day, int* hour, int* minut
modif_p++;
while (modif_p[0] >= '0' && modif_p[0] <= '9')
modif_p++;
if (modif_p[0] == 's') {
if (strncasecmp(modif_p, "SUNDAY", 6) == 0) {
w = 0;
modif_p = modif_p + 6;
} else if (strncasecmp(modif_p, "MONDAY", 6) == 0) {
w = 1;
modif_p = modif_p + 6;
} else if (strncasecmp(modif_p, "TUESDAY", 7) == 0) {
w = 2;
modif_p = modif_p + 7;
} else if (strncasecmp(modif_p, "WEDNESDAY", 9) == 0) {
w = 3;
modif_p = modif_p + 9;
} else if (strncasecmp(modif_p, "THURSDAY", 8) == 0) {
w = 4;
modif_p = modif_p + 8;
} else if (strncasecmp(modif_p, "FRIDAY", 6) == 0) {
w = 5;
modif_p = modif_p + 6;
} else if (strncasecmp(modif_p, "SATURDAY", 8) == 0) {
w = 6;
modif_p = modif_p + 8;
} else if (modif_p[0] == 's') {
s = value;
modif_p++;
} else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
@ -473,6 +499,7 @@ static int split_exact_quest_time(char* modif_p, int* day, int* hour, int* minut
if (h < 0 || h > 23 || mn > 59 || s > 59) // hour is required
return 0;
*week = w;
*day = max(0,d);
*hour = h;
*minute = max(0,mn);
@ -536,10 +563,18 @@ static time_t quest_time(std::shared_ptr<s_quest_db> qi)
struct tm *lt = localtime(&t);
uint32 time_today = lt->tm_hour * 3600 + lt->tm_min * 60 + lt->tm_sec;
if (time_today < (qi->time % 86400))
return static_cast<time_t>(t + qi->time - time_today);
else // Carry over to the next day
return static_cast<time_t>(t + 86400 + qi->time - time_today);
int32 day_shift = 0;
if (time_today >= (qi->time % 86400)) // Carry over to the next day
day_shift = 1;
if (qi->time_week > -1) {
if (qi->time_week < (lt->tm_wday + day_shift))
day_shift = qi->time_week + 7 - lt->tm_wday;
else
day_shift = qi->time_week - lt->tm_wday;
}
return static_cast<time_t>(t + (day_shift * 86400) + qi->time - time_today);
}
return 0;

View File

@ -42,6 +42,7 @@ struct s_quest_db {
int32 id;
time_t time;
bool time_at;
int32 time_week;
std::vector<std::shared_ptr<s_quest_objective>> objectives;
std::vector<std::shared_ptr<s_quest_dropitem>> dropitem;
std::string name;

View File

@ -24038,24 +24038,32 @@ BUILDIN_FUNC(ignoretimeout)
* geteleminfo <type>{,<char_id>};
**/
BUILDIN_FUNC(geteleminfo) {
TBL_ELEM *ed = NULL;
TBL_PC *sd = NULL;
int type = script_getnum(st,2);
map_session_data *sd = nullptr;
if (!script_charid2sd(3, sd)) {
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS;
return SCRIPT_CMD_FAILURE;
}
s_elemental_data *ed = nullptr;
if (!(ed = sd->ed)) {
//ShowDebug("buildin_geteleminfo: Player doesn't have Elemental.\n");
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS;
}
int type = script_getnum(st,2);
switch (type) {
case 0: script_pushint(st, ed->elemental.elemental_id); break;
case 1: script_pushint(st, ed->bl.id); break;
case ELEMINFO_ID:
script_pushint(st, ed->elemental.elemental_id);
break;
case ELEMINFO_GAMEID:
script_pushint(st, ed->bl.id);
break;
case ELEMINFO_CLASS:
script_pushint(st, ed->elemental.class_);
break;
default:
ShowError("buildin_geteleminfo: Invalid type '%d'.\n", type);
script_pushint(st, 0);
@ -27123,6 +27131,106 @@ BUILDIN_FUNC(opentips){
#endif
}
BUILDIN_FUNC(setdialogalign){
map_session_data *sd;
if ( !script_rid2sd(sd) ) {
return SCRIPT_CMD_FAILURE;
}
int32 align = script_getnum( st, 2 );
if( align < DIALOG_ALIGN_LEFT || align > DIALOG_ALIGN_BOTTOM ){
ShowError( "buildin_setdialogalign: Unknown align value %d\n", align );
return SCRIPT_CMD_FAILURE;
}
clif_set_dialog_align( *sd, st->oid, static_cast<e_say_dialog_align>( align ) );
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(setdialogsize){
map_session_data *sd;
if ( !script_rid2sd(sd) ) {
script_pushint(st, 0);
return SCRIPT_CMD_FAILURE;
}
int32 x = script_getnum( st, 2 );
if( x < 0 || x > INT16_MAX ){
ShowError( "buildin_setdialogsize: x size %d is out of range [0,%d]\n", x, INT16_MAX );
return SCRIPT_CMD_FAILURE;
}
int32 y = script_getnum( st, 3 );
if( y < 0 || y > INT16_MAX ){
ShowError( "buildin_setdialogsize: y size %d is out of range [0,%d]\n", y, INT16_MAX );
return SCRIPT_CMD_FAILURE;
}
clif_set_npc_window_size( *sd, x, y );
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(setdialogpos){
map_session_data *sd;
if ( !script_rid2sd(sd) ) {
script_pushint(st, 0);
return SCRIPT_CMD_FAILURE;
}
int32 x = script_getnum( st, 2 );
if( x < 0 || x > INT16_MAX ){
ShowError( "buildin_setdialogpos: x position %d is out of range [0,%d]\n", x, INT16_MAX );
return SCRIPT_CMD_FAILURE;
}
int32 y = script_getnum( st, 3 );
if( y < 0 || y > INT16_MAX ){
ShowError( "buildin_setdialogpos: y position %d is out of range [0,%d]\n", y, INT16_MAX );
return SCRIPT_CMD_FAILURE;
}
clif_set_npc_window_pos( *sd, x, y );
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(setdialogpospercent){
map_session_data *sd;
if ( !script_rid2sd(sd) ) {
script_pushint(st, 0);
return SCRIPT_CMD_FAILURE;
}
int32 x = script_getnum( st, 2 );
if( x < 0 || x > 100 ){
ShowError( "buildin_setdialogpospercent: x rate %d is out of range [0,100]\n", x );
return SCRIPT_CMD_FAILURE;
}
int32 y = script_getnum( st, 3 );
if( y < 0 || y > 100 ){
ShowError( "buildin_setdialogpospercent: y rate %d is out of range [0,100]\n", y );
return SCRIPT_CMD_FAILURE;
}
clif_set_npc_window_pos_percent( *sd, x, y );
return SCRIPT_CMD_SUCCESS;
}
#include <custom/script.inc>
// declarations that were supposed to be exported from npc_chat.cpp
@ -27883,6 +27991,11 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(autoloot,"??"),
BUILDIN_DEF(opentips, "i?"),
BUILDIN_DEF(setdialogalign, "i"),
BUILDIN_DEF(setdialogsize, "ii"),
BUILDIN_DEF(setdialogpos, "ii"),
BUILDIN_DEF(setdialogpospercent, "ii"),
#include <custom/script_def.inc>
{NULL,NULL,NULL},

View File

@ -2121,8 +2121,13 @@ enum e_hat_effects : int16{
HAT_EF_AUTUMN_FULL_MOON,
HAT_EF_NIFLHEIM_NIGHT_SKY,
HAT_EF_C_ROS2023_CAPE_1,
HAT_EF_BLACK_THUNDER_,
HAT_EF_C_ROS2023_CAPE_2,
HAT_EF_C_15TH_NOV_HELMET,
HAT_EF_COSMIC_CONNECTION,
HAT_EF_C_BABY_GLOOM,
HAT_EF_WINTERNIGHTBELLS,
HAT_EF_NIGHTSKYOFRUTIE,
HAT_EF_MAX
};
@ -2180,6 +2185,13 @@ enum e_iteminfo : uint8 {
ITEMINFO_SUBTYPE,
};
/* geteleminfo script command */
enum e_eleminfo : uint8 {
ELEMINFO_ID = 0,
ELEMINFO_GAMEID,
ELEMINFO_CLASS,
};
class ConstantDatabase : public YamlDatabase {
public:
ConstantDatabase() : YamlDatabase("CONSTANT_DB", 1) {

View File

@ -1900,6 +1900,16 @@
export_constant(SC_GROUNDGRAVITY);
export_constant(SC_BREAKINGLIMIT);
export_constant(SC_RULEBREAK);
export_constant(SC_INTENSIVE_AIM);
export_constant(SC_INTENSIVE_AIM_COUNT);
export_constant(SC_GRENADE_FRAGMENT_1);
export_constant(SC_GRENADE_FRAGMENT_2);
export_constant(SC_GRENADE_FRAGMENT_3);
export_constant(SC_GRENADE_FRAGMENT_4);
export_constant(SC_GRENADE_FRAGMENT_5);
export_constant(SC_GRENADE_FRAGMENT_6);
export_constant(SC_AUTO_FIRING_LAUNCHER);
export_constant(SC_HIDDEN_CARD);
// Sky Emperor
export_constant(SC_RISING_SUN);
@ -5316,7 +5326,6 @@
export_constant(IG_CARDALBUM_GARMENT);
export_constant(IG_FLAMEL_CARD);
export_constant(IG_SPECIAL_BOX);
export_constant(IG_TRESURE_BOX_WOE_);
export_constant(IG_RWC_PARTI_BOX);
export_constant(IG_RWC_FINAL_COMP_BOX);
export_constant(IG_GIFT_BUNDLE);
@ -7039,6 +7048,737 @@
export_constant(IG_DUN_VOUCHER_BOX2);
export_constant(IG_BLUEBOXOFQUESTIONS);
export_constant(IG_ENCHANT_STONE_BOX33);
export_constant(IG_PC_BANG_COIN_BOX3);
export_constant(IG_PCBANG_GIFT_BOX);
export_constant(IG_PCBANG_COUPON_BOX2);
export_constant(IG_PCBANG_COUPON_BOX3);
export_constant(IG_CHANCE_BOX);
export_constant(IG_ATTEND_3DAY_BOX);
export_constant(IG_ATTEND_7DAY_BOX);
export_constant(IG_ATTEND_10DAY_BOX);
export_constant(IG_ATTEND_15DAY_BOX);
export_constant(IG_ATTEND_20DAY_BOX);
export_constant(IG_ATTEND_25DAY_BOX);
export_constant(IG_GOLDPC_FIRST_BOX);
export_constant(IG_TICKET_GIFT_BOX);
export_constant(IG_TICKET_GIFT_BOX2);
export_constant(IG_ASSORTED_SCROLL_BOX);
export_constant(IG_DROOPING_KITTY_BOX);
export_constant(IG_MAGESTIC_GOAT_BOX);
export_constant(IG_DEVIRUCHI_CAP_BOX);
export_constant(IG_EXECUTIONER_BOX);
export_constant(IG_BROOD_AXE_BOX);
export_constant(IG_TOMAHAWK_BOX);
export_constant(IG_BOW_OF_RUDRA_BOX);
export_constant(IG_CUTLAS_BOX);
export_constant(IG_SOLAR_SWORD_BOX);
export_constant(IG_SWORD_BREAKER_BOX);
export_constant(IG_MAIL_BREAKER_BOX);
export_constant(IG_MOONLIGHT_SWORD_BOX);
export_constant(IG_SPANNER_BOX);
export_constant(IG_WEAPON_CARD_SCROLL);
export_constant(IG_ARMOR_CARD_SCROLL);
export_constant(IG_HELMET_CARD_SCROLL);
export_constant(IG_HOOD_CARD_SCROLL);
export_constant(IG_HOOD_CARD_SCROLL2);
export_constant(IG_SHOES_CARD_SCROLL);
export_constant(IG_ACCY_CARD_SCROLL);
export_constant(IG_WEAPON_CARD_SCROLL2);
export_constant(IG_WEAPON_CARD_SCROLL3);
export_constant(IG_ARMOR_CARD_SCROLL2);
export_constant(IG_ACCY_CARD_SCROLL2);
export_constant(IG_ASPERSIO_5_BOX30);
export_constant(IG_ASPERSIO_5_BOX50);
export_constant(IG_HANDCUFF_BOX);
export_constant(IG_INFILTRATOR_BOX1);
export_constant(IG_MURAMASA_BOX1);
export_constant(IG_EXCALIBUR_BOX1);
export_constant(IG_COMBAT_KNIFE_BOX1);
export_constant(IG_COUNTER_DAGGER_BOX1);
export_constant(IG_KAISER_KNUCKLE_BOX1);
export_constant(IG_POLE_AXE_BOX1);
export_constant(IG_MIGHTY_STAFF_BOX1);
export_constant(IG_RIGHT_EPSILON_BOX1);
export_constant(IG_BALISTAR_BOX1);
export_constant(IG_DIARY_OF_SAGE_BOX1);
export_constant(IG_ASURA_BOX1);
export_constant(IG_APPLE_OF_ARCHER_BOX1);
export_constant(IG_BUNNY_BAND_BOX1);
export_constant(IG_SAHKKAT_BOX1);
export_constant(IG_LORD_CIRCLET_BOX1);
export_constant(IG_ELVEN_EARS_BOX1);
export_constant(IG_STEEL_FLOWER_BOX1);
export_constant(IG_CRITICAL_RING_BOX1);
export_constant(IG_EARRING_BOX1);
export_constant(IG_RING_BOX1);
export_constant(IG_NECKLACE_BOX1);
export_constant(IG_GLOVE_BOX1);
export_constant(IG_BROOCH_BOX1);
export_constant(IG_ROSARY_BOX1);
export_constant(IG_SAFETY_RING_BOX1);
export_constant(IG_VESPER_CORE01_BOX1);
export_constant(IG_VESPER_CORE02_BOX1);
export_constant(IG_VESPER_CORE03_BOX1);
export_constant(IG_VESPER_CORE04_BOX1);
export_constant(IG_DROOPING_KITTY_BOX1);
export_constant(IG_MAGESTIC_GOAT_BOX1);
export_constant(IG_DEVIRUCHI_CAP_BOX1);
export_constant(IG_EXECUTIONER_BOX1);
export_constant(IG_BROOD_AXE_BOX1);
export_constant(IG_TOMAHAWK_BOX1);
export_constant(IG_CUTLAS_BOX1);
export_constant(IG_SOLAR_SWORD_BOX1);
export_constant(IG_MOONLIGHT_SWORD_BOX1);
export_constant(IG_SPANNER_BOX1);
export_constant(IG_FREYJA_OVERCOAT_BOX);
export_constant(IG_FREYJA_BOOTS_BOX);
export_constant(IG_FREYJA_CAPE_BOX);
export_constant(IG_FREYJA_CROWN_BOX);
export_constant(IG_BRO_PACKAGE1);
export_constant(IG_PECOPECO_HAIRBAND_BOX);
export_constant(IG_RED_GLASSES_BOX);
export_constant(IG_WHISPER_MASK_BOX);
export_constant(IG_GOLD_BOX_);
export_constant(IG_SILVER_BOX_);
export_constant(IG_PECOPECO_HAIRBAND_BOX1);
export_constant(IG_RED_GLASSES_BOX1);
export_constant(IG_WHISPER_MASK_BOX1);
export_constant(IG_RAMEN_HAT_BOX1);
export_constant(IG_5_ANNIVERSARY_COIN_BOX);
export_constant(IG_CERTIFICATE_TW_BOX);
export_constant(IG_NAGAN_BOX);
export_constant(IG_SKEWER_BOX);
export_constant(IG_SURVIVAL_ROD_BOX);
export_constant(IG_QUADRILLE_BOX);
export_constant(IG_GREAT_AXE_BOX);
export_constant(IG_BLOODY_ROAR_BOX);
export_constant(IG_HARDBACK_BOX);
export_constant(IG_IMMATERIAL_SWORD_BOX);
export_constant(IG_UNHOLY_TOUCH_BOX);
export_constant(IG_CLOAK_OF_SURVIVAL_BOX);
export_constant(IG_MASQUERADE_BOX);
export_constant(IG_ORC_HERO_HELM_BOX);
export_constant(IG_EVIL_WING_EARS_BOX);
export_constant(IG_DARK_BLINDFOLD_BOX);
export_constant(IG_KRO_DROOPING_KITTY_BOX);
export_constant(IG_CORSAIR_BOX);
export_constant(IG_BLOODY_IRON_BALL_BOX);
export_constant(IG_SPIRITUAL_RING_BOX);
export_constant(IG_NAGAN_BOX1);
export_constant(IG_SKEWER_BOX1);
export_constant(IG_SURVIVAL_ROD_BOX1);
export_constant(IG_QUADRILLE_BOX1);
export_constant(IG_GREAT_AXE_BOX1);
export_constant(IG_FIRE_BRAND_BOX1);
export_constant(IG_IMMATERIAL_SWORD_BOX1);
export_constant(IG_UNHOLY_TOUCH_BOX1);
export_constant(IG_CLOAK_OF_SURVIVAL_BOX1);
export_constant(IG_MASQUERADE_BOX1);
export_constant(IG_ORC_HERO_HELM_BOX1);
export_constant(IG_EVIL_WING_EARS_BOX1);
export_constant(IG_DARK_BLINDFOLD_BOX1);
export_constant(IG_KRO_DROOPING_KITTY_BOX1);
export_constant(IG_CORSAIR_BOX1);
export_constant(IG_SPIRITUAL_RING_BOX1);
export_constant(IG_INDONESIA_BOX);
export_constant(IG_GREEN_BOX_);
export_constant(IG_RESIST_BOX1);
export_constant(IG_RESIST_BOX2);
export_constant(IG_STAT_BOOST1);
export_constant(IG_STAT_BOOST2);
export_constant(IG_STAT_BOOST3);
export_constant(IG_STAT_BOOST4);
export_constant(IG_OBSERVER_BOX);
export_constant(IG_LUCKY_CLIP_BOX);
export_constant(IG_F_LEVER_ACTION_RIFLE_BO);
export_constant(IG_F_REFRESH_SHOES_BOX);
export_constant(IG_F_PECOPECO_HAIRBAND_BOX);
export_constant(IG_F_RED_GLASSES_BOX);
export_constant(IG_F_WHISPER_MASK_BOX);
export_constant(IG_F_RAMEN_HAT_BOX);
export_constant(IG_F_VIGORGRA_PACKAGE3);
export_constant(IG_F_VIGORGRA_PACKAGE4);
export_constant(IG_NOVICE_SET_BOX);
export_constant(IG_BEHOLDER_RING_BOX2);
export_constant(IG_HALLOW_RING_BOX2);
export_constant(IG_CLAMOROUS_RING_BOX2);
export_constant(IG_CHEMICAL_RING_BOX2);
export_constant(IG_INSECTICIDE_RING_BOX2);
export_constant(IG_FISHER_RING_BOX2);
export_constant(IG_DECUSSATE_RING_BOX2);
export_constant(IG_BLOODY_RING_BOX2);
export_constant(IG_SATANIC_RING_BOX2);
export_constant(IG_DRAGOON_RING_BOX2);
export_constant(IG_FPICTURE_DIARY_BOX);
export_constant(IG_FMINI_HEART_BOX);
export_constant(IG_FNEWCOMER_BOX);
export_constant(IG_FKID_BOX);
export_constant(IG_FMAGIC_CASTLE_BOX);
export_constant(IG_FBULGING_HEAD_BOX);
export_constant(IG_FPICTURE_DIARY_BOX_1M);
export_constant(IG_FMINI_HEART_BOX_1M);
export_constant(IG_FNEWCOMER_BOX_1M);
export_constant(IG_FKID_BOX_1M);
export_constant(IG_FMAGIC_CASTLE_BOX_1M);
export_constant(IG_FBULGING_HEAD_BOX_1M);
export_constant(IG_FHEALING_STAFF_BOX);
export_constant(IG_FPRAXINUS_BOX);
export_constant(IG_MUFFLER_C_BOX);
export_constant(IG_VALKYRJA_S_SHIELD_C_BOX);
export_constant(IG_SKUL_RING_C_BOX);
export_constant(IG_S_BARRICADE_REPAIR_KIT);
export_constant(IG_S_GSTONE_REPAIR_KIT);
export_constant(IG_ARDOR_SCROLL);
export_constant(IG_HOLY_SABER_BOX);
export_constant(IG_BOOK_OF_PRAYER_BOX);
export_constant(IG_PHENOMENA_WHIP_BOX);
export_constant(IG_STAFF_OF_DARKNESS_BOX);
export_constant(IG_MONK_KNUCKLE_BOX);
export_constant(IG_MACE_OF_MADNESS_BOX);
export_constant(IG_SPEAR_OF_EXCELLENT_BOX);
export_constant(IG_BOW_OF_EVIL_BOX);
export_constant(IG_KATAR_OF_SPEED_BOX);
export_constant(IG_SS_REVOLVER_BOX);
export_constant(IG_XMAS_SCROLL);
export_constant(IG_FORTUNE_SWORD_BOX_I);
export_constant(IG_HOUSE_AUGER_BOX_I);
export_constant(IG_KAMAITACHI_BOX_I);
export_constant(IG_BERSERK_GUITAR_BOX_I);
export_constant(IG_DOOM_SLAYER_BOX_I);
export_constant(IG_HUUMA_BLAZE_BOX_I);
export_constant(IG_ODIN_S_BLESSING_BOX_I);
export_constant(IG_RING_OF_F_LORD_BOX_I);
export_constant(IG_RING_OF_RESON_BOX_I);
export_constant(IG_BOY_S_CAP_BOX_I);
export_constant(IG_ULLE_CAP_BOX_I);
export_constant(IG_SPINX_HELM_BOX_I);
export_constant(IG_POWER_OF_THOR_BOX);
export_constant(IG_ACTI_POTION_BOX);
export_constant(IG_ACTI_POTION_BOX2);
export_constant(IG_HALF_ASPRIKA_BOX);
export_constant(IG_HALF_BRYNHILD_BOX);
export_constant(IG_SPIKED_SCARF_BOX);
export_constant(IG_RAINBOW_SCARF_BOX);
export_constant(IG_3D_GLASSES_BOX);
export_constant(IG_CHEER_SCARF_BOX);
export_constant(IG_CHEER_SCARF2_BOX);
export_constant(IG_CHEER_SCARF3_BOX);
export_constant(IG_CHEER_SCARF4_BOX);
export_constant(IG_CHEER_SCARF6_BOX);
export_constant(IG_CHEER_SCARF8_BOX);
export_constant(IG_CHEER_SCARF10_BOX);
export_constant(IG_CHEER_SCARF10_BOX2);
export_constant(IG_RING_OF_VALKYRIE_BOX);
export_constant(IG_RAPID_LIFE_WATER_BOX);
export_constant(IG_LOLLI_POP_BOX);
export_constant(IG_SPECIAL_BOX1);
export_constant(IG_SPECIAL_BOX2);
export_constant(IG_SPECIAL_BOX3);
export_constant(IG_SPECIAL_BOX4);
export_constant(IG_SPECIAL_BOX5);
export_constant(IG_PCBANG_COUPON_BOX);
export_constant(IG_B_HALTER_BOX_30DAYS);
export_constant(IG_PCBANG_COUPON_BOX4);
export_constant(IG_OLD_HAT_BOX);
export_constant(IG_SAPA_FEAT_CERT_PACK);
export_constant(IG_ARCHANGEL_WING_BOX);
export_constant(IG_TRANS_BOX_DEVI);
export_constant(IG_TRANS_BOX_RAY_ARCH);
export_constant(IG_TRANS_BOX_MAVKA);
export_constant(IG_TRANS_BOX_MARDUK);
export_constant(IG_TRANS_BOX_BANSHEE);
export_constant(IG_TRANS_BOX_GOLEM);
export_constant(IG_UPG_REVOLVER_BOX2);
export_constant(IG_UPG_TWOHAND_SWORD_BOX2);
export_constant(IG_UPG_KATAR_BOX2);
export_constant(IG_UPG_TWO_HANDED_AXE_BOX2);
export_constant(IG_UPG_LANCE_BOX2);
export_constant(IG_UPG_BOOK_BOX2);
export_constant(IG_UPG_STAFF_BOX2);
export_constant(IG_UPG_DAGGER_BOX2);
export_constant(IG_UPG_MACE_BOX2);
export_constant(IG_UPG_BOW_BOX2);
export_constant(IG_GRYPHON_EGG_SCROLL);
export_constant(IG_ASPD_POTION_BOX10);
export_constant(IG_DRAGON_EGG_SCROLL);
export_constant(IG_2011_RWC_SCROLL_KR);
export_constant(IG_CHANGE_NAME_CARD_BOX2);
export_constant(IG_PCBANG_COUPON_BOX5);
export_constant(IG_CRU_SCROLL);
export_constant(IG_EVENT_GIFT_BOX);
export_constant(IG_EVENT_GIFT_BOX_);
export_constant(IG_TIME_GUARDIAN_BOX);
export_constant(IG_BEGINNER_KIT_BOX);
export_constant(IG_MOTHER_LOVE_BOX);
export_constant(IG_OLD_ORE_BOX_);
export_constant(IG_BOARDING_HALTER_BOX3);
export_constant(IG_UNDEAD_EGG);
export_constant(IG_GIRLS_HEART);
export_constant(IG_C_CENTER_POT_BOX);
export_constant(IG_C_AWAKENING_POT_BOX);
export_constant(IG_C_BERSERK_POT_BOX);
export_constant(IG_C_WING_OF_FLY_BOX);
export_constant(IG_REFINE_ORE_BOX3);
export_constant(IG_GUARANTEE7_BOX);
export_constant(IG_WOLFKING_SCROLL);
export_constant(IG_ALMIGHTY_BOX2);
export_constant(IG_HD_ELUNIUM_BOX30);
export_constant(IG_HD_ORIDECON_BOX30);
export_constant(IG_KINGS_GIFT);
export_constant(IG_C_CENTER_POT_3D_BOX);
export_constant(IG_C_AWAKENING_POT_3D_BOX);
export_constant(IG_C_BERSERK_POT_3D_BOX);
export_constant(IG_BM_LIMIT_PACK);
export_constant(IG_GOLDENTREASUREBOX);
export_constant(IG_UNLIMITED_10_BOX);
export_constant(IG_XMAX_EGG_KR);
export_constant(IG_C_FESTIVAL_TICKET);
export_constant(IG_REFINE_ORE_BOX4);
export_constant(IG_REFINE_ORE_BOX4_SET10);
export_constant(IG_REFINE_ORE_BOX4_SET20);
export_constant(IG_NEW_YEAR_GIFT_BOX);
export_constant(IG_PCBANG_COUPON_BOX6);
export_constant(IG_SEALED_D_LORD_SCROLL);
export_constant(IG_STEALFIGHTER_20LV);
export_constant(IG_STEALFIGHTER_25LV);
export_constant(IG_KINGS_GIFT2);
export_constant(IG_HAPPY_CALL_BOX);
export_constant(IG_SEALED_KNIGHT_WS_SCROLL);
export_constant(IG_C_WING_OF_FLY_1DAY_BOX);
export_constant(IG_SILVERVINE_BOX10_);
export_constant(IG_SILVERVINE_BOX110);
export_constant(IG_SEALED_BERZ_SCROLL);
export_constant(IG_3_LIFE_POTION_PACK);
export_constant(IG_3_LIFE_POTION_10PACK);
export_constant(IG_CLEARBOX_S);
export_constant(IG_SEALED_KIEL_SCROLL);
export_constant(IG_SEALED_GLOOM_SCROLL);
export_constant(IG_REFINE_ORE_BOX5);
export_constant(IG_REFINE_ORE_BOX5_SET10);
export_constant(IG_ANGELING_PACKAGE);
export_constant(IG_DEVILING_PACKAGE);
export_constant(IG_OLD_HAT_BOX_);
export_constant(IG_MEMORIAL_BOX);
export_constant(IG_WET_CARDALBUM);
export_constant(IG_GOLDEN_CARD);
export_constant(IG_SHADOW_BOX3);
export_constant(IG_11TH_S_PACKAGE);
export_constant(IG_SILVERVINE_BOX10_2);
export_constant(IG_SILVERVINE_BOX110_2);
export_constant(IG_GEMSTONE_SHADOW_BOX);
export_constant(IG_SEALED_F_BISHOP_SCROLL);
export_constant(IG_HANGULDAY_BOX);
export_constant(IG_3_LIFE_POTION_PACK2);
export_constant(IG_3_LIFE_POTION_10PACK2);
export_constant(IG_SEALED_IFRIT_SCROLL);
export_constant(IG_BISCUIT_STICK_SET);
export_constant(IG_PREMIUM_BOOK_BOX);
export_constant(IG_LI_EMPELIUM_BOX);
export_constant(IG_LI_UPG_BUCKLER_BOX);
export_constant(IG_REFINE_ORE_BOX6);
export_constant(IG_REFINE_ORE_BOX6_SET10);
export_constant(IG_SEALED_TURTLEG_SCROLL);
export_constant(IG_SEALED_BACSOJIN_SCROLL);
export_constant(IG_GREED_SHADOW_BOX);
export_constant(IG_HEAL_SHADOW_BOX);
export_constant(IG_HIDING_SHADOW_BOX);
export_constant(IG_CLOAKING_SHADOW_BOX);
export_constant(IG_COSTUME_FESTIVAL_BOX2);
export_constant(IG_C_WING_OF_FLY_5DAY_BOX);
export_constant(IG_TELEPORT_SHADOW_BOX);
export_constant(IG_STEAL_SHADOW_BOX);
export_constant(IG_SEALED_PHARAOH_SCROLL);
export_constant(IG_QUESTION_BOX);
export_constant(IG_SEALED_M_FLOWER_SCROLL);
export_constant(IG_SEALED_B_YGNIZEM_SCROLL);
export_constant(IG_REFINE_ORE_BOX7);
export_constant(IG_REFINE_ORE_BOX7_SET10);
export_constant(IG_SEALED_APO_H_SCROLL);
export_constant(IG_PC_NOMALBOX);
export_constant(IG_PC_WOODENBOX);
export_constant(IG_PC_GOLDENBOX);
export_constant(IG_PC_PLATINUMBOX);
export_constant(IG_3_LIFE_POTION_PACK4);
export_constant(IG_3_LIFE_POTION_10PACK4);
export_constant(IG_SEALED_DRACULA_SCROLL);
export_constant(IG_BEARERS_SHADOW_BOX);
export_constant(IG_VIGORGRA_PACKAGE_V4);
export_constant(IG_VIGORGRA_PACKAGE_SET_V4);
export_constant(IG_SEALED_B_SHECIL_SCROLL);
export_constant(IG_NYANGVINE_BOX4);
export_constant(IG_NYANGVINE_BOX10);
export_constant(IG_NYANGVINE_BOX40);
export_constant(IG_REFINE_ORE_BOX8);
export_constant(IG_REFINE_ORE_BOX8_SET10);
export_constant(IG_SEALED_CARD);
export_constant(IG_LI_HD_ELUNIUM_BOX30);
export_constant(IG_LI_HD_ORIDECON_BOX30);
export_constant(IG_UNLIMITED_BOX3);
export_constant(IG_UNLIMITED_10_BOX3);
export_constant(IG_GUARANTEE_RELAX_SCROLL);
export_constant(IG_LIMIT_MANUAL_BOX);
export_constant(IG_SEALED_DRACULA_SCROLL2);
export_constant(IG_3_LIFE_POTION_10PACK5);
export_constant(IG_3_LIFE_POTION_PACK5);
export_constant(IG_SEALED_MYSTERIOUS_EGG);
export_constant(IG_SEALED_DRACULA_ALBUM);
export_constant(IG_LIMIT_POWER_BOOSTER_BOX);
export_constant(IG_LIMIT_POWER_BOOSTER100);
export_constant(IG_SEALED_BERZ_ALBUM);
export_constant(IG_SEALED_BERZ_SCROLL2);
export_constant(IG_NYANGVINE_BOX200);
export_constant(IG_APRILGIFTBOX);
export_constant(IG_NOVEMBERGIFTBOX);
export_constant(IG_SEPTEMBERGIFTBOX);
export_constant(IG_REFINE_ORE_BOX9);
export_constant(IG_REFINE_ORE_BOX9_SET10);
export_constant(IG_2015_NEW_YEAR_SCROLL);
export_constant(IG_NEW_YEAR_SHADOW_CUBE);
export_constant(IG_2015GOLDPCBOX);
export_constant(IG_ALMIGHTY_BOX4);
export_constant(IG_ALMIGHTY100_BOX2);
export_constant(IG_SEALED_SCROLL2);
export_constant(IG_INVISIBLE_BOX);
export_constant(IG_FREEZE_DREAM);
export_constant(IG_LAPINE_DDUKDDAKBOX);
export_constant(IG_GUNSLINGER_BOX);
export_constant(IG_MINI_FAN_BOX);
export_constant(IG_KAFRA_BOX);
export_constant(IG_CANDY_BOX_MELEE);
export_constant(IG_CANDY_BOX_RANGE);
export_constant(IG_CANDY_BOX_MAGIC);
export_constant(IG_BLOODYKNIGHT_SHIELD_BOX);
export_constant(IG_E_WING_OF_FLY_3DAY_BOX);
export_constant(IG_REBEGINER_BOX);
export_constant(IG_REBEGINER_S_BOX);
export_constant(IG_OVERWHELM_ARMOR_BOX);
export_constant(IG_POWERFUL_HELM_BOX);
export_constant(IG_MYSTERIOUS_PLASTIC);
export_constant(IG_80LVUP);
export_constant(IG_JUMPING_KIT_BOX);
export_constant(IG_MAIN_LUCKY_BOX_);
export_constant(IG_SILLIT_PONG_BOX);
export_constant(IG_KUNAI_SCROLL_OF_FLAME);
export_constant(IG_KUNAI_SCROLL_OF_ICICLE);
export_constant(IG_KUNAI_SCROLL_OF_POISON);
export_constant(IG_KUNAI_SCROLL_OF_SOIL);
export_constant(IG_KUNAI_SCROLL_OF_WIND);
export_constant(IG_C_CATPAW_7DAY_BOX_);
export_constant(IG_CANNON_BALL_BOX);
export_constant(IG_IRON_CANNON_BALL_BOX);
export_constant(IG_SOUL_CANNON_BALL_BOX);
export_constant(IG_DARK_CANNON_BALL_BOX);
export_constant(IG_HOLY_CANNON_BALL_BOX);
export_constant(IG_CANNON_BOX_6);
export_constant(IG_MAGIC_GEAR_FUEL_BOX);
export_constant(IG_REPAIRA_BOX);
export_constant(IG_REPAIRB_BOX);
export_constant(IG_REPAIRC_BOX);
export_constant(IG_FLAME_STONE_BUNDLE);
export_constant(IG_ICE_STONE_BUNDLE);
export_constant(IG_WIND_STONE_BUNDLE);
export_constant(IG_SHADOW_ORB_BUNDLE);
export_constant(IG_CHARM_FIRE_BUNDLE);
export_constant(IG_CHARM_ICE_BUNDLE);
export_constant(IG_CHARM_WIND_BUNDLE);
export_constant(IG_CHARM_EARTH_BUNDLE);
export_constant(IG_KUNAI_SCROLL_EXPLOSIVE);
export_constant(IG_GEMSTONE_BLUE);
export_constant(IG_GEMSTONE_YL);
export_constant(IG_GEMSTONE_RED);
export_constant(IG_BULLET_CASE_FULL);
export_constant(IG_BULLET_CASE_MINE);
export_constant(IG_BULLET_CASE_TAIL);
export_constant(IG_C_BRAID_HALF_UP_BOX);
export_constant(IG_POENETENTIA_BOX3);
export_constant(IG_POENETENTIA_BOX4);
export_constant(IG_CHUSEOG_PRESENT_BOX);
export_constant(IG_LI_NYANGVINE_BOX100_2);
export_constant(IG_BARMUND_RUNE_BOX);
export_constant(IG_SEALED_CARD3);
export_constant(IG_LI_NYANGVINE_STONE_BOX3);
export_constant(IG_RO_LIVE_SHOP_BOX);
export_constant(IG_RO_LIVE_SHOP_EX_BOX);
export_constant(IG_SEASON_EVT_REWARD_11);
export_constant(IG_CANNON_BOX_ICE);
export_constant(IG_CANNON_BOX_LIGHTNING);
export_constant(IG_CANNON_BOX_STONE);
export_constant(IG_CANNON_BOX_FLARE);
export_constant(IG_CANNON_BOX_POISONING);
export_constant(IG_KUNAI_SCROLL);
export_constant(IG_KUNAI_SCROLL_NOTHING);
export_constant(IG_KUNAI_SCROLL_SHADOW);
export_constant(IG_KUNAI_SCROLL_HAMAYA);
export_constant(IG_NW_GRENADE_BOX);
export_constant(IG_SOA_CHARM_BUNDLE);
export_constant(IG_SS_CHARM_BOX);
export_constant(IG_SS_CHARM_F_BOX);
export_constant(IG_SS_CHARM_W_BOX);
export_constant(IG_SS_CHARM_G_BOX);
export_constant(IG_SS_CHARM_L_BOX);
export_constant(IG_PAYMENT_COSTUME_BOX1);
export_constant(IG_PAYMENT_COSTUME_BOX2);
export_constant(IG_2021_PROMO_PACKAGE_1);
export_constant(IG_2021_PROMO_PACKAGE_2);
export_constant(IG_E_BOARDING_HALTER_BOX);
export_constant(IG_COSTUMEMILEAGE_PACKAGE4);
export_constant(IG_COSTUMEMILEAGE_PACKAGE5);
export_constant(IG_COSTUMEMILEAGE_PACKAGE6);
export_constant(IG_EVT_RAGFES_BOX);
export_constant(IG_KR_B_SPECIAL08);
export_constant(IG_KR_B_SPECIAL05);
export_constant(IG_SEASON_EVT_REWARD_12);
export_constant(IG_SECURITY_CAMPAIGN_BOX);
export_constant(IG_HERO_HAMMER_PACKAGE_6);
export_constant(IG_HERO_UP_PACKAGE_6);
export_constant(IG_HERO_TOKEN_BOX);
export_constant(IG_JANUARYGIFTBOX_);
export_constant(IG_FEBRUARYGIFTBOX_);
export_constant(IG_MARCHGIFTBOX_);
export_constant(IG_APRILGIFTBOX_);
export_constant(IG_MAYGIFTBOX_);
export_constant(IG_JUNEGIFTBOX_);
export_constant(IG_JULYGIFTBOX_);
export_constant(IG_AUGUSTGIFTBOX_);
export_constant(IG_SEPTEMBERGIFTBOX_);
export_constant(IG_OCTOBERGIFTBOX_);
export_constant(IG_NOVEMBERGIFTBOX_);
export_constant(IG_DECEMBERGIFTBOX_);
export_constant(IG_SEASON_EVT_REWARD_1);
export_constant(IG_2021_WINTER_EVENT_BOX1);
export_constant(IG_2021_WINTER_EVENT_BOX2);
export_constant(IG_ICE_F_STONE_BOX);
export_constant(IG_BS_MAKING_S);
export_constant(IG_MONTHLY_PACKAGE_1);
export_constant(IG_MONTHLY_PACKAGE_2);
export_constant(IG_MONTHLY_PACKAGE_3);
export_constant(IG_MONTHLY_BUFF_PACKAGE);
export_constant(IG_MONTHLY_BATTLE_PACKAGE);
export_constant(IG_MD_AIRBOAT_EXPBOX);
export_constant(IG_ENCHANT_TICKET_3);
export_constant(IG_FAN_GREED_1HOUR_BOX);
export_constant(IG_KAKAO_PLUS_BOX);
export_constant(IG_COSTUMEMILEPACK_27_1);
export_constant(IG_COSTUMEMILEPACK_27_2);
export_constant(IG_COSTUMEMILEPACK_27_3);
export_constant(IG_P_BOOSTER230_GIFT);
export_constant(IG_BOOSTER230_GIFT);
export_constant(IG_BOOSTER_PACK_10);
export_constant(IG_BOOSTER_PACK_20);
export_constant(IG_BOOSTER_PACK_40);
export_constant(IG_BOOSTER_PACK_50);
export_constant(IG_BOOSTER_PACK_70);
export_constant(IG_BOOSTER_PACK_80);
export_constant(IG_BOOSTER_PACK_110);
export_constant(IG_BOOSTER_PACK_120);
export_constant(IG_BOOSTER_PACK_140);
export_constant(IG_BOOSTER_PACK_150);
export_constant(IG_BOOSTER_PACK_170);
export_constant(IG_BOOSTER_PACK_180);
export_constant(IG_BOOSTER_PACK_210);
export_constant(IG_BOOSTER_PACK_220);
export_constant(IG_BOOSTER_PACK_240);
export_constant(IG_BOOSTER_PACK_250);
export_constant(IG_BOOSTER_CALL_PACKAGE);
export_constant(IG_E_BOARDING_HALTER_BOX2);
export_constant(IG_SHADOW_UP_BOX);
export_constant(IG_VIVA_ADUL_HAT_BOX_11);
export_constant(IG_EVT_MAKINGMATERIALS_BOX);
export_constant(IG_LI_NYANGVINE_BOX1_28);
export_constant(IG_LI_NYANGVINE_BOX2_28);
export_constant(IG_LI_NYANGVINE_BOX3_28);
export_constant(IG_EVT_20TH_WHITEGOLD);
export_constant(IG_EVT_20TH_GOLD);
export_constant(IG_EVT_20TH_SILVER);
export_constant(IG_EVT_20TH_BRONZE);
export_constant(IG_EVT_20TH_RETURN);
export_constant(IG_EVT_20TH_RETURN2);
export_constant(IG_E_CLOTH_DYE_BOX);
export_constant(IG_PLAIN_RUNE_BOX5);
export_constant(IG_FLAME_RUNE_BOX5);
export_constant(IG_ICE_RUNE_BOX5);
export_constant(IG_DEATH_RUNE_BOX5);
export_constant(IG_RO_FESTIVAL_BOX);
export_constant(IG_SERVICE1_M_01_BOX);
export_constant(IG_SERVICE1_M_05_BOX);
export_constant(IG_SERVICE1_M_07_BOX);
export_constant(IG_SERVICE1_M_10_BOX);
export_constant(IG_SERVICE1P_M_01_BOX);
export_constant(IG_SERVICE1P_M_05_BOX);
export_constant(IG_SERVICE1P_M_07_BOX);
export_constant(IG_SERVICE1P_M_10_BOX);
export_constant(IG_SERVICE1_F_01_BOX);
export_constant(IG_SERVICE1_F_05_BOX);
export_constant(IG_SERVICE1_F_07_BOX);
export_constant(IG_SERVICE1_F_10_BOX);
export_constant(IG_SERVICE1P_F_01_BOX);
export_constant(IG_SERVICE1P_F_05_BOX);
export_constant(IG_SERVICE1P_F_07_BOX);
export_constant(IG_SERVICE1P_F_10_BOX);
export_constant(IG_R_BEARERS_EARRING_BOX);
export_constant(IG_R_BEARERS_PENDANT_BOX);
export_constant(IG_R_BEARERS_ARMOR_BOX);
export_constant(IG_R_BEARERS_SHOES_BOX);
export_constant(IG_HASTY_WEAPON_BOX);
export_constant(IG_HASTY_SHIELD_BOX);
export_constant(IG_S_RELOAD_SHIELD_BOX);
export_constant(IG_RO_ARENA_BOX);
export_constant(IG_RO_ARENA_BOX2);
export_constant(IG_HEROSRIA_GIFT);
export_constant(IG_MAUTOSPELL_EARRING_BOX);
export_constant(IG_MAUTOSPELL_PENDANT_BOX);
export_constant(IG_MAUTOSPELL_ARMOR_BOX);
export_constant(IG_MAUTOSPELL_SHOES_BOX);
export_constant(IG_INFINITY_WEAPON_BOX);
export_constant(IG_INFINITY_SHIELD_BOX);
export_constant(IG_LUXURIOUS_BLUE_BOX);
export_constant(IG_VR_BOOK_EVENT);
export_constant(IG_LI_NYANGVINE_BOX1_29);
export_constant(IG_LI_NYANGVINE_BOX2_29);
export_constant(IG_LI_NYANGVINE_BOX3_29);
export_constant(IG_EXP_WEAPON_BOX);
export_constant(IG_EXP_SHIELD_BOX);
export_constant(IG_M_BLITZ_WEAPON_BOX);
export_constant(IG_M_BLITZ_SHIELD_BOX);
export_constant(IG_CVT_WING_BOX);
export_constant(IG_TEMPLE_RUNE_BOX5);
export_constant(IG_VENOM_RUNE_BOX5);
export_constant(IG_SOUL_RUNE_BOX5);
export_constant(IG_CASH_BOOSTER_BOX);
export_constant(IG_A_BUBBLE_GUM_BOX10);
export_constant(IG_COSTUMEMILEPACK_29_1);
export_constant(IG_COSTUMEMILEPACK_29_2);
export_constant(IG_COSTUMEMILEPACK_29_3);
export_constant(IG_S_BEARERS_CUBE);
export_constant(IG_PENE_SET_CUBE);
export_constant(IG_TEMP_SET_CUBE);
export_constant(IG_JUSTICE_WEAPON_BOX);
export_constant(IG_INJUSTICE_WEAPON_BOX);
export_constant(IG_GOODNEVIL_HELM_BOX);
export_constant(IG_F_EIN_1HDAGGER_BOX);
export_constant(IG_SHADOW_SELECT_BOX_SET);
export_constant(IG_REFINE_HAMMER_BOX);
export_constant(IG_LI_NYANGVINE_BOX1_30);
export_constant(IG_LI_NYANGVINE_BOX2_30);
export_constant(IG_LI_NYANGVINE_BOX3_30);
export_constant(IG_SLD_BOSS_CARD_ALBUM);
export_constant(IG_COSTUMEMILEPACK_30_1);
export_constant(IG_COSTUMEMILEPACK_30_2);
export_constant(IG_COSTUMEMILEPACK_30_3);
export_constant(IG_VIP_GIFT);
export_constant(IG_VVIP_GIFT);
export_constant(IG_SVIP_GIFT);
export_constant(IG_2023_SPRING_COLLECTION);
export_constant(IG_KR_B_SPECIAL04);
export_constant(IG_LI_NYANGVINE_BOX1_31);
export_constant(IG_LI_NYANGVINE_BOX2_31);
export_constant(IG_LI_NYANGVINE_BOX3_31);
export_constant(IG_STONE_ROBE3_BOX);
export_constant(IG_RO_CONCERT_SCROLL);
export_constant(IG_RO_CONCERT_SCROLL_BOX);
export_constant(IG_FAN_UPGRADE_KIT_EX_10);
export_constant(IG_KR_B_SPECIAL06);
export_constant(IG_COSTUMEMILEPACK_31_1);
export_constant(IG_COSTUMEMILEPACK_31_2);
export_constant(IG_COSTUMEMILEPACK_31_3);
export_constant(IG_CATPAW_1DAY_BOX);
export_constant(IG_MILEAGE_COUPON);
export_constant(IG_LI_NYANGVINE_BOX1_32);
export_constant(IG_LI_NYANGVINE_BOX2_32);
export_constant(IG_LI_NYANGVINE_BOX3_32);
export_constant(IG_21TH_PRESENT_BOX);
export_constant(IG_21TH_COSTUME_COLLECTION);
export_constant(IG_S_ENCHANT_ESSENCE_BOX_3);
export_constant(IG_SEASON_EVT_REWARD_8);
export_constant(IG_COSTUMEMILEPACK_32_1);
export_constant(IG_COSTUMEMILEPACK_32_2);
export_constant(IG_COSTUMEMILEPACK_32_3);
export_constant(IG_M_ARMOR_BOX);
export_constant(IG_M_SHOES_BOX);
export_constant(IG_M_PENDANT_BOX);
export_constant(IG_M_EARRING_BOX);
export_constant(IG_EIN_ORE_BOX);
export_constant(IG_FATE_FRAGMENT_BOX);
export_constant(IG_SIN_FRAGMENT_BOX);
export_constant(IG_AMETHYST_FRAGMENT_BOX);
export_constant(IG_SNOW_F_ORE_BOX);
export_constant(IG_SCHMIDT_ANTIQUITY);
export_constant(IG_SCHMIDT_ANTIQUITY2);
export_constant(IG_AMDARAIS_ANTIQUITY);
export_constant(IG_AMDARAIS_ANTIQUITY2);
export_constant(IG_C_AMDARAIS_ANTIQUITY);
export_constant(IG_C_HIMEL_ANTIQUITY);
export_constant(IG_UNKNOWN_ANTIQUITY);
export_constant(IG_SAKRAY_ANTIQUITY);
export_constant(IG_AIRBOAT_ANTIQUITY);
export_constant(IG_CELINE_KIMI_ANTIQUITY);
export_constant(IG_MIGUEL_ANTIQUITY);
export_constant(IG_EL_A17T_ANTIQUITY);
export_constant(IG_PITAYA_BOSS_ANTIQUITY);
export_constant(IG_SWEETY_ANTIQUITY);
export_constant(IG_REDPEPPER_ANTIQUITY);
export_constant(IG_REDPEPPER_ANTIQUITY2);
export_constant(IG_DEMI_FREYJA_ANTIQUITY);
export_constant(IG_JUNCEA_ANTIQUITY);
export_constant(IG_AQUILA_ANTIQUITY);
export_constant(IG_AQUILA_ANTIQUITY2);
export_constant(IG_F_ICESLUG_ANTIQUIY);
export_constant(IG_LASGAND_ANTIQUITY);
export_constant(IG_LASGAND_ANTIQUITY2);
export_constant(IG_THANATOS_ANTIQUITY);
export_constant(IG_CINNAMON_PACK1);
export_constant(IG_CINNAMON_PACK2);
export_constant(IG_CINNAMON_PACK3);
export_constant(IG_CINNAMON_PACK4);
export_constant(IG_COS_ENCHANTSTONE_BOX1);
export_constant(IG_COS_ENCHANTSTONE_BOX2);
export_constant(IG_COS_ENCHANTSTONE_BOX3);
export_constant(IG_T_GARDEN_EV_1);
export_constant(IG_T_GARDEN_EV_2);
export_constant(IG_T_GARDEN_EV_3);
export_constant(IG_LI_NYANGVINE_BOX1_33);
export_constant(IG_LI_NYANGVINE_BOX2_33);
export_constant(IG_LI_NYANGVINE_BOX3_33);
export_constant(IG_LI_NYANG_CINNA_BOX1_33);
export_constant(IG_LI_NYANG_CINNA_BOX2_33);
export_constant(IG_LI_NYANG_CINNA_BOX3_33);
export_constant(IG_BL_DEPTH_EV_1);
export_constant(IG_BL_DEPTH_EV_2);
export_constant(IG_KR_B_SPECIAL09);
export_constant(IG_LI_A_ELUNIUM_BOX);
export_constant(IG_LI_A_ORIDECON_BOX);
export_constant(IG_PRESENTBOX_EP17_2);
export_constant(IG_PRESENTBOX_EP18);
export_constant(IG_REFINE_EVENT_BOX);
export_constant(IG_PRESENTBOX_EP19);
export_constant(IG_PRESENTBOX_EP20);
export_constant(IG_PRESENTBOX_GLASTHEIM);
export_constant(IG_BROWN_DIA_BOX);
export_constant(IG_COSTUMEMILEPACK_33_1);
export_constant(IG_COSTUMEMILEPACK_33_2);
export_constant(IG_COSTUMEMILEPACK_33_3);
export_constant(IG_2023_XMAX_PACK_1);
export_constant(IG_2023_XMAX_PACK_2);
export_constant(IG_A_FORCE_BOOSTER_BOX);
export_constant(IG_A_FORCE_BOOSTER_10_BOX);
export_constant(IG_BROWN_DIA_BOX_3_7);
export_constant(IG_2401_EV_LUNCH_BOX);
export_constant(IG_BLACK_DIA_3_BOX);
export_constant(IG_LI_NYANGVINE_BOX1_34);
export_constant(IG_LI_NYANGVINE_BOX2_34);
export_constant(IG_LI_NYANGVINE_BOX3_34);
export_constant(IG_ENCHANT_STONE_BOX34);
export_constant(IG_S_BADGE_PACK);
export_constant(IG_SUPER_SONIC_PACK);
export_constant(IG_CHAOS_EMERALD_PACK);
export_constant(IG_VIP_BIRTHDAY_BOX);
export_constant(IG_R_EP17_ALBUM);
export_constant(IG_R_EP178_BOSS);
export_constant(IG_SONIC_PREMIUM_PACK1);
export_constant(IG_SONIC_PREMIUM_PACK2);
export_constant(IG_S_BADGE_PACK_);
export_constant(IG_SUPER_SONIC_PACK_);
export_constant(IG_CHAOS_EMERALD_PACK_);
/* unit stop walking */
export_constant(USW_NONE);
@ -8322,6 +9062,30 @@
export_constant_npc(JT_4_LARVA_VIOLET);
export_constant_npc(JT_4_HERO_SAUSAGE);
export_constant_npc(JT_4_PRINCESS_SAUSAGE);
export_constant_npc(JT_4_EP20_LASGAND);
export_constant_npc(JT_4_EP20_NYAR);
export_constant_npc(JT_4_EP20_DEVICE_BLUE);
export_constant_npc(JT_4_EP20_DEVICE_RED);
export_constant_npc(JT_4_EP20_DEVICE_BLACK);
export_constant_npc(JT_4_GACHA_MACHINE);
export_constant_npc(JT_4_VR_CHAO);
export_constant_npc(JT_4_RUNESTONE);
export_constant_npc(JT_4_EM_ARDOR);
export_constant_npc(JT_4_EM_DILUVIO);
export_constant_npc(JT_4_EM_PROCELLA);
export_constant_npc(JT_4_EM_TERREMOTUS);
export_constant_npc(JT_4_EM_SERPENS);
export_constant_npc(JT_4_SNOWDOG);
export_constant_npc(JT_1_SHADOW_RED);
export_constant_npc(JT_1_SHADOW_ORANGE);
export_constant_npc(JT_1_SHADOW_YELLOW);
export_constant_npc(JT_1_SHADOW_GREEN);
export_constant_npc(JT_1_SHADOW_BLUE);
export_constant_npc(JT_1_SHADOW_INDIGO);
export_constant_npc(JT_1_SHADOW_VIOLET);
export_constant_npc(JT_4_EVT_LAMMIR);
export_constant_npc(JT_4_EVT_SULKI);
export_constant_npc(JT_4_EVT_KKAT);
export_constant_npc(JT_ROZ_MQ_XAVIER);
export_constant_npc(JT_ROZ_MQ_MOCLORD);
export_constant_npc(JT_ROZ_MQ_SKULD);
@ -9679,8 +10443,13 @@
export_constant(HAT_EF_AUTUMN_FULL_MOON);
export_constant(HAT_EF_NIFLHEIM_NIGHT_SKY);
export_constant(HAT_EF_C_ROS2023_CAPE_1);
export_constant(HAT_EF_BLACK_THUNDER_);
export_constant(HAT_EF_C_ROS2023_CAPE_2);
export_constant(HAT_EF_C_15TH_NOV_HELMET);
export_constant(HAT_EF_COSMIC_CONNECTION);
export_constant(HAT_EF_C_BABY_GLOOM);
export_constant(HAT_EF_WINTERNIGHTBELLS);
export_constant(HAT_EF_NIGHTSKYOFRUTIE);
/* pet catch */
export_constant(PET_CATCH_UNIVERSAL);
@ -10216,6 +10985,11 @@
export_constant(ITEMINFO_ARMORLEVEL);
export_constant(ITEMINFO_SUBTYPE);
/* geteleminfo script command */
export_constant(ELEMINFO_ID);
export_constant(ELEMINFO_GAMEID);
export_constant(ELEMINFO_CLASS);
/* refine types */
export_constant(REFINE_TYPE_ARMOR);
export_constant(REFINE_TYPE_WEAPON);

View File

@ -2190,19 +2190,19 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl, uint
status_change_end(bl, SC_SOUNDBLEND);
break;
case EM_DIAMOND_STORM:
sc_start(src, bl, SC_HANDICAPSTATE_FROSTBITE, 40 + 10 * skill_lv, skill_lv, skill_get_time2(skill_id, skill_lv));
sc_start(src, bl, SC_HANDICAPSTATE_FROSTBITE, 5, skill_lv, skill_get_time2(skill_id, skill_lv));
break;
case EM_LIGHTNING_LAND:
sc_start(src, bl, SC_HANDICAPSTATE_LIGHTNINGSTRIKE, 10 + 10 * skill_lv, skill_lv, skill_get_time2(skill_id, skill_lv));
sc_start(src, bl, SC_HANDICAPSTATE_LIGHTNINGSTRIKE, 3, skill_lv, skill_get_time2(skill_id, skill_lv));
break;
case EM_VENOM_SWAMP:
sc_start(src, bl, SC_HANDICAPSTATE_DEADLYPOISON, 10 + 10 * skill_lv, skill_lv, skill_get_time2(skill_id, skill_lv));
sc_start(src, bl, SC_HANDICAPSTATE_DEADLYPOISON, 3, skill_lv, skill_get_time2(skill_id, skill_lv));
break;
case EM_CONFLAGRATION:
sc_start(src, bl, SC_HANDICAPSTATE_CONFLAGRATION, 10 + 10 * skill_lv, skill_lv, skill_get_time2(skill_id, skill_lv));
sc_start(src, bl, SC_HANDICAPSTATE_CONFLAGRATION, 3, skill_lv, skill_get_time2(skill_id, skill_lv));
break;
case EM_TERRA_DRIVE:
sc_start(src, bl, SC_HANDICAPSTATE_CRYSTALLIZATION, 40 + 10 * skill_lv, skill_lv, skill_get_time2(skill_id, skill_lv));
sc_start(src, bl, SC_HANDICAPSTATE_CRYSTALLIZATION, 5, skill_lv, skill_get_time2(skill_id, skill_lv));
break;
case MT_RUSH_QUAKE:
sc_start( src, bl, SC_RUSH_QUAKE1, 100, skill_lv, skill_get_time( skill_id, skill_lv ) );
@ -4799,6 +4799,29 @@ static TIMER_FUNC(skill_timerskill){
skill_unitsetting(src, skl->skill_id, skl->skill_lv, tmpx, tmpy, skill_get_unit_interval(skl->skill_id));
}
break;
case NW_HASTY_FIRE_IN_THE_HOLE:
skill_castend_pos2(src, skl->x, skl->y, skl->skill_id, skl->skill_lv, tick, skl->flag);
break;
case NW_GRENADES_DROPPING: {
int area = skill_get_splash(skl->skill_id, skl->skill_lv);
short tmpx = 0, tmpy = 0;
tmpx = skl->x - area + rnd() % (area * 2 + 1);
tmpy = skl->y - area + rnd() % (area * 2 + 1);
skill_unitsetting(src, skl->skill_id, skl->skill_lv, tmpx, tmpy, skl->flag);
}
break;
case NW_MISSION_BOMBARD: {
int area = skill_get_unit_range(skl->skill_id, skl->skill_lv);
int range = skill_get_splash(skl->skill_id, skl->skill_lv);
short tmpx = 0, tmpy = 0;
tmpx = skl->x - range + rnd() % (range * 2 + 1);
tmpy = skl->y - range + rnd() % (range * 2 + 1);
map_foreachinarea(skill_area_sub, src->m, tmpx - range, tmpy - range, tmpx + range, tmpy + range, BL_CHAR,
src, skl->skill_id, skl->skill_lv, tick, skl->flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
}
break;
}
}
} while (0);
@ -5240,6 +5263,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case ABR_DUAL_CANNON_FIRE:
case ABR_INFINITY_BUSTER:
case MT_TRIPLE_LASER:
case NW_MISSION_BOMBARD:
case NW_HASTY_FIRE_IN_THE_HOLE:
case NW_BASIC_GRENADE:
case NW_WILD_FIRE:
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
case DK_DRAGONIC_AURA:
@ -5271,9 +5298,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case SHC_SHADOW_STAB:
if (sc && sc->getSCE(SC_CLOAKINGEXCEED))
flag |= 2;// Flag to deal 3 hits.
status_change_end(src, SC_CLOAKING);
status_change_end(src, SC_CLOAKINGEXCEED);
@ -5883,6 +5907,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case WH_GALESTORM:// Give AP if 3 or more targets are hit.
if (sd && map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill_area_sub_count) >= 3)
status_heal(src, 0, 0, 10, 0);
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
break;
case BO_ACIDIFIED_ZONE_WATER:
case BO_ACIDIFIED_ZONE_GROUND:
@ -5926,6 +5951,24 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
}
break;
case NW_THE_VIGILANTE_AT_NIGHT:
if (flag & 1)
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
break;
case NW_SPIRAL_SHOOTING:
if (flag & 1) {
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
} else {
int splash = skill_get_splash(skill_id, skill_lv);
if (sd && sd->weapontype1 == W_GRENADE)
splash += 2;
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
map_foreachinrange(skill_area_sub, bl, splash, BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
status_change_end(src, SC_INTENSIVE_AIM_COUNT);
}
break;
case SH_HOWLING_OF_CHUL_HO:
if (flag & 1)
@ -7098,6 +7141,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
break;
case NW_MAGAZINE_FOR_ONE:
case NW_ONLY_ONE_BULLET:
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
status_change_end(src, SC_INTENSIVE_AIM_COUNT);
break;
default:
ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skill_id);
clif_skill_damage(src, bl, tick, status_get_amotion(src), tstatus->dmotion,
@ -7122,6 +7172,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
// perform skill requirement consumption
if (!(flag&SKILL_NOCONSUME_REQ))
skill_consume_requirement(sd,skill_id,skill_lv,2);
}
@ -7318,6 +7369,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
type = skill_get_sc(skill_id);
tsc = status_get_sc(bl);
status_change* sc = status_get_sc(src);
tsce = (tsc && type != SC_NONE)?tsc->getSCE(type):NULL;
status_change *sc = status_get_sc(src);
@ -12110,9 +12162,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
s_elemental_data *ele = BL_CAST(BL_ELEM, src);
if( ele ) {
sc_type type2 = (sc_type)(type-1);
status_change *sc = status_get_sc(&ele->bl);
status_change *esc = status_get_sc(&ele->bl);
if( (sc && sc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
if( (esc && esc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
status_change_end(src,type);
status_change_end(bl,type2);
} else {
@ -12137,11 +12189,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case EL_WATER_SCREEN: {
s_elemental_data *ele = BL_CAST(BL_ELEM, src);
if( ele ) {
status_change *sc = status_get_sc(&ele->bl);
status_change *esc = status_get_sc(&ele->bl);
sc_type type2 = (sc_type)(type-1);
clif_skill_nodamage(src,src,skill_id,skill_lv,1);
if( (sc && sc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
if( (esc && esc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
status_change_end(bl,type);
status_change_end(src,type2);
} else {
@ -12881,6 +12933,54 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1, skill_castend_damage_id);
break;
case NW_THE_VIGILANTE_AT_NIGHT:
i = skill_get_splash(skill_id, skill_lv);
skill_area_temp[0] = 0;
skill_area_temp[1] = bl->id;
skill_area_temp[2] = 0;
if (sd && sd->weapontype1 == W_GATLING) {
i = 5; // 11x11
clif_skill_nodamage(src, bl, NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING, skill_lv, 1);
} else
clif_skill_nodamage(src, bl, NW_THE_VIGILANTE_AT_NIGHT_GUN_SHOTGUN, skill_lv, 1);
map_foreachinrange(skill_area_sub, bl, i, BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
status_change_end(src, SC_INTENSIVE_AIM_COUNT);
break;
case NW_INTENSIVE_AIM:
if (tsc && tsc->getSCE(type)) {
status_change_end(src, SC_INTENSIVE_AIM_COUNT);
status_change_end(bl, type);
} else {
status_change_end(src, SC_INTENSIVE_AIM_COUNT);
sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
}
clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
break;
case NW_HIDDEN_CARD:
case NW_AUTO_FIRING_LAUNCHER:
sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
break;
case NW_GRENADE_FRAGMENT:
status_change_end(src, type);
if (skill_lv < 7)
sc_start(src, bl, (sc_type)(SC_GRENADE_FRAGMENT_1 -1 + skill_lv), 100, skill_lv, skill_get_time(skill_id, skill_lv));
else if (skill_lv == 7) {
status_change_end(src, SC_GRENADE_FRAGMENT_1);
status_change_end(src, SC_GRENADE_FRAGMENT_2);
status_change_end(src, SC_GRENADE_FRAGMENT_3);
status_change_end(src, SC_GRENADE_FRAGMENT_4);
status_change_end(src, SC_GRENADE_FRAGMENT_5);
status_change_end(src, SC_GRENADE_FRAGMENT_6);
}
clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
break;
case SH_HOWLING_OF_CHUL_HO:
i = skill_get_splash(skill_id, skill_lv);
if (pc_checkskill(sd, SH_COMMUNE_WITH_CHUL_HO) > 0 || (sc && sc->getSCE(SC_TEMPORARY_COMMUNION)))
@ -12998,6 +13098,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
skill_onskillusage(sd, bl, skill_id, tick);
// perform skill requirement consumption
if (!(flag&SKILL_NOCONSUME_REQ))
skill_consume_requirement(sd,skill_id,skill_lv,2);
}
@ -13713,6 +13814,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case SU_CN_METEOR:
case NPC_RAINOFMETEOR:
case HN_METEOR_STORM_BUSTER:
case NW_GRENADES_DROPPING:
break; //Effect is displayed on respective switch case.
default:
if(skill_get_inf(skill_id)&INF_SELF_SKILL)
@ -13753,6 +13855,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
break;
case SR_RIDEINLIGHTNING:
case NW_BASIC_GRENADE:
i = skill_get_splash(skill_id, skill_lv);
map_foreachinallarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR,
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
@ -14656,6 +14759,53 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
break;
case NW_WILD_FIRE:
i = skill_get_splash(skill_id, skill_lv);
if (sd && sd->status.weapon == W_GRENADE)
i += 2;
map_foreachinallarea(skill_area_sub,
src->m, x - i, y - i, x + i, y + i, BL_CHAR,
src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1,
skill_castend_damage_id);
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
status_change_end(src, SC_INTENSIVE_AIM_COUNT);
break;
case NW_HASTY_FIRE_IN_THE_HOLE:
i = skill_get_splash(skill_id, skill_lv);
if (flag & 1){
i++;
}
if (flag & 2){
i++;
}
map_foreachinallarea(skill_area_sub,
src->m, x - i, y - i, x + i, y + i, BL_CHAR,
src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1,
skill_castend_damage_id);
if (!(flag & 1)) {
skill_addtimerskill(src, tick + 300, 0, x, y, skill_id, skill_lv, 0, flag | 1 | SKILL_NOCONSUME_REQ);
skill_addtimerskill(src, tick + 600, 0, x, y, skill_id, skill_lv, 0, flag | 3 | SKILL_NOCONSUME_REQ);
}
break;
case NW_GRENADES_DROPPING: {
uint16 splash = skill_get_splash(skill_id, skill_lv);
uint16 tmpx = rnd_value( x - splash, x + splash );
uint16 tmpy = rnd_value( y - splash, y + splash );
skill_unitsetting(src, skill_id, skill_lv, tmpx, tmpy, flag);
for (i = 0; i <= (skill_get_time(skill_id, skill_lv) / skill_get_unit_interval(skill_id)); i++) {
skill_addtimerskill(src, tick + (t_tick)i*skill_get_unit_interval(skill_id), 0, x, y, skill_id, skill_lv, 0, flag);
}
} break;
case NW_MISSION_BOMBARD:
i = skill_get_splash(skill_id,skill_lv);
map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SKILL_ALTDMG_FLAG|1,skill_castend_damage_id);
skill_unitsetting(src, skill_id, skill_lv, x, y, flag);
for (i = 1; i <= (skill_get_time(skill_id, skill_lv) / skill_get_unit_interval(skill_id)); i++) {
skill_addtimerskill(src, tick + (t_tick)i*skill_get_unit_interval(skill_id), 0, x, y, skill_id, skill_lv, 0, flag);
}
break;
default:
ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skill_id);
return 1;
@ -14674,6 +14824,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
skill_onskillusage(sd, NULL, skill_id, tick);
// perform skill requirement consumption
if (!(flag&SKILL_NOCONSUME_REQ))
skill_consume_requirement(sd,skill_id,skill_lv,2);
}
@ -15322,6 +15473,10 @@ std::shared_ptr<s_skill_unit_group> skill_unitsetting(struct block_list *src, ui
case WH_FLAMETRAP:
limit += 3000 * (sd ? pc_checkskill(sd, WH_ADVANCED_TRAP) : 5);
break;
case NW_GRENADES_DROPPING:
limit = skill_get_time2(skill_id,skill_lv);
break;
}
// Init skill unit group
@ -18829,6 +18984,8 @@ struct s_skill_condition skill_get_requirement(map_session_data* sd, uint16 skil
req.mhp = skill->require.mhp[skill_lv-1];
req.weapon = skill->require.weapon;
req.ammo_qty = skill->require.ammo_qty[skill_lv-1];
if (skill_id == NW_MAGAZINE_FOR_ONE && sd->weapontype1 == W_GATLING)
req.ammo_qty += 4;
if (req.ammo_qty)
req.ammo = skill->require.ammo;
@ -24880,8 +25037,7 @@ uint64 MagicMushroomDatabase::parseBodyNode(const ryml::NodeRef& node) {
/** Reads skill no cast db
* Structure: SkillID,Flag
*/
static bool skill_parse_row_nocastdb(char* split[], int columns, int current)
{
static bool skill_parse_row_nocastdb( char* split[], size_t columns, size_t current ){
std::shared_ptr<s_skill_db> skill = skill_db.find(atoi(split[0]));
if (!skill)
@ -24895,8 +25051,7 @@ static bool skill_parse_row_nocastdb(char* split[], int columns, int current)
/** Reads Produce db
* Structure: ProduceItemID,ItemLV,RequireSkill,Requireskill_lv,MaterialID1,MaterialAmount1,...
*/
static bool skill_parse_row_producedb(char* split[], int columns, int current)
{
static bool skill_parse_row_producedb( char* split[], size_t columns, size_t current ){
unsigned short x, y;
unsigned short id = atoi(split[0]);
t_itemid nameid = 0;
@ -25085,8 +25240,7 @@ uint64 AbraDatabase::parseBodyNode(const ryml::NodeRef& node) {
/** Reads change material db
* Structure: ProductID,BaseRate,MakeAmount1,MakeAmountRate1...,MakeAmount5,MakeAmountRate5
*/
static bool skill_parse_row_changematerialdb(char* split[], int columns, int current)
{
static bool skill_parse_row_changematerialdb( char* split[], size_t columns, size_t current ){
uint16 id = atoi(split[0]);
t_itemid nameid = strtoul(split[1], nullptr, 10);
short rate = atoi(split[2]);
@ -25142,8 +25296,7 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
* Reads skill damage adjustment
* @author [Lilith]
*/
static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
{
static bool skill_parse_row_skilldamage( char* split[], size_t columns, size_t current ){
int64 caster_tmp;
uint16 id;
int caster, value;

View File

@ -41,6 +41,8 @@ class status_change;
/// To control alternative skill scalings
#define SKILL_ALTDMG_FLAG 0x10
/// Make skill ignore requirement consumption [Muh]
#define SKILL_NOCONSUME_REQ 0x20
/// Constants to identify a skill's nk value (damage properties)
/// The NK value applies only to non INF_GROUND_SKILL skills

View File

@ -4169,6 +4169,10 @@ int status_calc_pc_sub(map_session_data* sd, uint8 opt)
base_status->mdef++;
}
// ----- CONCENTRATION CALCULATION -----
if ((skill = pc_checkskill(sd, NW_GRENADE_MASTERY)) > 0)
base_status->con += skill;
// ------ ATTACK CALCULATION ------
// Base batk value is set in status_calc_misc
@ -4383,6 +4387,8 @@ int status_calc_pc_sub(map_session_data* sd, uint8 opt)
base_status->patk += skill;
if ((skill = pc_checkskill(sd, HN_SELFSTUDY_SOCERY)) > 0)
base_status->smatk += skill;
if ((skill = pc_checkskill(sd, NW_P_F_I)) > 0 && (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
base_status->patk += skill + 2;
// 2-Handed Staff Mastery
if( sd->status.weapon == W_2HSTAFF && ( skill = pc_checkskill( sd, AG_TWOHANDSTAFF ) ) > 0 ){
@ -4764,6 +4770,8 @@ int status_calc_pc_sub(map_session_data* sd, uint8 opt)
sd->bonus.short_attack_atk_rate += 5 * sc->getSCE( SC_RUSH_QUAKE2 )->val1;
sd->bonus.long_attack_atk_rate += 5 * sc->getSCE( SC_RUSH_QUAKE2 )->val1;
}
if (sc->getSCE(SC_HIDDEN_CARD))
sd->bonus.long_attack_atk_rate += sc->getSCE(SC_HIDDEN_CARD)->val3;
if (sc->getSCE(SC_DEADLY_DEFEASANCE))
sd->special_state.no_magic_damage = 0;
if (sc->getSCE(SC_CLIMAX_DES_HU))
@ -7087,6 +7095,8 @@ static unsigned short status_calc_batk(struct block_list *bl, status_change *sc,
batk += 20;
if(sc->getSCE(SC_SKF_ATK))
batk += sc->getSCE(SC_SKF_ATK)->val1;
if (sc->getSCE(SC_INTENSIVE_AIM))
batk += 150;
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
@ -7403,6 +7413,8 @@ static signed short status_calc_critical(struct block_list *bl, status_change *s
critical += sc->getSCE(SC_MTF_HITFLEE)->val1;
if (sc->getSCE(SC_PACKING_ENVELOPE9))
critical += sc->getSCE(SC_PACKING_ENVELOPE9)->val1 * 10;
if (sc->getSCE(SC_INTENSIVE_AIM))
critical += 300;
return (short)cap_value(critical,10,SHRT_MAX);
}
@ -7479,6 +7491,8 @@ static signed short status_calc_hit(struct block_list *bl, status_change *sc, in
hit += sc->getSCE(SC_LIMIT_POWER_BOOSTER)->val1;
if (sc->getSCE(SC_ACARAJE))
hit += 5;
if (sc->getSCE(SC_INTENSIVE_AIM))
hit += 250;
return (short)cap_value(hit,1,SHRT_MAX);
}
@ -8535,6 +8549,8 @@ static signed short status_calc_patk(struct block_list *bl, status_change *sc, i
if( sc->getSCE( SC_ATTACK_STANCE ) ){
patk += sc->getSCE( SC_ATTACK_STANCE )->val3;
}
if (sc->getSCE(SC_HIDDEN_CARD))
patk += sc->getSCE(SC_HIDDEN_CARD)->val2;
if (sc->getSCE(SC_TEMPORARY_COMMUNION))
patk += sc->getSCE(SC_TEMPORARY_COMMUNION)->val2;
if (sc->getSCE(SC_BLESSING_OF_M_CREATURES))
@ -12628,7 +12644,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
tick = INFINITE_TICK;
break;
case SC_GUARDIAN_S:
val2 = ( status->max_hp / 2 ) * ( 50 * val1 ) / 100 + 15 * status->sta; // Barrier HP
val2 = ( status->max_hp * 30 / 100 ) * ( 25 * val1 ) / 100 + 15 * status->sta; // Barrier HP
break;
case SC_REBOUND_S:
val2 = 10 * val1;// Reduced Damage From Devotion
@ -12769,6 +12785,13 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_WEAPONBREAKER:
val2 = val1 * 2 * 100; // Chance to break weapon
break;
case SC_INTENSIVE_AIM:
tick = 500;
break;
case SC_HIDDEN_CARD:
val2 = 3 * val1;
val3 = 10 * val1;
break;
case SC_TEMPORARY_COMMUNION:
val2 = val1 * 3;
break;
@ -12917,7 +12940,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
if (battle_config.sc_castcancel&bl->type && scdb->flag[SCF_STOPCASTING])
unit_skillcastcancel(bl,0);
sc->opt1 = scdb->opt1;
if(scdb->opt1 != OPT1_NONE) sc->opt1 = scdb->opt1;
sc->opt2 |= scdb->opt2;
sc->opt3 |= scdb->opt3;
sc->option |= scdb->look;
@ -14937,6 +14960,17 @@ TIMER_FUNC(status_change_timer){
if (sce->val4 >= 0)
skill_castend_damage_id( bl, bl, NPC_KILLING_AURA, sce->val1, tick, 0 );
break;
case SC_INTENSIVE_AIM:
if (!sc || !sc->getSCE(SC_INTENSIVE_AIM_COUNT))
sce->val4 = 0;
if (sce->val4 < 10) {
sce->val4++;
sc_start(bl, bl, SC_INTENSIVE_AIM_COUNT, 100, sce->val4, INFINITE_TICK);
}
sc_timer_next(500 + tick);
return 0;
case SC_KI_SUL_RAMPAGE:
if (sce->val4-- > 0) {
int i = skill_get_splash(SH_KI_SUL_RAMPAGE, sce->val1);
@ -15478,8 +15512,7 @@ void status_change_clear_onChangeMap(struct block_list *bl, status_change *sc)
* @param current: Current row being read into SCDisabled array
* @return True - Successfully stored, False - Invalid SC
*/
static bool status_readdb_status_disabled(char **str, int columns, int current)
{
static bool status_readdb_status_disabled( char **str, size_t columns, size_t current ){
int64 type = SC_NONE;
if (ISDIGIT(str[0][0]))

View File

@ -1350,6 +1350,18 @@ enum sc_type : int16 {
SC_BLESSING_OF_M_CREATURES,
SC_BLESSING_OF_M_C_DEBUFF,
// Night Watch
SC_INTENSIVE_AIM,
SC_INTENSIVE_AIM_COUNT,
SC_GRENADE_FRAGMENT_1,
SC_GRENADE_FRAGMENT_2,
SC_GRENADE_FRAGMENT_3,
SC_GRENADE_FRAGMENT_4,
SC_GRENADE_FRAGMENT_5,
SC_GRENADE_FRAGMENT_6,
SC_AUTO_FIRING_LAUNCHER,
SC_HIDDEN_CARD,
#ifdef RENEWAL
SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
#endif

View File

@ -577,7 +577,7 @@ bool Csv2YamlTool::initialize( int argc, char* argv[] ){
// Copied and adjusted from guild.cpp
// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
static bool guild_read_guildskill_tree_db( char* split[], int columns, int current ){
static bool guild_read_guildskill_tree_db( char* split[], size_t columns, size_t current ){
uint16 skill_id = (uint16)atoi(split[0]);
std::string* name = util::umap_find( aegis_skillnames, skill_id );
@ -802,8 +802,7 @@ static bool pet_read_db( const char* file ){
}
// Copied and adjusted from skill.cpp
static bool skill_parse_row_magicmushroomdb(char *split[], int column, int current)
{
static bool skill_parse_row_magicmushroomdb( char *split[], size_t column, size_t current ){
uint16 skill_id = atoi(split[0]);
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
@ -820,8 +819,7 @@ static bool skill_parse_row_magicmushroomdb(char *split[], int column, int curre
}
// Copied and adjusted from skill.cpp
static bool skill_parse_row_abradb(char* split[], int columns, int current)
{
static bool skill_parse_row_abradb( char* split[], size_t columns, size_t current ){
uint16 skill_id = atoi(split[0]);
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
@ -861,8 +859,7 @@ static bool skill_parse_row_abradb(char* split[], int columns, int current)
}
// Copied and adjusted from skill.cpp
static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
{
static bool skill_parse_row_spellbookdb( char* split[], size_t columns, size_t current ){
uint16 skill_id = atoi(split[0]);
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
@ -889,7 +886,7 @@ static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
}
// Copied and adjusted from mob.cpp
static bool mob_readdb_mobavail(char* str[], int columns, int current) {
static bool mob_readdb_mobavail( char* str[], size_t columns, size_t current ){
uint16 mob_id = atoi(str[0]);
std::string *mob_name = util::umap_find(aegis_mobnames, mob_id);
@ -1121,8 +1118,7 @@ static bool mob_readdb_mobavail(char* str[], int columns, int current) {
// skill_db.yml function
//----------------------
static bool skill_parse_row_requiredb(char* split[], int columns, int current)
{
static bool skill_parse_row_requiredb( char* split[], size_t columns, size_t current ){
s_skill_require entry = {};
skill_split_atoi(split[1], entry.hp);
@ -1236,8 +1232,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
// skill_db.yml function
//----------------------
static bool skill_parse_row_castdb(char* split[], int columns, int current)
{
static bool skill_parse_row_castdb( char* split[], size_t columns, size_t current ){
s_skill_db entry = {};
skill_split_atoi(split[1], entry.cast);
@ -1257,8 +1252,7 @@ static bool skill_parse_row_castdb(char* split[], int columns, int current)
// skill_db.yml function
//----------------------
static bool skill_parse_row_castnodexdb(char* split[], int columns, int current)
{
static bool skill_parse_row_castnodexdb( char* split[], size_t columns, size_t current ){
s_skill_db entry = {};
entry.castnodex = atoi(split[1]);
@ -1272,8 +1266,7 @@ static bool skill_parse_row_castnodexdb(char* split[], int columns, int current)
// skill_db.yml function
//----------------------
static bool skill_parse_row_unitdb(char* split[], int columns, int current)
{
static bool skill_parse_row_unitdb( char* split[], size_t columns, size_t current ){
s_skill_unit_csv entry = {};
entry.unit_id = (uint16)strtol(split[1], NULL, 16);
@ -1291,8 +1284,7 @@ static bool skill_parse_row_unitdb(char* split[], int columns, int current)
// skill_db.yml function
//----------------------
static bool skill_parse_row_copyabledb(char* split[], int column, int current)
{
static bool skill_parse_row_copyabledb( char* split[], size_t column, size_t current ){
s_skill_copyable entry = {};
int skill_id = -1;
@ -1321,8 +1313,7 @@ static bool skill_parse_row_copyabledb(char* split[], int column, int current)
// skill_db.yml function
//----------------------
static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int current)
{
static bool skill_parse_row_nonearnpcrangedb( char* split[], size_t column, size_t current ){
s_skill_db entry = {};
int skill_id = -1;
@ -1350,7 +1341,7 @@ static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int curr
}
// Copied and adjusted from skill.cpp
static bool skill_parse_row_skilldb(char* split[], int columns, int current) {
static bool skill_parse_row_skilldb( char* split[], size_t columns, size_t current ){
int arr[MAX_SKILL_LEVEL], arr_size, skill_id = atoi(split[0]);
body << YAML::BeginMap;
@ -2323,7 +2314,7 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current) {
}
// Copied and adjusted from quest.cpp
static bool quest_read_db(char *split[], int columns, int current) {
static bool quest_read_db( char *split[], size_t columns, size_t current ){
int quest_id = atoi(split[0]);
if (quest_id < 0 || quest_id >= INT_MAX) {
@ -2459,7 +2450,7 @@ static bool quest_read_db(char *split[], int columns, int current) {
}
// Copied and adjusted from instance.cpp
static bool instance_readdb_sub(char* str[], int columns, int current) {
static bool instance_readdb_sub( char* str[], size_t columns, size_t current ){
body << YAML::BeginMap;
body << YAML::Key << "Id" << YAML::Value << atoi(str[0]);
body << YAML::Key << "Name" << YAML::Value << str[1];
@ -2498,21 +2489,21 @@ static bool instance_readdb_sub(char* str[], int columns, int current) {
// item_db.yml function
//---------------------
static bool itemdb_read_itemavail(char *str[], int columns, int current) {
static bool itemdb_read_itemavail( char *str[], size_t columns, size_t current ){
item_avail.insert({ strtoul(str[0], nullptr, 10), strtoul(str[1], nullptr, 10) });
return true;
}
// item_db.yml function
//---------------------
static bool itemdb_read_buyingstore(char* fields[], int columns, int current) {
static bool itemdb_read_buyingstore( char* fields[], size_t columns, size_t current ){
item_buyingstore.insert({ strtoul(fields[0], nullptr, 10), true });
return true;
}
// item_db.yml function
//---------------------
static bool itemdb_read_flag(char* fields[], int columns, int current) {
static bool itemdb_read_flag( char* fields[], size_t columns, size_t current ){
s_item_flag_csv2yaml item = { 0 };
uint16 flag = abs(atoi(fields[1]));
@ -2547,7 +2538,7 @@ static bool itemdb_read_flag(char* fields[], int columns, int current) {
// item_db.yml function
//---------------------
static bool itemdb_read_itemdelay(char* str[], int columns, int current) {
static bool itemdb_read_itemdelay( char* str[], size_t columns, size_t current ){
s_item_delay_csv2yaml item = { 0 };
item.delay = atoi(str[1]);
@ -2561,7 +2552,7 @@ static bool itemdb_read_itemdelay(char* str[], int columns, int current) {
// item_db.yml function
//---------------------
static bool itemdb_read_stack(char* fields[], int columns, int current) {
static bool itemdb_read_stack( char* fields[], size_t columns, size_t current ){
s_item_stack_csv2yaml item = { 0 };
item.amount = atoi(fields[1]);
@ -2583,7 +2574,7 @@ static bool itemdb_read_stack(char* fields[], int columns, int current) {
// item_db.yml function
//---------------------
static bool itemdb_read_nouse(char* fields[], int columns, int current) {
static bool itemdb_read_nouse( char* fields[], size_t columns, size_t current ){
s_item_nouse_csv2yaml item = { 0 };
item.sitting = "true";
@ -2595,7 +2586,7 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current) {
// item_db.yml function
//---------------------
static bool itemdb_read_itemtrade(char* str[], int columns, int current) {
static bool itemdb_read_itemtrade( char* str[], size_t columns, size_t current ){
s_item_trade_csv2yaml item = { 0 };
int flag = atoi(str[1]);
@ -3103,7 +3094,7 @@ static bool itemdb_read_randomopt(const char* file) {
}
// Copied and adjusted from itemdb.cpp
static bool itemdb_read_randomopt_group(char* str[], int columns, int current) {
static bool itemdb_read_randomopt_group( char* str[], size_t columns, size_t current ){
if ((columns - 2) % 3 != 0) {
ShowError("itemdb_read_randomopt_group: Invalid column entries '%d'.\n", columns);
return false;
@ -3205,7 +3196,7 @@ static bool itemdb_randomopt_group_yaml(void) {
return true;
}
static bool pc_readdb_levelpenalty( char* fields[], int columns, int current ){
static bool pc_readdb_levelpenalty( char* fields[], size_t columns, size_t current ){
// 1=experience, 2=item drop
int type = atoi( fields[0] );
@ -3269,7 +3260,7 @@ bool pc_levelpenalty_yaml(){
// mob_db.yml function
//--------------------
static bool mob_readdb_race2(char *fields[], int columns, int current) {
static bool mob_readdb_race2( char *fields[], size_t columns, size_t current ){
int64 race;
if (ISDIGIT(fields[0][0]))
@ -3300,7 +3291,7 @@ static bool mob_readdb_race2(char *fields[], int columns, int current) {
// mob_db.yml function
//--------------------
static bool mob_readdb_drop(char *str[], int columns, int current) {
static bool mob_readdb_drop( char *str[], size_t columns, size_t current ){
uint32 mob_id = strtoul(str[0], nullptr, 10);
std::string *mob_name = util::umap_find(aegis_mobnames, static_cast<uint16>(mob_id));
@ -3347,7 +3338,7 @@ static bool mob_readdb_drop(char *str[], int columns, int current) {
}
// Copied and adjusted from mob.cpp
static bool mob_readdb_sub(char *fields[], int columns, int current) {
static bool mob_readdb_sub( char *fields[], size_t columns, size_t current ){
uint32 mob_id = strtoul(fields[0], nullptr, 10);
body << YAML::BeginMap;
@ -3711,7 +3702,7 @@ static bool mob_readdb_sub(char *fields[], int columns, int current) {
}
// Copied and adjusted from mob.cpp
static bool mob_parse_row_chatdb(char* fields[], int columns, int current) {
static bool mob_parse_row_chatdb( char* fields[], size_t columns, size_t current ){
int msg_id = atoi(fields[0]);
if (msg_id <= 0){
@ -3783,7 +3774,7 @@ static bool read_homunculus_expdb(const char* file) {
}
// Copied and adjusted from mob.cpp
static bool mob_readdb_group(char* str[], int columns, int current) {
static bool mob_readdb_group( char* str[], size_t columns, size_t current ){
if (strncasecmp(str[0], "MOBG_", 5) != 0) {
ShowError("The group %s must start with 'MOBG_'.\n", str[0]);
return false;
@ -3859,8 +3850,7 @@ static bool mob_readdb_group_yaml(void) {
}
// Copied and adjusted from skill.cpp
static bool skill_parse_row_createarrowdb(char* split[], int columns, int current)
{
static bool skill_parse_row_createarrowdb( char* split[], size_t columns, size_t current ){
t_itemid nameid = static_cast<t_itemid>(strtoul(split[0], nullptr, 10));
if (nameid == 0)
@ -3944,7 +3934,7 @@ static bool pc_read_statsdb(const char* file) {
}
// Copied and adjusted from guild.cpp
static bool guild_read_castledb(char* str[], int columns, int current) {
static bool guild_read_castledb( char* str[], size_t columns, size_t current ){
body << YAML::BeginMap;
body << YAML::Key << "Id" << YAML::Value << str[0];
body << YAML::Key << "Map" << YAML::Value << str[1];
@ -3955,7 +3945,7 @@ static bool guild_read_castledb(char* str[], int columns, int current) {
}
// Copied and adjusted from int_guild.cpp
static bool exp_guild_parse_row(char* split[], int column, int current) {
static bool exp_guild_parse_row( char* split[], size_t column, size_t current ){
t_exp exp = strtoull(split[0], nullptr, 10);
if (exp > MAX_GUILD_EXP) {
@ -3972,7 +3962,7 @@ static bool exp_guild_parse_row(char* split[], int column, int current) {
}
// Copied and adjusted from itemdb.cpp
static bool itemdb_read_group(char* str[], int columns, int current) {
static bool itemdb_read_group( char* str[], size_t columns, size_t current ){
if (strncasecmp(str[0], "IG_", 3) != 0) {
ShowError("The group %s must start with 'IG_'.\n", str[0]);
return false;
@ -4122,7 +4112,7 @@ static bool itemdb_read_group_yaml(void) {
}
// Copied and adjusted from mob.cpp
static bool mob_readdb_itemratio(char* str[], int columns, int current) {
static bool mob_readdb_itemratio( char* str[], size_t columns, size_t current ){
t_itemid nameid = strtoul(str[0], nullptr, 10);
std::string *item_name = util::umap_find(aegis_itemnames, nameid);
@ -4222,7 +4212,7 @@ static bool status_readdb_attrfix(const char* file) {
}
// Copied and adjusted from script.cpp
static bool read_constdb(char* fields[], int columns, int current) {
static bool read_constdb( char* fields[], size_t columns, size_t current ){
char name[1024], val[1024];
int type = 0;
@ -4252,7 +4242,7 @@ static bool read_constdb(char* fields[], int columns, int current) {
// job_db.yml function
//----------------------
static bool pc_readdb_job2(char* fields[], int columns, int current) {
static bool pc_readdb_job2( char* fields[], size_t columns, size_t current ){
std::vector<int> stats;
stats.resize(MAX_LEVEL);
@ -4267,7 +4257,7 @@ static bool pc_readdb_job2(char* fields[], int columns, int current) {
// job_db.yml function
//----------------------
static bool pc_readdb_job_param(char* fields[], int columns, int current) {
static bool pc_readdb_job_param( char* fields[], size_t columns, size_t current ){
int job_id = atoi(fields[0]);
s_job_param entry = {};
@ -4285,7 +4275,7 @@ static bool pc_readdb_job_param(char* fields[], int columns, int current) {
// job_basehpsp_db.yml function
//----------------------
static bool pc_readdb_job_exp_sub(char* fields[], int columns, int current) {
static bool pc_readdb_job_exp_sub( char* fields[], size_t columns, size_t current ){
int level = atoi(fields[0]), jobs[CLASS_COUNT], job_count = skill_split_atoi(fields[1], jobs, CLASS_COUNT), type = atoi(fields[2]);
for (int i = 0; i < job_count; i++) {
@ -4299,7 +4289,7 @@ static bool pc_readdb_job_exp_sub(char* fields[], int columns, int current) {
}
// Copied and adjusted from pc.cpp
static bool pc_readdb_job_exp(char* fields[], int columns, int current) {
static bool pc_readdb_job_exp( char* fields[], size_t columns, size_t current ){
int level = atoi(fields[0]), jobs[CLASS_COUNT], job_count = skill_split_atoi(fields[1], jobs, CLASS_COUNT), type = atoi(fields[2]);
body << YAML::BeginMap;
@ -4337,7 +4327,7 @@ static bool pc_readdb_job_exp(char* fields[], int columns, int current) {
}
// Copied and adjusted from pc.cpp
static bool pc_readdb_job_basehpsp(char* fields[], int columns, int current) {
static bool pc_readdb_job_basehpsp( char* fields[], size_t columns, size_t current ){
int type = atoi(fields[3]), jobs[CLASS_COUNT], job_count = skill_split_atoi(fields[2], jobs, CLASS_COUNT);
body << YAML::BeginMap;
@ -4401,7 +4391,7 @@ static bool pc_readdb_job_basehpsp(char* fields[], int columns, int current) {
}
// Copied and adjusted from pc.cpp
static bool pc_readdb_job1(char* fields[], int columns, int current) {
static bool pc_readdb_job1( char* fields[], size_t columns, size_t current ){
int job_id = atoi(fields[0]);
if (job_id == JOB_WEDDING)
@ -4499,7 +4489,7 @@ static bool pc_readdb_job1(char* fields[], int columns, int current) {
// elemental_db.yml function
//---------------------------
static bool read_elemental_skilldb(char* str[], int columns, int current) {
static bool read_elemental_skilldb( char* str[], size_t columns, size_t current ){
uint16 skill_id = atoi(str[1]);
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
@ -4533,7 +4523,7 @@ static bool read_elemental_skilldb(char* str[], int columns, int current) {
}
// Copied and adjusted from elemental.cpp
static bool read_elementaldb(char* str[], int columns, int current) {
static bool read_elementaldb( char* str[], size_t columns, size_t current ){
body << YAML::BeginMap;
body << YAML::Key << "Id" << YAML::Value << str[0];
body << YAML::Key << "AegisName" << YAML::Value << str[1];
@ -4609,7 +4599,7 @@ static bool read_elementaldb(char* str[], int columns, int current) {
// mercenary_db.yml function
//---------------------------
static bool mercenary_read_skilldb(char* str[], int columns, int current) {
static bool mercenary_read_skilldb( char* str[], size_t columns, size_t current ){
uint16 skill_id = atoi(str[1]);
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
@ -4636,7 +4626,7 @@ static bool mercenary_read_skilldb(char* str[], int columns, int current) {
}
// Copied and adjusted from mercenary.cpp
static bool mercenary_readdb(char* str[], int columns, int current) {
static bool mercenary_readdb( char* str[], size_t columns, size_t current ){
body << YAML::BeginMap;
body << YAML::Key << "Id" << YAML::Value << str[0];
body << YAML::Key << "AegisName" << YAML::Value << str[1];
@ -4716,7 +4706,7 @@ static bool mercenary_readdb(char* str[], int columns, int current) {
}
// Copied and adjusted from pc.cpp
static bool pc_readdb_skilltree(char* fields[], int columns, int current) {
static bool pc_readdb_skilltree( char* fields[], size_t columns, size_t current ){
uint16 baselv, joblv, offset;
uint16 class_ = (uint16)atoi(fields[0]);
uint16 skill_id = (uint16)atoi(fields[1]);
@ -4947,7 +4937,7 @@ static bool itemdb_read_combos(const char* file) {
}
// Copied and adjusted from cashshop.cpp
static bool cashshop_parse_dbrow( char* fields[], int columns, int current ){
static bool cashshop_parse_dbrow( char* fields[], size_t columns, size_t current ){
uint16 tab = atoi( fields[0] );
t_itemid nameid = strtoul( fields[1], nullptr, 10 );
uint32 price = atoi( fields[2] );
@ -4994,7 +4984,7 @@ static bool cashshop_parse_dbrow( char* fields[], int columns, int current ){
// homunculus_db.yml function
//---------------------------
static bool read_homunculus_skilldb(char* split[], int columns, int current) {
static bool read_homunculus_skilldb( char* split[], size_t columns, size_t current ){
s_homun_skill_tree_entry entry = {};
entry.id = atoi(split[1]);
@ -5022,7 +5012,7 @@ static bool compareHomSkillId(const s_homun_skill_tree_entry &a, const s_homun_s
}
// Copied and adjusted from homunculus.cpp
static bool read_homunculusdb(char* str[], int columns, int current) {
static bool read_homunculusdb( char* str[], size_t columns, size_t current ){
bool has_evo = false;
body << YAML::BeginMap;

View File

@ -476,65 +476,65 @@ void init_random_option_constants() {
#undef export_constant2
}
static bool guild_read_guildskill_tree_db( char* split[], int columns, int current );
static bool guild_read_guildskill_tree_db( char* split[], size_t columns, size_t current );
static bool pet_read_db( const char* file );
static bool skill_parse_row_magicmushroomdb(char *split[], int column, int current);
static bool skill_parse_row_abradb(char* split[], int columns, int current);
static bool skill_parse_row_spellbookdb(char* split[], int columns, int current);
static bool mob_readdb_mobavail(char *str[], int columns, int current);
static bool skill_parse_row_requiredb(char* split[], int columns, int current);
static bool skill_parse_row_castdb(char* split[], int columns, int current);
static bool skill_parse_row_castnodexdb(char* split[], int columns, int current);
static bool skill_parse_row_unitdb(char* split[], int columns, int current);
static bool skill_parse_row_copyabledb(char* split[], int columns, int current);
static bool skill_parse_row_nonearnpcrangedb(char* split[], int columns, int current);
static bool skill_parse_row_skilldb(char* split[], int columns, int current);
static bool quest_read_db(char *split[], int columns, int current);
static bool instance_readdb_sub(char* str[], int columns, int current);
static bool itemdb_read_itemavail(char *str[], int columns, int current);
static bool itemdb_read_buyingstore(char* fields[], int columns, int current);
static bool itemdb_read_flag(char* fields[], int columns, int current);
static bool itemdb_read_itemdelay(char* str[], int columns, int current);
static bool itemdb_read_stack(char* fields[], int columns, int current);
static bool itemdb_read_nouse(char* fields[], int columns, int current);
static bool itemdb_read_itemtrade(char* fields[], int columns, int current);
static bool skill_parse_row_magicmushroomdb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_abradb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_spellbookdb( char* split[], size_t columns, size_t current );
static bool mob_readdb_mobavail( char* str[], size_t columns, size_t current );
static bool skill_parse_row_requiredb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_castdb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_castnodexdb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_unitdb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_copyabledb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_nonearnpcrangedb( char* split[], size_t columns, size_t current );
static bool skill_parse_row_skilldb( char* split[], size_t columns, size_t current );
static bool quest_read_db( char* split[], size_t columns, size_t current );
static bool instance_readdb_sub( char* str[], size_t columns, size_t current );
static bool itemdb_read_itemavail( char* str[], size_t columns, size_t current );
static bool itemdb_read_buyingstore( char* fields[], size_t columns, size_t current );
static bool itemdb_read_flag( char* fields[], size_t columns, size_t current );
static bool itemdb_read_itemdelay( char* str[], size_t columns, size_t current );
static bool itemdb_read_stack( char* fields[], size_t columns, size_t current );
static bool itemdb_read_nouse( char* fields[], size_t columns, size_t current );
static bool itemdb_read_itemtrade( char* fields[], size_t columns, size_t current );
static bool itemdb_read_db(const char *file);
static bool itemdb_read_randomopt(const char* file);
static bool itemdb_read_randomopt_group(char *str[], int columns, int current);
static bool itemdb_read_randomopt_group( char* str[], size_t columns, size_t current );
static bool itemdb_randomopt_group_yaml(void);
static bool pc_readdb_levelpenalty(char* fields[], int columns, int current);
static bool pc_readdb_levelpenalty( char* fields[], size_t columns, size_t current );
static bool pc_levelpenalty_yaml();
static bool mob_parse_row_chatdb(char* fields[], int columns, int current);
static bool mob_parse_row_chatdb( char* fields[], size_t columns, size_t current );
static bool read_homunculus_expdb(const char* file);
static bool mob_readdb_group(char* str[], int columns, int current);
static bool mob_readdb_group( char* str[], size_t columns, size_t current );
static bool mob_readdb_group_yaml(void);
static bool skill_parse_row_createarrowdb(char* fields[], int columns, int current);
static bool skill_parse_row_createarrowdb( char* fields[], size_t columns, size_t current );
static bool pc_read_statsdb(const char* file);
static bool guild_read_castledb(char* str[], int columns, int current);
static bool exp_guild_parse_row(char* split[], int column, int current);
static bool itemdb_read_group(char* fields[], int columns, int current);
static bool guild_read_castledb( char* str[], size_t columns, size_t current );
static bool exp_guild_parse_row( char* split[], size_t columns, size_t current );
static bool itemdb_read_group( char* fields[], size_t columns, size_t current );
static bool itemdb_read_group_yaml(void);
static bool mob_readdb_itemratio(char* fields[], int columns, int current);
static bool mob_readdb_itemratio( char* fields[], size_t columns, size_t current );
static bool status_readdb_attrfix(const char* file);
static bool read_constdb(char* fields[], int columns, int current);
static bool mob_readdb_race2(char *fields[], int columns, int current);
static bool mob_readdb_drop(char *str[], int columns, int current);
static bool mob_readdb_sub(char *fields[], int columns, int current);
static bool pc_readdb_job2(char *fields[], int columns, int current);
static bool pc_readdb_job_param(char *fields[], int columns, int current);
static bool pc_readdb_job_exp(char *fields[], int columns, int current);
static bool pc_readdb_job_exp_sub(char *fields[], int columns, int current);
static bool pc_readdb_job_basehpsp(char *fields[], int columns, int current);
static bool pc_readdb_job1(char *fields[], int columns, int current);
static bool read_elemental_skilldb(char* str[], int columns, int current);
static bool read_elementaldb(char* str[], int columns, int current);
static bool mercenary_read_skilldb(char* str[], int columns, int current);
static bool mercenary_readdb(char* str[], int columns, int current);
static bool pc_readdb_skilltree(char* str[], int columns, int current);
static bool read_constdb( char* fields[], size_t columns, size_t current );
static bool mob_readdb_race2( char* fields[], size_t columns, size_t current );
static bool mob_readdb_drop( char* str[], size_t columns, size_t current );
static bool mob_readdb_sub( char* fields[], size_t columns, size_t current );
static bool pc_readdb_job2( char* fields[], size_t columns, size_t current );
static bool pc_readdb_job_param( char* fields[], size_t columns, size_t current );
static bool pc_readdb_job_exp( char* fields[], size_t columns, size_t current );
static bool pc_readdb_job_exp_sub( char* fields[], size_t columns, size_t current );
static bool pc_readdb_job_basehpsp( char* fields[], size_t columns, size_t current );
static bool pc_readdb_job1( char* fields[], size_t columns, size_t current );
static bool read_elemental_skilldb( char* str[], size_t columns, size_t current );
static bool read_elementaldb( char* str[], size_t columns, size_t current );
static bool mercenary_read_skilldb( char* str[], size_t columns, size_t current );
static bool mercenary_readdb( char* str[], size_t columns, size_t current );
static bool pc_readdb_skilltree( char* str[], size_t columns, size_t current );
static bool pc_readdb_skilltree_yaml(void);
static bool itemdb_read_combos(const char* file);
static bool cashshop_parse_dbrow( char* fields[], int columns, int current );
static bool read_homunculus_skilldb(char* split[], int columns, int current);
static bool read_homunculusdb(char* str[], int columns, int current);
static bool cashshop_parse_dbrow( char* fields[], size_t columns, size_t current );
static bool read_homunculus_skilldb( char* split[], size_t columns, size_t current );
static bool read_homunculusdb( char* str[], size_t columns, size_t current );
#endif /* CSV2YAML_HPP */

View File

@ -593,7 +593,7 @@ void ItemDatabase::loadingFinished() {
ItemDatabase item_db;
static bool parse_mob_constants_txt(char *split[], int columns, int current) {
static bool parse_mob_constants_txt( char *split[], size_t columns, size_t current ){
uint16 mob_id = atoi(split[0]);
char *name = trim(split[1]);
@ -602,7 +602,7 @@ static bool parse_mob_constants_txt(char *split[], int columns, int current) {
return true;
}
static bool parse_skill_constants_txt(char *split[], int columns, int current) {
static bool parse_skill_constants_txt( char *split[], size_t columns, size_t current ){
uint16 skill_id = atoi(split[0]);
char *name = trim(split[16]);