From 7e72f0cee8867837be53cb2119b610b00e9bd587 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 18 Feb 2013 00:30:28 -0300 Subject: Improvements all over the place Committing on the behalf of mkbu95 who is unable to do it himself, he coded it all and sent me the diff. Thanks mkbu95! Signed-off-by: shennetsind --- src/map/itemdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/map/itemdb.c') diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 68baae1e1..79d303085 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -867,7 +867,7 @@ void itemdb_read_combos() { /* populate the children to refer to this combo */ for( v = 1; v < retcount; v++ ) { - struct item_data * it = NULL; + struct item_data * it; int index; it = itemdb_exists(items[v]); -- cgit v1.2.3-70-g09d2 From 90f117f6b071c9c12bb8b521b6de46301639e75c Mon Sep 17 00:00:00 2001 From: shennetsind Date: Wed, 27 Mar 2013 13:22:55 -0300 Subject: Introducing Hercules' Map Zone Database Click the link for full info~! http://hercules.ws/board/topic/302-introducing-hercules-map-zone-database/ Signed-off-by: shennetsind --- conf/mapflag/restricted.txt | 126 ---------------- conf/mapflag/zone.txt | 122 ++++++++++++++++ conf/messages.conf | 2 +- db/const.txt | 2 +- db/pre-re/item_noequip.txt | 60 -------- db/pre-re/map_zone_db.txt | 239 ++++++++++++++++++++++++++++++ db/pre-re/skill_nocast_db.txt | 154 -------------------- db/re/item_noequip.txt | 60 -------- db/re/map_zone_db.txt | 239 ++++++++++++++++++++++++++++++ db/re/skill_nocast_db.txt | 154 -------------------- doc/script_commands.txt | Bin 591942 -> 592070 bytes npc/scripts_mapflags.conf | 6 +- src/map/atcommand.c | 32 ++-- src/map/clif.h | 4 + src/map/itemdb.c | 22 --- src/map/itemdb.h | 3 +- src/map/map.c | 331 +++++++++++++++++++++++++++++++++++++++++- src/map/map.h | 33 ++++- src/map/mob.c | 3 +- src/map/npc.c | 66 +++++---- src/map/npc.h | 1 + src/map/pc.c | 23 ++- src/map/script.c | 56 +++---- src/map/skill.c | 38 ++--- src/map/skill.h | 2 - src/map/status.c | 47 +++--- 26 files changed, 1085 insertions(+), 740 deletions(-) delete mode 100644 conf/mapflag/restricted.txt create mode 100644 conf/mapflag/zone.txt delete mode 100644 db/pre-re/item_noequip.txt create mode 100644 db/pre-re/map_zone_db.txt delete mode 100644 db/pre-re/skill_nocast_db.txt delete mode 100644 db/re/item_noequip.txt create mode 100644 db/re/map_zone_db.txt delete mode 100644 db/re/skill_nocast_db.txt (limited to 'src/map/itemdb.c') diff --git a/conf/mapflag/restricted.txt b/conf/mapflag/restricted.txt deleted file mode 100644 index 9c2a44bd8..000000000 --- a/conf/mapflag/restricted.txt +++ /dev/null @@ -1,126 +0,0 @@ -//===== Hercules Script ======================================= -//= Mapflag: Restricted. -//===== By: ================================================== -//= Komurka -//===== Current Version: ===================================== -//= 1.3 -//===== Description: ========================================= -//= Disables items configured in item_noequip.txt -//= and skills configured in skill_nocast_db.txt. -//===== Additional Comments: ================================= -//= 1.1 - Added WoE:SE Map restrictions. [L0ne_W0lf] -//= 1.2 - Added Endless Tower Restrictions. (bugreport:4707) [L0ne_W0lf] -//= 1.3 - Added Orc's Memory, Nidhoggur's Nest and towns restrictions. [Daegaladh] -//============================================================ - -//Aldebaran Turbo Track -alde_tt02 mapflag restricted 1 -turbo_n_1 mapflag restricted 1 -turbo_n_4 mapflag restricted 1 -turbo_n_8 mapflag restricted 1 -turbo_n_16 mapflag restricted 1 -turbo_e_4 mapflag restricted 1 -turbo_e_8 mapflag restricted 1 -turbo_e_16 mapflag restricted 1 - -//Jail -sec_pri mapflag restricted 2 - -//Izlude Battle Arena -force_1-1 mapflag restricted 3 -force_2-1 mapflag restricted 3 -force_3-1 mapflag restricted 3 -force_4-1 mapflag restricted 3 -force_5-1 mapflag restricted 3 -force_1-2 mapflag restricted 3 -force_1-3 mapflag restricted 3 -prt_are_in mapflag restricted 3 - -//WoE:SE Maps -schg_cas01 mapflag restricted 4 -schg_cas02 mapflag restricted 4 -schg_cas03 mapflag restricted 4 -schg_cas04 mapflag restricted 4 -schg_cas05 mapflag restricted 4 -arug_cas01 mapflag restricted 4 -arug_cas02 mapflag restricted 4 -arug_cas03 mapflag restricted 4 -arug_cas04 mapflag restricted 4 -arug_cas05 mapflag restricted 4 - -//Sealed Shrine ================== -1@cata mapflag restricted 5 -2@cata mapflag restricted 5 - -//Endless Tower ================== -1@tower mapflag restricted 6 -2@tower mapflag restricted 6 -3@tower mapflag restricted 6 -4@tower mapflag restricted 6 -5@tower mapflag restricted 6 -6@tower mapflag restricted 6 - -//Orc's Memory =================== -1@orcs mapflag restricted 6 -2@orcs mapflag restricted 6 - -// Nidhoggr's Instance =========== -1@nyd mapflag restricted 6 -2@nyd mapflag restricted 6 - -// Misty Forest Labyrinth =========== -1@mist mapflag restricted 6 - -// Octopus Cave =========== -1@cash mapflag restricted 6 - -// Drain =========== -1@pump mapflag restricted 6 -2@pump mapflag restricted 6 - -// Somatology Laboratory =========== -1@lhz mapflag restricted 6 - -// Bangungot Hospital F2 =========== -1@ma_h mapflag restricted 6 - -// Buwaya Cave =========== -1@ma_c mapflag restricted 6 - -// Bakonawa Hideout =========== -1@ma_b mapflag restricted 6 - -// Inside Eclage =========== -1@ecl mapflag restricted 6 - -//Towns -alberta mapflag restricted 7 -aldebaran mapflag restricted 7 -amatsu mapflag restricted 7 -ayothaya mapflag restricted 7 -brasilis mapflag restricted 7 -comodo mapflag restricted 7 -einbroch mapflag restricted 7 -einbech mapflag restricted 7 -geffen mapflag restricted 7 -gonryun mapflag restricted 7 -izlude mapflag restricted 7 -jawaii mapflag restricted 7 -hugel mapflag restricted 7 -lighthalzen mapflag restricted 7 -louyang mapflag restricted 7 -manuk mapflag restricted 7 -mid_camp mapflag restricted 7 -moc_ruins mapflag restricted 7 -morocc mapflag restricted 7 -moscovia mapflag restricted 7 -niflheim mapflag restricted 7 -prontera mapflag restricted 7 -payon mapflag restricted 7 -pay_arche mapflag restricted 7 -rachel mapflag restricted 7 -splendide mapflag restricted 7 -umbala mapflag restricted 7 -veins mapflag restricted 7 -xmas mapflag restricted 7 -yuno mapflag restricted 7 diff --git a/conf/mapflag/zone.txt b/conf/mapflag/zone.txt new file mode 100644 index 000000000..2f0938c9c --- /dev/null +++ b/conf/mapflag/zone.txt @@ -0,0 +1,122 @@ +//===== Hercules============================================== +//= Mapflag: Zone. +//===== By: ================================================== +//= Ind/Hercules +//===== Current Version: ===================================== +//= 1.0 +//===== Description: ========================================= +//= Flags maps as part of zones defined in map_zone_db.txt +//===== Additional Comments: ================================= +//============================================================ + +//Aldebaran Turbo Track +alde_tt02 mapflag zone Aldebaran Turbo Track +turbo_n_1 mapflag zone Aldebaran Turbo Track +turbo_n_4 mapflag zone Aldebaran Turbo Track +turbo_n_8 mapflag zone Aldebaran Turbo Track +turbo_n_16 mapflag zone Aldebaran Turbo Track +turbo_e_4 mapflag zone Aldebaran Turbo Track +turbo_e_8 mapflag zone Aldebaran Turbo Track +turbo_e_16 mapflag zone Aldebaran Turbo Track + +//Jail +sec_pri mapflag zone Jail + +//Izlude Battle Arena +force_1-1 mapflag zone Izlude Battle Arena +force_2-1 mapflag zone Izlude Battle Arena +force_3-1 mapflag zone Izlude Battle Arena +force_4-1 mapflag zone Izlude Battle Arena +force_5-1 mapflag zone Izlude Battle Arena +force_1-2 mapflag zone Izlude Battle Arena +force_1-3 mapflag zone Izlude Battle Arena +prt_are_in mapflag zone Izlude Battle Arena + +//WoE:SE Maps +schg_cas01 mapflag zone GvG2 +schg_cas02 mapflag zone GvG2 +schg_cas03 mapflag zone GvG2 +schg_cas04 mapflag zone GvG2 +schg_cas05 mapflag zone GvG2 +arug_cas01 mapflag zone GvG2 +arug_cas02 mapflag zone GvG2 +arug_cas03 mapflag zone GvG2 +arug_cas04 mapflag zone GvG2 +arug_cas05 mapflag zone GvG2 + +//Sealed Shrine ================== +1@cata mapflag zone Sealed Shrine +2@cata mapflag zone Sealed Shrine + +//Endless Tower ================== +1@tower mapflag zone Memorial Dungeon +2@tower mapflag zone Memorial Dungeon +3@tower mapflag zone Memorial Dungeon +4@tower mapflag zone Memorial Dungeon +5@tower mapflag zone Memorial Dungeon +6@tower mapflag zone Memorial Dungeon + +//Orc's Memory =================== +1@orcs mapflag zone Memorial Dungeon +2@orcs mapflag zone Memorial Dungeon + +// Nidhoggr's Instance =========== +1@nyd mapflag zone Memorial Dungeon +2@nyd mapflag zone Memorial Dungeon + +// Misty Forest Labyrinth =========== +1@mist mapflag zone Memorial Dungeon + +// Octopus Cave =========== +1@cash mapflag zone Memorial Dungeon + +// Drain =========== +1@pump mapflag zone Memorial Dungeon +2@pump mapflag zone Memorial Dungeon + +// Somatology Laboratory =========== +1@lhz mapflag zone Memorial Dungeon + +// Bangungot Hospital F2 =========== +1@ma_h mapflag zone Memorial Dungeon + +// Buwaya Cave =========== +1@ma_c mapflag zone Memorial Dungeon + +// Bakonawa Hideout =========== +1@ma_b mapflag zone Memorial Dungeon + +// Inside Eclage =========== +1@ecl mapflag zone Memorial Dungeon + +//Towns +alberta mapflag zone Towns +aldebaran mapflag zone Towns +amatsu mapflag zone Towns +ayothaya mapflag zone Towns +brasilis mapflag zone Towns +comodo mapflag zone Towns +einbroch mapflag zone Towns +einbech mapflag zone Towns +geffen mapflag zone Towns +gonryun mapflag zone Towns +izlude mapflag zone Towns +jawaii mapflag zone Towns +hugel mapflag zone Towns +lighthalzen mapflag zone Towns +louyang mapflag zone Towns +manuk mapflag zone Towns +mid_camp mapflag zone Towns +moc_ruins mapflag zone Towns +morocc mapflag zone Towns +moscovia mapflag zone Towns +niflheim mapflag zone Towns +prontera mapflag zone Towns +payon mapflag zone Towns +pay_arche mapflag zone Towns +rachel mapflag zone Towns +splendide mapflag zone Towns +umbala mapflag zone Towns +veins mapflag zone Towns +xmas mapflag zone Towns +yuno mapflag zone Towns diff --git a/conf/messages.conf b/conf/messages.conf index 9b1af268a..6025ecd81 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -835,7 +835,7 @@ // @mapinfo 1038: Please enter at least one valid list number (usage: @mapinfo <0-3> ). 1039: ------ Map Info ------ -1040: Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d +1040: Map: %s (Zone:%s) | Players: %d | NPCs: %d | Chats: %d | Vendings: %d 1041: ------ Map Flags ------ 1042: Town Map 1043: Autotrade Enabled diff --git a/db/const.txt b/db/const.txt index b4fa39366..d3d5991ab 100644 --- a/db/const.txt +++ b/db/const.txt @@ -348,7 +348,7 @@ mf_nomvploot 32 mf_noreturn 33 mf_nowarpto 34 mf_nightmaredrop 35 -mf_restricted 36 +mf_zone 36 mf_nocommand 37 mf_nodrop 38 mf_jexp 39 diff --git a/db/pre-re/item_noequip.txt b/db/pre-re/item_noequip.txt deleted file mode 100644 index 6e8b65309..000000000 --- a/db/pre-re/item_noequip.txt +++ /dev/null @@ -1,60 +0,0 @@ -// The equipment/items/cards restriction file -// here you define which items may not be used at PvP / GvG -// format: , -// mode -// 1 - restricted in normal maps -// 2 - restricted in PVP -// 4 - restricted in GVG -// 8 - restricted in Battlegrounds -// Restricted zones - they're configured by 'restricted ' mapflag -// 32 - restricted in zone 1 -// 64 - restricted in zone 2 -// 128 - restricted in zone 3 -// 256 - restricted in zone 4 -// 512 - restricted in zone 5 -// 1024 - restricted in zone 6 -// 2048 - restricted in zone 7 - -//Examples: -//1201,1 you can't use KNIFE(ID 1201) on normal maps -//608,4 you can't use Yggdrasil Seed(ID 608) on both GvG and WoE Castles -//4174,6 Forbid Deviling Card in every PVP or GVG map, and during woes. -//501,32 you can't use Red Potion on map marked as 'restricted zone 1' -//502,64 you can't use Orange Potion on map marked as 'restricted zone 2' -//503,128 you can't use Yellow Potion on map marked as 'restricted zone 3' -// you can even mix modes -//519,322 (256+64+2) you can't use Milk on PVP, and maps marked as 'restricted zone 2' and 'restricted zone 4' - -//PVP -14529,2 //Greed Scroll - -//GVG -12218,4 //LV5 Assumptio Scroll -14529,4 //Greed Scroll -14590,4 //Party Assumptio 5 Scroll - -//BATTLEGROUND -12218,8 //LV5 Assumptio Scroll -14590,8 //Party Assumptio 5 Scroll - - -//Zone 1 - Aldebaran Turbo Track -601,32 //Fly Wing -605,32 //Anodyne -506,32 //Green Potion -525,32 //Panacea - -//Zone 2 - Jail -601,64 //Fly Wing - not really needed here but ... -602,64 //Butterfly Wing - also not needed -12212,64 //Giant Fly Wing -14582,64 -14583,64 -14584,64 -14585,64 - -//Zone 3 - Izlude Battle Arena -601,128 //Fly Wing - -//Zone 7 - Towns -14529,2048 //Greed Scroll diff --git a/db/pre-re/map_zone_db.txt b/db/pre-re/map_zone_db.txt new file mode 100644 index 000000000..996726575 --- /dev/null +++ b/db/pre-re/map_zone_db.txt @@ -0,0 +1,239 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//==================================================== +//= Hercules Map Zone Database [Ind/Hercules] +//== +//= A unlimited number of zones may be created, a zone +//= may be used to create a set of disabled items, disabled skills +//= and mapflags to be used by as many maps as one chooses, +//= maps can be linked to a specific zone through the zone mapflag +//= 'mapflagzone' +zones: ( +{ + /* Normal zone is applied to all maps that are not pkable (where players cant fight each other) */ + /* However, it wont be applied to maps with its own zones (specified thru mapflag) */ + name: "Normal" /* changing this name requires MAP_ZONE_NORMAL_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + WM_LULLABY_DEEPSLEEP: true + WM_SIRCLEOFNATURE: true + WM_SATURDAY_NIGHT_FEVER: true + SO_ARRULLO: true + CG_HERMODE: true + } + + disabled_items: { + + } + mapflags: ( ) +}, +{ + /* PvP zone is applied to all maps with a pvp mapflag */ + name: "PvP" /* changing this name requires MAP_ZONE_PVP_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + BS_GREED: true + CG_HERMODE: true + } + + disabled_items: { + Greed_Scroll: true + } +}, +{ + /* GvG zone is applied to all maps with a pvp mapflag */ + name: "GvG" /* changing this name requires MAP_ZONE_GVG_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + AL_TELEPORT: true + AL_WARP: true + WZ_ICEWALL: true + TF_BACKSLIDING: true + RG_INTIMIDATE: true + WE_CALLPARTNER: true + HP_ASSUMPTIO: true + HP_BASILICA: true + CG_MOONLIT: true + WE_CALLPARENT: true + WE_CALLBABY: true + CR_CULTIVATION: true + NJ_KIRIKAGE: true + CASH_ASSUMPTIO: true + BS_GREED: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } + + disabled_items: { + Assumptio_5_Scroll: true + Greed_Scroll: true + Pty_Assumptio_Scroll: true + } +}, +{ + /* Battlegrounds zone is applied to all maps with a battlegrounds mapflag */ + name: "Battlegrounds" /* changing this name requires MAP_ZONE_BG_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + AL_TELEPORT: true + AL_WARP: true + WZ_ICEWALL: true + TF_BACKSLIDING: true + RG_INTIMIDATE: true + MO_BODYRELOCATION: true + WE_CALLPARTNER: true + HP_ASSUMPTIO: true + HP_BASILICA: true + CG_MOONLIT: true + WE_CALLPARENT: true + WE_CALLBABY: true + CR_CULTIVATION: true + TK_RUN: true + TK_HIGHJUMP: true + SG_FEEL: true + SG_SUN_WARM: true + SG_MOON_WARM: true + SG_STAR_WARM: true + SG_SUN_COMFORT: true + SG_MOON_COMFORT: true + SG_STAR_COMFORT: true + SG_HATE: true + SG_SUN_ANGER: true + SG_MOON_ANGER: true + SG_STAR_ANGER: true + SG_SUN_BLESS: true + SG_MOON_BLESS: true + SG_STAR_BLESS: true + NJ_KIRIKAGE: true + CASH_ASSUMPTIO: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } + disabled_items: { + Assumptio_5_Scroll: true + Pty_Assumptio_Scroll: true + } +}, +{ + name: "Aldebaran Turbo Track" + + disabled_skills: { + SM_ENDURE: true + AL_TELEPORT: true + AL_WARP: true + AL_CURE: true + TF_HIDING: true + WZ_ICEWALL: true + AS_CLOAKING: true + RG_INTIMIDATE: true + MO_BODYRELOCATION: true + LK_CONCENTRATION: true + LK_BERSERK: true + HP_BASILICA: true + WS_CARTBOOST: true + ST_CHASEWALK: true + CG_MOONLIT: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + GN_CARTBOOST: true + } + + disabled_items: { + Wing_Of_Fly: true + Anodyne: true + Green_Potion: true + Panacea: true + } +}, +{ + name: "Jail" + + disabled_skills: { + TK_JUMPKICK: true + TK_HIGHJUMP: true + } + + disabled_items: { + Wing_Of_Fly: true + Wing_Of_Butterfly: true + Giant_Fly_Wing: true + WOB_Rune: true + WOB_Schwaltz: true + WOB_Rachel: true + WOB_Local: true + } +}, +{ + name: "Izlude Battle Arena" + + disabled_skills: { + RG_INTIMIDATE: true + AL_TELEPORT: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } + + disabled_items: { + Wing_Of_Fly: true + } +}, +{ + name: "GvG2" + inherit: ( "GvG" ) /* will import all gvg has */ + + disabled_skills: { + TK_HIGHJUMP: true + SA_ABRACADABRA: true + } +}, +{ + name: "Sealed Shrine" + + disabled_skills: { + MG_SAFETYWALL: true + AL_TELEPORT: true + RG_INTIMIDATE: true + HP_ASSUMPTIO: true + CASH_ASSUMPTIO: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } +}, +{ + name: "Memorial Dungeon" /* ETower, Orc's Memory, Nidhoggur's Nest, etc */ + + disabled_skills: { + AL_TELEPORT: true + WZ_ICEWALL: true + RG_INTIMIDATE: true + PF_SPIDERWEB: true + NPC_EXPULSION: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } +}, +{ + name: "Towns" + + disabled_skills: { + AM_CANNIBALIZE: true + AM_SPHEREMINE: true + CR_CULTIVATION: true + BS_GREED: true + SC_MANHOLE: true + WM_POEMOFNETHERWORLD: true + GN_WALLOFTHORN: true + } + + disabled_items: { + Greed_Scroll: true + } +} +) \ No newline at end of file diff --git a/db/pre-re/skill_nocast_db.txt b/db/pre-re/skill_nocast_db.txt deleted file mode 100644 index 5e12477a9..000000000 --- a/db/pre-re/skill_nocast_db.txt +++ /dev/null @@ -1,154 +0,0 @@ -// Forbidden Skills Database -// -// Structure of Database: -// SkillID,Flag -// -// Legend for 'Flag' field (bitmask): -// 1 = Cannot be used in normal maps -// 2 = Cannot be used in PvP maps (use this instead of 1 for PK-mode servers) -// 4 = Cannot be used in GvG maps -// 8 = Cannot be used in Battleground maps -// 16 = Cannot be cloned (clones will not copy this skill) -// Restricted zones - they're configured by 'restricted ' mapflag -// 32 = Cannot be used in zone 1 maps -// 64 = Cannot be used in zone 2 maps -// 128 = Cannot be used in zone 3 maps -// 256 = Cannot be used in zone 4 maps -// 512 = Cannot be used in zone 5 maps -// 1024 = Cannot be used in zone 6 maps -// 2048 = Cannot be used in zone 7 maps -// -// Example: -// 8,6 = Endure cannot be used in PvP and GvG maps (2+4) - -//Normal -2422,1 //WM_LULLABY_DEEPSLEEP -2423,1 //WM_SIRCLEOFNATURE -2430,1 //WM_SATURDAY_NIGHT_FEVER -2455,1 //SO_ARRULLO - -//PVP -1013,2 //BS_GREED - -//GVG -26,4 //AL_TELEPORT -27,4 //AL_WARP -87,4 //WZ_ICEWALL -150,4 //TF_BACKSLIDING -219,4 //RG_INTIMIDATE -336,4 //WE_CALLPARTNER -361,4 //HP_ASSUMPTIO -362,4 //HP_BASILICA -395,4 //CG_MOONLIT -409,4 //WE_CALLPARENT -410,4 //WE_CALLBABY -491,4 //CR_CULTIVATION -530,4 //NJ_KIRIKAGE -691,4 //CASH_ASSUMPTIO -1013,4 //BS_GREED -2284,4 //SC_FATALMENACE -2300,4 //SC_DIMENSIONDOOR - -//BATTLEGROUND -26,8 //AL_TELEPORT -27,8 //AL_WARP -87,8 //WZ_ICEWALL -150,8 //TF_BACKSLIDING -219,8 //RG_INTIMIDATE -264,8 //MO_BODYRELOCATION -336,8 //WE_CALLPARTNER -361,8 //HP_ASSUMPTIO -362,8 //HP_BASILICA -395,8 //CG_MOONLIT -409,8 //WE_CALLPARENT -410,8 //WE_CALLBABY -491,8 //CR_CULTIVATION -411,8 //TK_RUN -426,8 //TK_HIGHJUMP -427,8 //SG_FEEL -428,8 //SG_SUN_WARM -429,8 //SG_MOON_WARM -430,8 //SG_STAR_WARM -431,8 //SG_SUN_COMFORT -432,8 //SG_MOON_COMFORT -433,8 //SG_STAR_COMFORT -434,8 //SG_HATE -435,8 //SG_SUN_ANGER -436,8 //SG_MOON_ANGER -437,8 //SG_STAR_ANGER -438,8 //SG_SUN_BLESS -439,8 //SG_MOON_BLESS -440,8 //SG_STAR_BLESS -530,8 //NJ_KIRIKAGE -691,8 //CASH_ASSUMPITO -2284,8 //SC_FATALMENACE -2300,8 //SC_DIMENSIONDOOR - -//mixed -488,3 //CG_HERMODE -3013,3 //KO_KYOUGAKU - -//Clone Forbidden/pointless skills -77,16 //PR_TURNUNDEAD -79,16 //PR_MAGNUS - -//Zone 1 - Aldebaran Turbo Track -8,32 //SM_ENDURE -26,32 //AL_TELEPORT -27,32 //AL_WARP -35,32 //AL_CURE -51,32 //TF_HIDING -87,32 //WZ_ICEWALL -135,32 //AS_CLOAKING -219,32 //RG_INTIMIDATE -264,32 //MO_BODYRELOCATION -357,32 //LK_CONCENTRATION -359,32 //LK_BERSERK -362,32 //HP_BASILICA -387,32 //WS_CARTBOOST -389,32 //ST_CHASEWALK -395,32 //CG_MOONLIT -2284,32 //SC_FATALMENACE -2300,32 //SC_DIMENSIONDOOR -2478,32 //GN_CARTBOOST - -//Zone 2 - Jail -421,64 //TK_JUMPKICK -426,64 //TK_HIGHJUMP - -//Zone 3 - Izlude Battle Arena -219,128 //RG_INTIMIDATE -26,128 //AL_TELEPORT -2284,128 //SC_FATALMENACE -2300,128 //SC_DIMENSIONDOOR - -//Zone 4 - WoE:SE -426,256 //TK_HIGHJUMP -290,256 //SA_ABRACADABRA - -//Zone 5 - Sealed Shrine -12,512 //MG_SAFETYWALL -26,512 //AL_TELEPORT -219,512 //RG_INTIMIDATE -361,512 //HP_ASSUMPTIO -691,512 //CASH_ASSUMPTIO -2284,512 //SC_FATALMENACE -2300,512 //SC_DIMENSIONDOOR - -//Zone 6 - Endless Tower, Orc's Memory, Nidhoggur's Nest -26,1024 //AL_TELEPORT -87,1024 //WZ_ICEWALL -219,1024 //RG_INTIMIDATE -405,1024 //PF_SPIDERWEB -674,1024 //NPC_EXPULSION -2284,1024 //SC_FATALMENACE -2300,1024 //SC_DIMENSIONDOOR - -//Zone 7 - Towns -232,2048 //AM_CANNIBALIZE -233,2048 //AM_SPHEREMINE -491,2048 //CR_CULTIVATION -1013,2048 //BS_GREED -2299,2048 //SC_MANHOLE -2419,2048 //WM_POEMOFNETHERWORLD -2482,2048 //GN_WALLOFTHORN diff --git a/db/re/item_noequip.txt b/db/re/item_noequip.txt deleted file mode 100644 index 6e8b65309..000000000 --- a/db/re/item_noequip.txt +++ /dev/null @@ -1,60 +0,0 @@ -// The equipment/items/cards restriction file -// here you define which items may not be used at PvP / GvG -// format: , -// mode -// 1 - restricted in normal maps -// 2 - restricted in PVP -// 4 - restricted in GVG -// 8 - restricted in Battlegrounds -// Restricted zones - they're configured by 'restricted ' mapflag -// 32 - restricted in zone 1 -// 64 - restricted in zone 2 -// 128 - restricted in zone 3 -// 256 - restricted in zone 4 -// 512 - restricted in zone 5 -// 1024 - restricted in zone 6 -// 2048 - restricted in zone 7 - -//Examples: -//1201,1 you can't use KNIFE(ID 1201) on normal maps -//608,4 you can't use Yggdrasil Seed(ID 608) on both GvG and WoE Castles -//4174,6 Forbid Deviling Card in every PVP or GVG map, and during woes. -//501,32 you can't use Red Potion on map marked as 'restricted zone 1' -//502,64 you can't use Orange Potion on map marked as 'restricted zone 2' -//503,128 you can't use Yellow Potion on map marked as 'restricted zone 3' -// you can even mix modes -//519,322 (256+64+2) you can't use Milk on PVP, and maps marked as 'restricted zone 2' and 'restricted zone 4' - -//PVP -14529,2 //Greed Scroll - -//GVG -12218,4 //LV5 Assumptio Scroll -14529,4 //Greed Scroll -14590,4 //Party Assumptio 5 Scroll - -//BATTLEGROUND -12218,8 //LV5 Assumptio Scroll -14590,8 //Party Assumptio 5 Scroll - - -//Zone 1 - Aldebaran Turbo Track -601,32 //Fly Wing -605,32 //Anodyne -506,32 //Green Potion -525,32 //Panacea - -//Zone 2 - Jail -601,64 //Fly Wing - not really needed here but ... -602,64 //Butterfly Wing - also not needed -12212,64 //Giant Fly Wing -14582,64 -14583,64 -14584,64 -14585,64 - -//Zone 3 - Izlude Battle Arena -601,128 //Fly Wing - -//Zone 7 - Towns -14529,2048 //Greed Scroll diff --git a/db/re/map_zone_db.txt b/db/re/map_zone_db.txt new file mode 100644 index 000000000..996726575 --- /dev/null +++ b/db/re/map_zone_db.txt @@ -0,0 +1,239 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//==================================================== +//= Hercules Map Zone Database [Ind/Hercules] +//== +//= A unlimited number of zones may be created, a zone +//= may be used to create a set of disabled items, disabled skills +//= and mapflags to be used by as many maps as one chooses, +//= maps can be linked to a specific zone through the zone mapflag +//= 'mapflagzone' +zones: ( +{ + /* Normal zone is applied to all maps that are not pkable (where players cant fight each other) */ + /* However, it wont be applied to maps with its own zones (specified thru mapflag) */ + name: "Normal" /* changing this name requires MAP_ZONE_NORMAL_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + WM_LULLABY_DEEPSLEEP: true + WM_SIRCLEOFNATURE: true + WM_SATURDAY_NIGHT_FEVER: true + SO_ARRULLO: true + CG_HERMODE: true + } + + disabled_items: { + + } + mapflags: ( ) +}, +{ + /* PvP zone is applied to all maps with a pvp mapflag */ + name: "PvP" /* changing this name requires MAP_ZONE_PVP_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + BS_GREED: true + CG_HERMODE: true + } + + disabled_items: { + Greed_Scroll: true + } +}, +{ + /* GvG zone is applied to all maps with a pvp mapflag */ + name: "GvG" /* changing this name requires MAP_ZONE_GVG_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + AL_TELEPORT: true + AL_WARP: true + WZ_ICEWALL: true + TF_BACKSLIDING: true + RG_INTIMIDATE: true + WE_CALLPARTNER: true + HP_ASSUMPTIO: true + HP_BASILICA: true + CG_MOONLIT: true + WE_CALLPARENT: true + WE_CALLBABY: true + CR_CULTIVATION: true + NJ_KIRIKAGE: true + CASH_ASSUMPTIO: true + BS_GREED: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } + + disabled_items: { + Assumptio_5_Scroll: true + Greed_Scroll: true + Pty_Assumptio_Scroll: true + } +}, +{ + /* Battlegrounds zone is applied to all maps with a battlegrounds mapflag */ + name: "Battlegrounds" /* changing this name requires MAP_ZONE_BG_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + AL_TELEPORT: true + AL_WARP: true + WZ_ICEWALL: true + TF_BACKSLIDING: true + RG_INTIMIDATE: true + MO_BODYRELOCATION: true + WE_CALLPARTNER: true + HP_ASSUMPTIO: true + HP_BASILICA: true + CG_MOONLIT: true + WE_CALLPARENT: true + WE_CALLBABY: true + CR_CULTIVATION: true + TK_RUN: true + TK_HIGHJUMP: true + SG_FEEL: true + SG_SUN_WARM: true + SG_MOON_WARM: true + SG_STAR_WARM: true + SG_SUN_COMFORT: true + SG_MOON_COMFORT: true + SG_STAR_COMFORT: true + SG_HATE: true + SG_SUN_ANGER: true + SG_MOON_ANGER: true + SG_STAR_ANGER: true + SG_SUN_BLESS: true + SG_MOON_BLESS: true + SG_STAR_BLESS: true + NJ_KIRIKAGE: true + CASH_ASSUMPTIO: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } + disabled_items: { + Assumptio_5_Scroll: true + Pty_Assumptio_Scroll: true + } +}, +{ + name: "Aldebaran Turbo Track" + + disabled_skills: { + SM_ENDURE: true + AL_TELEPORT: true + AL_WARP: true + AL_CURE: true + TF_HIDING: true + WZ_ICEWALL: true + AS_CLOAKING: true + RG_INTIMIDATE: true + MO_BODYRELOCATION: true + LK_CONCENTRATION: true + LK_BERSERK: true + HP_BASILICA: true + WS_CARTBOOST: true + ST_CHASEWALK: true + CG_MOONLIT: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + GN_CARTBOOST: true + } + + disabled_items: { + Wing_Of_Fly: true + Anodyne: true + Green_Potion: true + Panacea: true + } +}, +{ + name: "Jail" + + disabled_skills: { + TK_JUMPKICK: true + TK_HIGHJUMP: true + } + + disabled_items: { + Wing_Of_Fly: true + Wing_Of_Butterfly: true + Giant_Fly_Wing: true + WOB_Rune: true + WOB_Schwaltz: true + WOB_Rachel: true + WOB_Local: true + } +}, +{ + name: "Izlude Battle Arena" + + disabled_skills: { + RG_INTIMIDATE: true + AL_TELEPORT: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } + + disabled_items: { + Wing_Of_Fly: true + } +}, +{ + name: "GvG2" + inherit: ( "GvG" ) /* will import all gvg has */ + + disabled_skills: { + TK_HIGHJUMP: true + SA_ABRACADABRA: true + } +}, +{ + name: "Sealed Shrine" + + disabled_skills: { + MG_SAFETYWALL: true + AL_TELEPORT: true + RG_INTIMIDATE: true + HP_ASSUMPTIO: true + CASH_ASSUMPTIO: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } +}, +{ + name: "Memorial Dungeon" /* ETower, Orc's Memory, Nidhoggur's Nest, etc */ + + disabled_skills: { + AL_TELEPORT: true + WZ_ICEWALL: true + RG_INTIMIDATE: true + PF_SPIDERWEB: true + NPC_EXPULSION: true + SC_FATALMENACE: true + SC_DIMENSIONDOOR: true + } +}, +{ + name: "Towns" + + disabled_skills: { + AM_CANNIBALIZE: true + AM_SPHEREMINE: true + CR_CULTIVATION: true + BS_GREED: true + SC_MANHOLE: true + WM_POEMOFNETHERWORLD: true + GN_WALLOFTHORN: true + } + + disabled_items: { + Greed_Scroll: true + } +} +) \ No newline at end of file diff --git a/db/re/skill_nocast_db.txt b/db/re/skill_nocast_db.txt deleted file mode 100644 index 5e12477a9..000000000 --- a/db/re/skill_nocast_db.txt +++ /dev/null @@ -1,154 +0,0 @@ -// Forbidden Skills Database -// -// Structure of Database: -// SkillID,Flag -// -// Legend for 'Flag' field (bitmask): -// 1 = Cannot be used in normal maps -// 2 = Cannot be used in PvP maps (use this instead of 1 for PK-mode servers) -// 4 = Cannot be used in GvG maps -// 8 = Cannot be used in Battleground maps -// 16 = Cannot be cloned (clones will not copy this skill) -// Restricted zones - they're configured by 'restricted ' mapflag -// 32 = Cannot be used in zone 1 maps -// 64 = Cannot be used in zone 2 maps -// 128 = Cannot be used in zone 3 maps -// 256 = Cannot be used in zone 4 maps -// 512 = Cannot be used in zone 5 maps -// 1024 = Cannot be used in zone 6 maps -// 2048 = Cannot be used in zone 7 maps -// -// Example: -// 8,6 = Endure cannot be used in PvP and GvG maps (2+4) - -//Normal -2422,1 //WM_LULLABY_DEEPSLEEP -2423,1 //WM_SIRCLEOFNATURE -2430,1 //WM_SATURDAY_NIGHT_FEVER -2455,1 //SO_ARRULLO - -//PVP -1013,2 //BS_GREED - -//GVG -26,4 //AL_TELEPORT -27,4 //AL_WARP -87,4 //WZ_ICEWALL -150,4 //TF_BACKSLIDING -219,4 //RG_INTIMIDATE -336,4 //WE_CALLPARTNER -361,4 //HP_ASSUMPTIO -362,4 //HP_BASILICA -395,4 //CG_MOONLIT -409,4 //WE_CALLPARENT -410,4 //WE_CALLBABY -491,4 //CR_CULTIVATION -530,4 //NJ_KIRIKAGE -691,4 //CASH_ASSUMPTIO -1013,4 //BS_GREED -2284,4 //SC_FATALMENACE -2300,4 //SC_DIMENSIONDOOR - -//BATTLEGROUND -26,8 //AL_TELEPORT -27,8 //AL_WARP -87,8 //WZ_ICEWALL -150,8 //TF_BACKSLIDING -219,8 //RG_INTIMIDATE -264,8 //MO_BODYRELOCATION -336,8 //WE_CALLPARTNER -361,8 //HP_ASSUMPTIO -362,8 //HP_BASILICA -395,8 //CG_MOONLIT -409,8 //WE_CALLPARENT -410,8 //WE_CALLBABY -491,8 //CR_CULTIVATION -411,8 //TK_RUN -426,8 //TK_HIGHJUMP -427,8 //SG_FEEL -428,8 //SG_SUN_WARM -429,8 //SG_MOON_WARM -430,8 //SG_STAR_WARM -431,8 //SG_SUN_COMFORT -432,8 //SG_MOON_COMFORT -433,8 //SG_STAR_COMFORT -434,8 //SG_HATE -435,8 //SG_SUN_ANGER -436,8 //SG_MOON_ANGER -437,8 //SG_STAR_ANGER -438,8 //SG_SUN_BLESS -439,8 //SG_MOON_BLESS -440,8 //SG_STAR_BLESS -530,8 //NJ_KIRIKAGE -691,8 //CASH_ASSUMPITO -2284,8 //SC_FATALMENACE -2300,8 //SC_DIMENSIONDOOR - -//mixed -488,3 //CG_HERMODE -3013,3 //KO_KYOUGAKU - -//Clone Forbidden/pointless skills -77,16 //PR_TURNUNDEAD -79,16 //PR_MAGNUS - -//Zone 1 - Aldebaran Turbo Track -8,32 //SM_ENDURE -26,32 //AL_TELEPORT -27,32 //AL_WARP -35,32 //AL_CURE -51,32 //TF_HIDING -87,32 //WZ_ICEWALL -135,32 //AS_CLOAKING -219,32 //RG_INTIMIDATE -264,32 //MO_BODYRELOCATION -357,32 //LK_CONCENTRATION -359,32 //LK_BERSERK -362,32 //HP_BASILICA -387,32 //WS_CARTBOOST -389,32 //ST_CHASEWALK -395,32 //CG_MOONLIT -2284,32 //SC_FATALMENACE -2300,32 //SC_DIMENSIONDOOR -2478,32 //GN_CARTBOOST - -//Zone 2 - Jail -421,64 //TK_JUMPKICK -426,64 //TK_HIGHJUMP - -//Zone 3 - Izlude Battle Arena -219,128 //RG_INTIMIDATE -26,128 //AL_TELEPORT -2284,128 //SC_FATALMENACE -2300,128 //SC_DIMENSIONDOOR - -//Zone 4 - WoE:SE -426,256 //TK_HIGHJUMP -290,256 //SA_ABRACADABRA - -//Zone 5 - Sealed Shrine -12,512 //MG_SAFETYWALL -26,512 //AL_TELEPORT -219,512 //RG_INTIMIDATE -361,512 //HP_ASSUMPTIO -691,512 //CASH_ASSUMPTIO -2284,512 //SC_FATALMENACE -2300,512 //SC_DIMENSIONDOOR - -//Zone 6 - Endless Tower, Orc's Memory, Nidhoggur's Nest -26,1024 //AL_TELEPORT -87,1024 //WZ_ICEWALL -219,1024 //RG_INTIMIDATE -405,1024 //PF_SPIDERWEB -674,1024 //NPC_EXPULSION -2284,1024 //SC_FATALMENACE -2300,1024 //SC_DIMENSIONDOOR - -//Zone 7 - Towns -232,2048 //AM_CANNIBALIZE -233,2048 //AM_SPHEREMINE -491,2048 //CR_CULTIVATION -1013,2048 //BS_GREED -2299,2048 //SC_MANHOLE -2419,2048 //WM_POEMOFNETHERWORLD -2482,2048 //GN_WALLOFTHORN diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 7a622cdbc..d6279a4c6 100644 Binary files a/doc/script_commands.txt and b/doc/script_commands.txt differ diff --git a/npc/scripts_mapflags.conf b/npc/scripts_mapflags.conf index 429578f1a..78adeba20 100644 --- a/npc/scripts_mapflags.conf +++ b/npc/scripts_mapflags.conf @@ -22,10 +22,10 @@ npc: conf/mapflag/pvp.txt npc: conf/mapflag/pvp_noparty.txt npc: conf/mapflag/pvp_noguild.txt npc: conf/mapflag/night.txt -npc: conf/mapflag/restricted.txt +npc: conf/mapflag/zone.txt npc: conf/mapflag/battleground.txt npc: conf/mapflag/novending.txt npc: conf/mapflag/town.txt npc: conf/mapflag/reset.txt -//npc: conf/mapflag/skillmodifier.txt -//npc: conf/mapflag/skillduration.txt \ No newline at end of file +npc: conf/mapflag/skillmodifier.txt +npc: conf/mapflag/skillduration.txt \ No newline at end of file diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d563ba126..2e7c74b94 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3795,16 +3795,16 @@ ACMD_FUNC(reloadscript) * 0 = no additional information * 1 = Show users in that map and their location * 2 = Shows NPCs in that map - * 3 = Shows the shops/chats in that map (not implemented) + * 3 = Shows the chats in that map + TODO# add the missing mapflags e.g. adjust_skill_damage to display *------------------------------------------*/ -ACMD_FUNC(mapinfo) -{ +ACMD_FUNC(mapinfo) { struct map_session_data* pl_sd; struct s_mapiterator* iter; struct npc_data *nd = NULL; struct chat_data *cd = NULL; char direction[12]; - int i, m_id, chat_num, list = 0; + int i, m_id, chat_num = 0, list = 0, vend_num = 0; unsigned short m_index; char mapname[24]; @@ -3839,12 +3839,17 @@ ACMD_FUNC(mapinfo) // count chats (for initial message) chat_num = 0; iter = mapit_getallusers(); - for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) - if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd ) - chat_num++; + for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) { + if( pl_sd->mapindex == m_index ) { + if( sd->state.vending ) + vend_num++; + else if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && cd->usersd[0] == pl_sd ) + chat_num++; + } + } mapit_free(iter); - sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num); // Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d + sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].zone->name, map[m_id].users, map[m_id].npc_num, chat_num, vend_num); // Map: %s (Zone:%s) | Players: %d | NPCs: %d | Chats: %d | Vendings: %d clif_displaymessage(fd, atcmd_output); clif_displaymessage(fd, msg_txt(1041)); // ------ Map Flags ------ if (map[m_id].flag.town) @@ -3932,11 +3937,6 @@ ACMD_FUNC(mapinfo) strcat(atcmd_output, msg_txt(1077)); // Fireworks | if (map[m_id].flag.leaves) strcat(atcmd_output, msg_txt(1078)); // Leaves | - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //if (map[m_id].flag.rain) - // strcat(atcmd_output, msg_txt(1079)); // Rain | if (map[m_id].flag.nightenabled) strcat(atcmd_output, msg_txt(1080)); // Displays Night | clif_displaymessage(fd, atcmd_output); @@ -7635,7 +7635,7 @@ ACMD_FUNC(mapflag) { checkflag(fog); checkflag(fireworks); checkflag(sakura); checkflag(leaves); checkflag(nogo); checkflag(nobaseexp); checkflag(nojobexp); checkflag(nomobloot); checkflag(nomvploot); checkflag(nightenabled); - checkflag(restricted); checkflag(nodrop); checkflag(novending); checkflag(loadevent); + checkflag(nodrop); checkflag(novending); checkflag(loadevent); checkflag(nochat); checkflag(partylock); checkflag(guildlock); checkflag(src4instance); clif_displaymessage(sd->fd," "); clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) @@ -7654,7 +7654,7 @@ ACMD_FUNC(mapflag) { setflag(fog); setflag(fireworks); setflag(sakura); setflag(leaves); setflag(nogo); setflag(nobaseexp); setflag(nojobexp); setflag(nomobloot); setflag(nomvploot); setflag(nightenabled); - setflag(restricted); setflag(nodrop); setflag(novending); setflag(loadevent); + setflag(nodrop); setflag(novending); setflag(loadevent); setflag(nochat); setflag(partylock); setflag(guildlock); setflag(src4instance); clif_displaymessage(sd->fd,msg_txt(1314)); // Invalid flag name or flag. @@ -7666,7 +7666,7 @@ ACMD_FUNC(mapflag) { clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,"); clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,"); clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,"); - clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,"); + clif_displaymessage(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,"); clif_displaymessage(sd->fd,"guildlock, src4instance"); #undef checkflag diff --git a/src/map/clif.h b/src/map/clif.h index 8e0fc6629..1c04ae393 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -314,6 +314,10 @@ enum useskill_fail_cause USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83, }; +enum clif_messages { + SKILL_CANT_USE_AREA = 0x536, +}; + int clif_setip(const char* ip); void clif_setbindip(const char* ip); void clif_setport(uint16 port); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 79d303085..a91946b2a 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -585,27 +585,6 @@ static void itemdb_read_itemgroup(void) return; } -/*========================================== - * Read item forbidden by mapflag (can't equip item) - *------------------------------------------*/ -static bool itemdb_read_noequip(char* str[], int columns, int current) -{// , - int nameid; - struct item_data *id; - - nameid = atoi(str[0]); - - if( ( id = itemdb_exists(nameid) ) == NULL ) - { - ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid); - return false; - } - - id->flag.no_equip |= atoi(str[1]); - - return true; -} - /*========================================== * Reads item trade restrictions [Skotlex] *------------------------------------------*/ @@ -1310,7 +1289,6 @@ static void itemdb_read(void) { itemdb_read_combos(); itemdb_read_itemgroup(); sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail); - sv_readdb(db_path, DBPATH"item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip); sv_readdb(db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade); sv_readdb(db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay); sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack); diff --git a/src/map/itemdb.h b/src/map/itemdb.h index e308b248b..06c95da8a 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -66,7 +66,7 @@ enum { ITEMID_CAMOUFLAGE_GENERATOR, ITEMID_HIGH_QUALITY_COOLER, ITEMID_SPECIAL_COOLER, - } mecha_item_list; +} mecha_item_list; //The only item group required by the code to be known. See const.txt for the full list. #define IG_FINDINGORE 6 @@ -123,7 +123,6 @@ struct item_data { struct script_code *unequip_script;//Script executed once when unequipping. struct { unsigned available : 1; - short no_equip; unsigned no_refine : 1; // [celest] unsigned delay_consume : 1; // Signifies items that are not consumed immediately upon double-click [Skotlex] unsigned trade_restriction : 9; //Item restrictions mask [Skotlex] diff --git a/src/map/map.c b/src/map/map.c index bd0d97ece..a7b8513f7 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -13,6 +13,7 @@ #include "../common/random.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/conf.h" #include "map.h" #include "path.h" @@ -2892,6 +2893,31 @@ int map_delmap(char* mapname) } return 0; } +void map_zone_db_clear(void) { + struct map_zone_data *zone; + int i; + + DBIterator *iter = db_iterator(zone_db); + for(zone = dbi_first(iter); dbi_exists(iter); zone = dbi_next(iter)) { + aFree(zone->disabled_skills); + aFree(zone->disabled_items); + for(i = 0; i < zone->mapflags_count; i++) { + aFree(zone->mapflags[i]); + } + aFree(zone->mapflags); + } + dbi_destroy(iter); + + db_destroy(zone_db);/* will aFree(zone) */ + + /* clear the main zone stuff */ + aFree(map_zone_all.disabled_skills); + aFree(map_zone_all.disabled_items); + for(i = 0; i < map_zone_all.mapflags_count; i++) { + aFree(map_zone_all.mapflags[i]); + } + aFree(map_zone_all.mapflags); +} void do_final_maps(void) { int i, v = 0; @@ -2931,11 +2957,12 @@ void do_final_maps(void) { } map[i].skill_count = 0; } - + } + map_zone_db_clear(); + } - /// Initializes map flags and adjusts them depending on configuration. void map_flags_init(void) { int i, v = 0; @@ -2945,7 +2972,6 @@ void map_flags_init(void) { memset(&map[i].flag, 0, sizeof(map[i].flag)); // additional mapflag data - map[i].zone = 0; // restricted mapflag zone map[i].nocommand = 0; // nocommand mapflag level map[i].bexp = 100; // per map base exp multiplicator map[i].jexp = 100; // per map job exp multiplicator @@ -2968,10 +2994,12 @@ void map_flags_init(void) { } map[i].skills = NULL; map[i].skill_count = 0; - + // adjustments if( battle_config.pk_mode ) map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris] + /* align with 'All' zone */ + map[i].zone = &map_zone_all; } } @@ -3533,6 +3561,296 @@ int log_sql_init(void) #endif return 0; } +void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* start, const char* buffer, const char* filepath) { + int i; + char empty[1] = "\0"; + map[m].zone = zone; + for(i = 0; i < zone->mapflags_count; i++) { + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + int len = strlen(zone->mapflags[i]); + int k; + params[0] = '\0'; + memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + for(k = 0; k < len; k++) { + if( flag[k] == '\t' ) { + memcpy(params, &flag[k+1], len - k); + flag[k] = '\0'; + break; + } + } + npc_parse_mapflag(w1,empty,flag,params,start,buffer,filepath); + } +} +/* used on npc load and reload to apply all "Normal" zone */ +void map_zone_init(void) { + struct map_zone_data *zone; + char empty[1] = "\0"; + int i,k,j; + + zone = &map_zone_all; + + for(i = 0; i < zone->mapflags_count; i++) { + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + int len = strlen(zone->mapflags[i]); + params[0] = '\0'; + memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + for(k = 0; k < len; k++) { + if( flag[k] == '\t' ) { + memcpy(params, &flag[k+1], len - k); + flag[k] = '\0'; + break; + } + } + for(j = 0; j < map_num; j++) { + if( map[j].zone == &map_zone_all ) { + npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty); + } + } + } + +} +void read_map_zone_db(void) { + config_t map_zone_db; + config_setting_t *zones = NULL; + /* TODO: #ifndef required for re/pre-re */ +#ifdef RENEWAL + const char *config_filename = "db/re/map_zone_db.txt"; // FIXME hardcoded name +#else + const char *config_filename = "db/pre-re/map_zone_db.txt"; // FIXME hardcoded name +#endif + if (conf_read_file(&map_zone_db, config_filename)) + return; + + zones = config_lookup(&map_zone_db, "zones"); + + if (zones != NULL) { + struct map_zone_data *zone; + struct item_data *data; + config_setting_t *zone_e; + config_setting_t *skills; + config_setting_t *items; + config_setting_t *mapflags; + const char *name; + const char *zonename; + int i,h; + int zone_count = 0, disabled_skills_count = 0, disabled_items_count = 0, mapflags_count = 0; + + zone_count = config_setting_length(zones); + for (i = 0; i < zone_count; ++i) { + bool is_all = false; + + zone_e = config_setting_get_elem(zones, i); + + if (!config_setting_lookup_string(zone_e, "name", &zonename)) { + ShowError("map_zone_db: missing zone name, skipping... (%s:%d)\n", + config_setting_source_file(zone_e), config_setting_source_line(zone_e)); + config_setting_remove_elem(zones,i);/* remove from the tree */ + --zone_count; + --i; + continue; + } + + if( strdb_exists(zone_db, zonename) ) { + ShowError("map_zone_db: duplicate zone name '%s', skipping...\n",zonename); + config_setting_remove_elem(zones,i);/* remove from the tree */ + --zone_count; + --i; + continue; + } + + /* is this the global template? */ + if( strncmpi(zonename,MAP_ZONE_ALL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { + zone = &map_zone_all; + is_all = true; + } else { + CREATE( zone, struct map_zone_data, 1 ); + zone->disabled_skills_count = 0; + zone->disabled_items_count = 0; + } + safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH); + + if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) { + disabled_skills_count = config_setting_length(skills); + /* validate */ + for(h = 0; h < config_setting_length(skills); h++) { + config_setting_t *skill = config_setting_get_elem(skills, h); + name = config_setting_name(skill); + if( !strdb_exists(skilldb_name2id,name) ) { + ShowError("map_zone_db: unknown skill (%s) in disabled_skills for zone '%s', skipping skill...\n",name,zone->name); + config_setting_remove_elem(skills,h); + --disabled_skills_count; + --h; + continue; + } + if( !config_setting_get_bool(skill) )/* we dont remove it from the three due to inheritance */ + --disabled_skills_count; + } + /* all ok, process */ + CREATE( zone->disabled_skills, int, disabled_skills_count ); + for(h = 0; h < disabled_skills_count; h++) { + config_setting_t *skill = config_setting_get_elem(skills, h); + + name = config_setting_name(skill); + + if( config_setting_get_bool(skill) )/* only add if enabled */ + zone->disabled_skills[h] = strdb_iget(skilldb_name2id, name); + + } + zone->disabled_skills_count = disabled_skills_count; + } + + if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) { + disabled_items_count = config_setting_length(items); + /* validate */ + for(h = 0; h < config_setting_length(items); h++) { + config_setting_t *item = config_setting_get_elem(items, h); + name = config_setting_name(item); + data = itemdb_searchname(name); + if( data == NULL ) { + ShowError("map_zone_db: unknown item (%s) in disabled_items for zone '%s', skipping item...\n",name,zone->name); + config_setting_remove_elem(items,h); + --disabled_items_count; + --h; + continue; + } + if( !config_setting_get_bool(item) )/* we dont remove it from the three due to inheritance */ + --disabled_items_count; + } + /* all ok, process */ + CREATE( zone->disabled_items, int, disabled_items_count ); + for(h = 0; h < disabled_items_count; h++) { + config_setting_t *item = config_setting_get_elem(items, h); + + if( config_setting_get_bool(item) ) { /* only add if enabled */ + name = config_setting_name(item); + data = itemdb_searchname(name); + zone->disabled_items[h] = data->nameid; + } + + } + zone->disabled_items_count = disabled_items_count; + } + + if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) { + mapflags_count = config_setting_length(mapflags); + /* mapflags are not validated here, so we save all anyway */ + CREATE( zone->mapflags, char *, mapflags_count ); + for(h = 0; h < mapflags_count; h++) { + CREATE( zone->mapflags[h], char, MAP_ZONE_MAPFLAG_LENGTH ); + + name = config_setting_get_string_elem(mapflags, h); + + safestrncpy(zone->mapflags[h], name, MAP_ZONE_MAPFLAG_LENGTH); + + } + zone->mapflags_count = mapflags_count; + } + + + if( !is_all ) /* global template doesn't go into db -- since it isn't a alloc'd piece of data */ + strdb_put(zone_db, zonename, zone); + + } + + /* process inheritance, aka loop through the whole thing again :P */ + for (i = 0; i < zone_count; ++i) { + config_setting_t *inherit_tree = NULL; + + zone_e = config_setting_get_elem(zones, i); + + if( (inherit_tree = config_setting_get_member(zone_e, "inherit")) != NULL ) { + int inherit_count = config_setting_length(inherit_tree); + for(h = 0; h < inherit_count; h++) { + struct map_zone_data *izone; /* inherit zone */ + int disabled_skills_count_i = 0; /* disabled skill count from inherit zone */ + int disabled_items_count_i = 0; /* disabled item count from inherit zone */ + int mapflags_count_i = 0; /* mapflag count from inherit zone */ + int j; + + name = config_setting_get_string_elem(inherit_tree, h); + config_setting_lookup_string(zone_e, "name", &zonename);/* will succeed for we validated it earlier */ + + if( !(izone = strdb_get(zone_db, name)) ) { + ShowError("map_zone_db: Unknown zone '%s' being inherit by zone '%s', skipping...\n",name,zonename); + continue; + } + + zone = strdb_get(zone_db, zonename);/* will succeed for we just put it in here */ + + disabled_skills_count_i = izone->disabled_skills_count; + disabled_items_count_i = izone->disabled_items_count; + mapflags_count_i = izone->mapflags_count; + + /* process everything to override, paying attention to config_setting_get_bool */ + if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) { + disabled_skills_count = config_setting_length(skills); + for(j = 0; j < disabled_skills_count_i; j++) { + int k; + for(k = 0; k < disabled_skills_count; k++) { + config_setting_t *skill = config_setting_get_elem(skills, k); + if( strdb_iget(skilldb_name2id, config_setting_name(skill)) == izone->disabled_skills[j] ) { + if( config_setting_get_bool(skill) ) + continue; + break; + } + } + if( k == disabled_skills_count ) {/* we didn't find it */ + RECREATE( zone->disabled_skills, int, ++zone->disabled_skills_count ); + zone->disabled_skills[zone->disabled_skills_count-1] = izone->disabled_skills[j]; + } + } + } + + if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) { + disabled_items_count = config_setting_length(items); + for(j = 0; j < disabled_items_count_i; j++) { + int k; + for(k = 0; k < disabled_items_count; k++) { + config_setting_t *item = config_setting_get_elem(items, k); + + name = config_setting_name(item); + data = itemdb_searchname(name); + + if( data->nameid == izone->disabled_items[j] ) { + if( config_setting_get_bool(item) ) + continue; + break; + } + } + if( k == disabled_items_count ) {/* we didn't find it */ + RECREATE( zone->disabled_items, int, ++zone->disabled_items_count ); + zone->disabled_items[zone->disabled_items_count-1] = izone->disabled_items[j]; + } + } + } + + if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) { + mapflags_count = config_setting_length(mapflags); + for(j = 0; j < mapflags_count_i; j++) { + int k; + for(k = 0; k < mapflags_count; k++) { + name = config_setting_get_string_elem(mapflags, k); + + if( strcmpi(name,izone->mapflags[j]) == 0 ) { + break; + } + } + if( k == mapflags_count ) {/* we didn't find it */ + RECREATE( zone->mapflags, char*, ++zone->mapflags_count ); + CREATE( zone->mapflags[zone->mapflags_count-1], char, MAP_ZONE_MAPFLAG_LENGTH ); + safestrncpy(zone->mapflags[zone->mapflags_count-1], izone->mapflags[j], MAP_ZONE_MAPFLAG_LENGTH); + } + } + } + } + } + } + + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' zones in '"CL_WHITE"%s"CL_RESET"'.\n", zone_count, config_filename); + /* not supposed to go in here but in skill_final whatever */ + config_destroy(&map_zone_db); + } +} /** * @see DBApply @@ -3632,7 +3950,7 @@ void do_final(void) id_db->foreach(id_db,cleanup_db_sub); chrif_char_reset_offline(); chrif_flush_fifo(); - + do_final_atcommand(); battle->final(); do_final_chrif(); @@ -3933,7 +4251,9 @@ int do_init(int argc, char *argv[]) regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls + zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH); + map_sql_init(); if (log_config.sql_logs) log_sql_init(); @@ -3957,6 +4277,7 @@ int do_init(int argc, char *argv[]) do_init_script(); do_init_itemdb(); skill->init(); + read_map_zone_db();/* read after item and skill initalization */ do_init_mob(); do_init_pc(); do_init_status(); diff --git a/src/map/map.h b/src/map/map.h index 38d9726cb..cd5983686 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -11,9 +11,6 @@ #include "../common/mapindex.h" #include "../common/db.h" -/** - * [rAthena.org] - **/ #include "../config/core.h" #include @@ -21,8 +18,7 @@ struct npc_data; struct item_data; -enum E_MAPSERVER_ST -{ +enum E_MAPSERVER_ST { MAPSERVER_ST_RUNNING = CORE_ST_LAST, MAPSERVER_ST_SHUTDOWN, MAPSERVER_ST_LAST @@ -501,6 +497,28 @@ struct mapflag_skill_adjust { unsigned short modifier; }; +#define MAP_ZONE_NAME_LENGTH 30 +#define MAP_ZONE_ALL_NAME "Normal" +#define MAP_ZONE_PVP_NAME "PvP" +#define MAP_ZONE_GVG_NAME "GvG" +#define MAP_ZONE_BG_NAME "Battlegrounds" +#define MAP_ZONE_MAPFLAG_LENGTH 50 +DBMap *zone_db;/* string => struct map_zone_data */ +struct map_zone_data { + char name[MAP_ZONE_NAME_LENGTH];/* 20'd */ + int *disabled_skills; + int disabled_skills_count; + int *disabled_items; + int disabled_items_count; + char **mapflags; + int mapflags_count; +}; +void map_zone_init(void); +void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* start, const char* buffer, const char* filepath); + +struct map_zone_data map_zone_all;/* used as a base on all maps */ + + struct map_data { char name[MAP_NAME_LENGTH]; uint16 index; // The map index used by the mapindex* functions. @@ -559,7 +577,6 @@ struct map_data { unsigned nomobloot : 1; // [Lorky] unsigned nomvploot : 1; // [Lorky] unsigned nightenabled :1; //For night display. [Skotlex] - unsigned restricted : 1; // [Komurka] unsigned nodrop : 1; unsigned novending : 1; unsigned loadevent : 1; @@ -579,7 +596,6 @@ struct map_data { struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer] int mob_delete_timer; // [Skotlex] - int zone; // zone number (for item/skill restrictions) int jexp; // map experience multiplicator int bexp; // map experience multiplicator int nocommand; //Blocks @/# commands for non-gms. [Skotlex] @@ -600,6 +616,9 @@ struct map_data { /* adjust_skill_damage mapflag */ struct mapflag_skill_adjust **skills; unsigned short skill_count; + + /* Hercules nocast db overhaul */ + struct map_zone_data *zone; }; /// Stores information about a remote map (for multi-mapserver setups). diff --git a/src/map/mob.c b/src/map/mob.c index fa4bd5c7f..71b500491 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -3389,8 +3389,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) { skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id; if (!skill_id || sd->status.skill[skill_id].lv < 1 || - (skill->get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) || - skill->get_nocast(skill_id)&16 + (skill->get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ) continue; //Normal aggressive mob, disable skills that cannot help them fight diff --git a/src/map/npc.c b/src/map/npc.c index 0c9924d46..797fc7422 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3157,14 +3157,12 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c return strchr(start,'\n');// continue } - /*========================================== * Set or disable mapflag on map * eg : bat_c01 mapflag battleground 2 * also chking if mapflag conflict with another *------------------------------------------*/ -static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) -{ +const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) { int16 m; char mapname[32]; int state = 1; @@ -3231,19 +3229,21 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con map[m].flag.nozenypenalty=state; } else if (!strcmpi(w3,"pvp")) { + struct map_zone_data *zone; map[m].flag.pvp = state; - if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) - { + if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) { map[m].flag.gvg = 0; map[m].flag.gvg_dungeon = 0; map[m].flag.gvg_castle = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } - if( state && map[m].flag.battleground ) - { + if( state && map[m].flag.battleground ) { map[m].flag.battleground = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } + if( (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) { + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else if (!strcmpi(w3,"pvp_noparty")) map[m].flag.pvp_noparty=state; @@ -3283,17 +3283,20 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con else if (!strcmpi(w3,"pvp_nocalcrank")) map[m].flag.pvp_nocalcrank=state; else if (!strcmpi(w3,"gvg")) { + struct map_zone_data *zone; + map[m].flag.gvg = state; - if( state && map[m].flag.pvp ) - { + if( state && map[m].flag.pvp ) { map[m].flag.pvp = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } - if( state && map[m].flag.battleground ) - { + if( state && map[m].flag.battleground ) { map[m].flag.battleground = 0; ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } + if( (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) { + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else if (!strcmpi(w3,"gvg_noparty")) map[m].flag.gvg_noparty=state; @@ -3306,28 +3309,29 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con if (state) map[m].flag.pvp=0; } else if (!strcmpi(w3,"battleground")) { - if( state ) - { + struct map_zone_data *zone; + if( state ) { if( sscanf(w4, "%d", &state) == 1 ) map[m].flag.battleground = state; else map[m].flag.battleground = 1; // Default value - } - else + } else map[m].flag.battleground = 0; - if( map[m].flag.battleground && map[m].flag.pvp ) - { + if( map[m].flag.battleground && map[m].flag.pvp ) { map[m].flag.pvp = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } - if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) - { + if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) { map[m].flag.gvg = 0; map[m].flag.gvg_dungeon = 0; map[m].flag.gvg_castle = 0; ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } + + if( (zone = strdb_get(zone_db, MAP_ZONE_BG_NAME)) && map[m].zone != zone ) { + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else if (!strcmpi(w3,"noexppenalty")) map[m].flag.noexppenalty=state; @@ -3391,16 +3395,6 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con } else map[m].nocommand=0; } - else if (!strcmpi(w3,"restricted")) { - if (state) { - map[m].flag.restricted=1; - sscanf(w4, "%d", &state); - map[m].zone |= 1<<(state+1); - } else { - map[m].flag.restricted=0; - map[m].zone = 0; - } - } else if (!strcmpi(w3,"jexp")) { map[m].jexp = (state) ? atoi(w4) : 100; if( map[m].jexp < 0 ) map[m].jexp = 100; @@ -3459,6 +3453,14 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con map[m].skills[idx]->skill_id = (unsigned short)skill_id; map[m].skills[idx]->modifier = (unsigned short)atoi(mod); } + } else if (!strcmpi(w3,"zone")) { + struct map_zone_data *zone; + + if( !(zone = strdb_get(zone_db, w4)) ) { + ShowWarning("npc_parse_mapflag: Invalid zone '%s'! removing flag from %s (file '%s', line '%d').\n", w4, map[m].name, filepath, strline(buffer,start-buffer)); + } else if( map[m].zone != zone ) { /* we do not override :P would mess everything */ + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer)); @@ -3792,12 +3794,14 @@ int npc_reload(void) { "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); - + do_final_instance(); for( i = 0; i < ARRAYLENGTH(instance); ++i ) instance_init(instance[i].instance_id); + map_zone_init(); + //Re-read the NPC Script Events cache. npc_read_event_script(); @@ -3926,6 +3930,8 @@ int do_init_npc(void) "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); + map_zone_init(); + // set up the events cache memset(script_event, 0, sizeof(script_event)); npc_read_event_script(); diff --git a/src/map/npc.h b/src/map/npc.h index 20ce34459..424ff9312 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -124,6 +124,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type); int npc_buylist(struct map_session_data* sd,int n, unsigned short* item_list); int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list); void npc_parse_mob2(struct spawn_data* mob); +const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath); struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y); int npc_globalmessage(const char* name,const char* mes); diff --git a/src/map/pc.c b/src/map/pc.c index 4bd66a67c..840bf0c03 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4227,12 +4227,13 @@ int pc_isUseitem(struct map_session_data *sd,int n) int pc_useitem(struct map_session_data *sd,int n) { unsigned int tick = gettick(); - int amount, nameid; + int amount, nameid, i; struct script_code *script; nullpo_ret(sd); if( sd->npc_id ){ + /* TODO: add to clif_messages enum */ #ifdef RENEWAL clif_msg(sd, 0x783); // TODO look for the client date that has this message. #endif @@ -4320,19 +4321,15 @@ int pc_useitem(struct map_session_data *sd,int n) } } - /* on restricted maps the item is consumed but the effect is not used */ - if ( - (!map_flag_vs(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&1) || // Normal - (map[sd->bl.m].flag.pvp && sd->inventory_data[n]->flag.no_equip&2) || // PVP - (map_flag_gvg(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&4) || // GVG - (map[sd->bl.m].flag.battleground && sd->inventory_data[n]->flag.no_equip&8) || // Battleground - (map[sd->bl.m].flag.restricted && sd->inventory_data[n]->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction - ) { - if( battle_config.item_restricted_consumption_type ) { - clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true); - pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); + /* on restricted maps the item is consumed but the effect is not used */ + for(i = 0; i < map[sd->bl.m].zone->disabled_items_count; i++) { + if( map[sd->bl.m].zone->disabled_items[i] == nameid ) { + if( battle_config.item_restricted_consumption_type ) { + clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true); + pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); + } + return 0; } - return 0;/* regardless, effect is not run */ } sd->itemid = sd->status.inventory[n].nameid; diff --git a/src/map/script.c b/src/map/script.c index 4c913651a..0e45f4821 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -384,7 +384,7 @@ enum { MF_NORETURN, MF_NOWARPTO, MF_NIGHTMAREDROP, - MF_RESTRICTED, + MF_ZONE, MF_NOCOMMAND, MF_NODROP, MF_JEXP, @@ -9558,8 +9558,8 @@ static int buildin_announce_sub(struct block_list *bl, va_list ap) return 0; } /* Runs item effect on attached character. - * consumeitem ; - * consumeitem ""; */ + * itemeffect ; + * itemeffect ""; */ BUILDIN_FUNC(itemeffect) { TBL_NPC *nd; TBL_PC *sd; @@ -9579,14 +9579,14 @@ BUILDIN_FUNC(itemeffect) { ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name ); return 1; } - }else if( data_isint( data ) ){ + } else if( data_isint( data ) ){ int nameid = conv_num( st, data ); if( ( item_data = itemdb_exists( nameid ) ) == NULL ){ ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid ); return 1; } - }else{ + } else { ShowError("buildin_itemeffect: invalid data type for argument #1 (%d).", data->type ); return 1; } @@ -10707,10 +10707,6 @@ BUILDIN_FUNC(getmapflag) case MF_FOG: script_pushint(st,map[m].flag.fog); break; case MF_SAKURA: script_pushint(st,map[m].flag.sakura); break; case MF_LEAVES: script_pushint(st,map[m].flag.leaves); break; - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //case MF_RAIN: script_pushint(st,map[m].flag.rain); break; case MF_NOGO: script_pushint(st,map[m].flag.nogo); break; case MF_CLOUDS: script_pushint(st,map[m].flag.clouds); break; case MF_CLOUDS2: script_pushint(st,map[m].flag.clouds2); break; @@ -10725,7 +10721,6 @@ BUILDIN_FUNC(getmapflag) case MF_NORETURN: script_pushint(st,map[m].flag.noreturn); break; case MF_NOWARPTO: script_pushint(st,map[m].flag.nowarpto); break; case MF_NIGHTMAREDROP: script_pushint(st,map[m].flag.pvp_nightmaredrop); break; - case MF_RESTRICTED: script_pushint(st,map[m].flag.restricted); break; case MF_NOCOMMAND: script_pushint(st,map[m].nocommand); break; case MF_NODROP: script_pushint(st,map[m].flag.nodrop); break; case MF_JEXP: script_pushint(st,map[m].jexp); break; @@ -10764,15 +10759,27 @@ static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) { BUILDIN_FUNC(setmapflag) { int16 m,i; - const char *str; + const char *str, *val2; + struct script_data* data; int val=0; str=script_getstr(st,2); - i=script_getnum(st,3); + + i = script_getnum(st, 3); + if(script_hasdata(st,4)){ - val=script_getnum(st,4); + data = script_getdata(st,4); + get_val(st, data); + + + if( data_isstring(data) ) + val2 = script_getstr(st, 4); + else + val = script_getnum(st, 4); + } m = map_mapname2mapid(str); + if(m >= 0) { switch(i) { case MF_NOMEMO: map[m].flag.nomemo = 1; break; @@ -10821,9 +10828,13 @@ BUILDIN_FUNC(setmapflag) case MF_NORETURN: map[m].flag.noreturn = 1; break; case MF_NOWARPTO: map[m].flag.nowarpto = 1; break; case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 1; break; - case MF_RESTRICTED: - map[m].zone |= 1<<(val+1); - map[m].flag.restricted=1; + case MF_ZONE: { + char zone[6] = "zone\0"; + char empty[1] = "\0"; + char params[MAP_ZONE_MAPFLAG_LENGTH]; + memcpy(params, val2, MAP_ZONE_MAPFLAG_LENGTH); + npc_parse_mapflag(map[m].name, empty, zone, params, empty, empty, empty); + } break; case MF_NOCOMMAND: map[m].nocommand = (val <= 0) ? 100 : val; break; case MF_NODROP: map[m].flag.nodrop = 1; break; @@ -10887,10 +10898,6 @@ BUILDIN_FUNC(removemapflag) case MF_FOG: map[m].flag.fog = 0; break; case MF_SAKURA: map[m].flag.sakura = 0; break; case MF_LEAVES: map[m].flag.leaves = 0; break; - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //case MF_RAIN: map[m].flag.rain = 0; break; case MF_NOGO: map[m].flag.nogo = 0; break; case MF_CLOUDS: map[m].flag.clouds = 0; break; case MF_CLOUDS2: map[m].flag.clouds2 = 0; break; @@ -10905,11 +10912,8 @@ BUILDIN_FUNC(removemapflag) case MF_NORETURN: map[m].flag.noreturn = 0; break; case MF_NOWARPTO: map[m].flag.nowarpto = 0; break; case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 0; break; - case MF_RESTRICTED: - map[m].zone ^= 1<<(val+1); - if (map[m].zone == 0){ - map[m].flag.restricted=0; - } + case MF_ZONE:/* reset zone state, mapflags cant be removed however */ + map[m].zone = &map_zone_all; break; case MF_NOCOMMAND: map[m].nocommand = 0; break; case MF_NODROP: map[m].flag.nodrop = 0; break; @@ -17566,7 +17570,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(isloggedin,"i?"), BUILDIN_DEF(setmapflagnosave,"ssii"), BUILDIN_DEF(getmapflag,"si"), - BUILDIN_DEF(setmapflag,"si?"), + BUILDIN_DEF(setmapflag,"sv?"), BUILDIN_DEF(removemapflag,"si?"), BUILDIN_DEF(pvpon,"s"), BUILDIN_DEF(pvpoff,"s"), diff --git a/src/map/skill.c b/src/map/skill.c index 88111d898..3bd454357 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -212,7 +212,6 @@ int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_d int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_db[skill_id].mhp[skill_lv-1], skill_id, skill_lv); } int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_db[skill_id].castnodex[skill_lv-1], skill_id, skill_lv); } int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ skill_get (skill_db[skill_id].delaynodex[skill_lv-1], skill_id, skill_lv); } -int skill_get_nocast ( uint16 skill_id ) { skill_get (skill_db[skill_id].nocast, skill_id, 1); } int skill_get_type( uint16 skill_id ) { skill_get (skill_db[skill_id].skill_type, skill_id, 1); } int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill_db[skill_id].unit_id[flag], skill_id, 1); } int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill_db[skill_id].unit_interval, skill_id, 1); } @@ -478,6 +477,7 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b int skillnotok (uint16 skill_id, struct map_session_data *sd) { int16 idx,m; + int i; nullpo_retr (1, sd); m = sd->bl.m; idx = skill->get_index(skill_id); @@ -501,25 +501,23 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) return 1; } - if (sd->blockskill[idx] > 0){ + if (sd->blockskill[idx] > 0) { clif_skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0); return 1; } + /** - * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions above + * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions below * Also, without this check, an exploit where an item casting + healing (or any other kind buff) isn't deleted after used on a restricted map **/ if( sd->skillitem == skill_id ) return 0; - /* TODO: these skill_get_nocast should be cached once instead of looking it up 5 times =_= */ - // Check skill restrictions [Celest] - if( (!map_flag_vs(m) && skill->get_nocast (skill_id) & 1) || - (map[m].flag.pvp && skill->get_nocast (skill_id) & 2) || - (map_flag_gvg(m) && skill->get_nocast (skill_id) & 4) || - (map[m].flag.battleground && skill->get_nocast (skill_id) & 8) || - (map[m].flag.restricted && map[m].zone && skill->get_nocast (skill_id) & (8*map[m].zone)) ){ - clif_msg(sd, 0x536); // This skill cannot be used within this area + + for(i = 0; i < map[m].zone->disabled_skills_count; i++) { + if( skill_id == map[m].zone->disabled_skills[i] ) { + clif_msg(sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area return 1; + } } if( sd->sc.option&OPTION_MOUNTING ) @@ -17476,18 +17474,6 @@ bool skill_parse_row_castnodexdb(char* split[], int columns, int current) { return true; } -bool skill_parse_row_nocastdb(char* split[], int columns, int current) { -// skill_id,Flag - uint16 skill_id = atoi(split[0]); - uint16 idx = skill->get_index(skill_id); - if( !idx ) // invalid skill id - return false; - - skill_db[idx].nocast |= atoi(split[1]); - - return true; -} - bool skill_parse_row_unitdb(char* split[], int columns, int current) { // ID,unit ID,unit ID 2,layout,range,interval,target,flag uint16 skill_id = atoi(split[0]); @@ -17734,8 +17720,6 @@ void skill_readdb(void) { sv_readdb(db_path, DBPATH"skill_castnodex_db.txt", ',', 2, 3, MAX_SKILL_DB, skill->parse_row_castnodexdb); sv_readdb(db_path, DBPATH"skill_unit_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill->parse_row_unitdb); - sv_readdb(db_path, DBPATH"skill_nocast_db.txt" , ',', 2, 2, MAX_SKILL_DB, skill->parse_row_nocastdb); - skill->init_unit_layout(); sv_readdb(db_path, "produce_db.txt" , ',', 4, 4+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill->parse_row_producedb); sv_readdb(db_path, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESOURCE, MAX_SKILL_ARROW_DB, skill->parse_row_createarrowdb); @@ -17747,7 +17731,6 @@ void skill_readdb(void) { sv_readdb(db_path, "skill_reproduce_db.txt", ',', 1, 1, MAX_SKILL_DB, skill->parse_row_reproducedb); sv_readdb(db_path, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill->parse_row_improvisedb); sv_readdb(db_path, "skill_changematerial_db.txt" , ',', 4, 4+2*5, MAX_SKILL_PRODUCE_DB, skill->parse_row_changematerialdb); - } void skill_reload (void) { @@ -17791,6 +17774,7 @@ int do_init_skill (void) int do_final_skill(void) { db_destroy(skilldb_name2id); + /* TODO: ZONE_DB IS NOT PROPERLY CLEARED */ db_destroy(group_db); db_destroy(skillunit_db); db_destroy(skillcd_db); @@ -17834,7 +17818,6 @@ void skill_defaults(void) { skill->get_weapontype = skill_get_weapontype; skill->get_ammotype = skill_get_ammotype; skill->get_ammo_qty = skill_get_ammo_qty; - skill->get_nocast = skill_get_nocast; skill->get_unit_id = skill_get_unit_id; skill->get_inf2 = skill_get_inf2; skill->get_castcancel = skill_get_castcancel; @@ -17967,7 +17950,6 @@ void skill_defaults(void) { skill->parse_row_castdb = skill_parse_row_castdb; skill->parse_row_castnodexdb = skill_parse_row_castnodexdb; skill->parse_row_unitdb = skill_parse_row_unitdb; - skill->parse_row_nocastdb = skill_parse_row_nocastdb; skill->parse_row_producedb = skill_parse_row_producedb; skill->parse_row_createarrowdb = skill_parse_row_createarrowdb; skill->parse_row_abradb = skill_parse_row_abradb; diff --git a/src/map/skill.h b/src/map/skill.h index be5f0a54f..3e2fc7936 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1732,7 +1732,6 @@ struct skill_interface { int (*get_weapontype) ( uint16 skill_id ); int (*get_ammotype) ( uint16 skill_id ); int (*get_ammo_qty) ( uint16 skill_id, uint16 skill_lv ); - int (*get_nocast) ( uint16 skill_id ); int (*get_unit_id) (uint16 skill_id,int flag); int (*get_inf2) ( uint16 skill_id ); int (*get_castcancel) ( uint16 skill_id ); @@ -1866,7 +1865,6 @@ struct skill_interface { bool (*parse_row_castdb) (char* split[], int columns, int current); bool (*parse_row_castnodexdb) (char* split[], int columns, int current); bool (*parse_row_unitdb) (char* split[], int columns, int current); - bool (*parse_row_nocastdb) (char* split[], int columns, int current); bool (*parse_row_producedb) (char* split[], int columns, int current); bool (*parse_row_createarrowdb) (char* split[], int columns, int current); bool (*parse_row_abradb) (char* split[], int columns, int current); diff --git a/src/map/status.c b/src/map/status.c index 64f7f81af..f356e4aa5 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2228,7 +2228,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) const struct status_change *sc = &sd->sc; struct s_skill b_skill[MAX_SKILL]; // previous skill tree int b_weight, b_max_weight, b_cart_weight_max, // previous weight - i, index, skill,refinedef=0; + i, k, index, skill,refinedef=0; int64 i64; if (++calculating > 10) //Too many recursive calls! @@ -2392,19 +2392,14 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if(!sd->inventory_data[index]) continue; - if(sd->inventory_data[index]->flag.no_equip) { // Items may be equipped, their effects however are nullified. - if(map[sd->bl.m].flag.restricted && sd->inventory_data[index]->flag.no_equip&(8*map[sd->bl.m].zone)) - continue; - if(!map_flag_vs(sd->bl.m) && sd->inventory_data[index]->flag.no_equip&1) - continue; - if(map[sd->bl.m].flag.pvp && sd->inventory_data[index]->flag.no_equip&2) - continue; - if(map_flag_gvg(sd->bl.m) && sd->inventory_data[index]->flag.no_equip&4) - continue; - if(map[sd->bl.m].flag.battleground && sd->inventory_data[index]->flag.no_equip&8) - continue; + for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) { + if( map[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) { + break; + } } - + + if( k < map[sd->bl.m].zone->disabled_items_count ) + continue; status->def += sd->inventory_data[index]->def; @@ -2540,28 +2535,24 @@ int status_calc_pc_(struct map_session_data* sd, bool first) data = itemdb_exists(c); if(!data) continue; - if(first && data->equip_script) - { //Execute equip-script on login + if(first && data->equip_script) {//Execute equip-script on login run_script(data->equip_script,0,sd->bl.id,0); if (!calculating) return 1; } if(!data->script) continue; - if(data->flag.no_equip) { //Card restriction checks. - if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone)) - continue; - if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1) - continue; - if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2) - continue; - if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4) - continue; - if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8) - continue; + + for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) { + if( map[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) { + break; + } } - if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) - { //Left hand status. + + if( k < map[sd->bl.m].zone->disabled_items_count ) + continue; + + if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { //Left hand status. sd->state.lr_flag = 1; run_script(data->script,0,sd->bl.id,0); sd->state.lr_flag = 0; -- cgit v1.2.3-70-g09d2 From 39799c4d0a5a9e523b0830f028f8aafb20744ba7 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 8 Apr 2013 22:25:47 -0300 Subject: Introducing Cash Shop Support Special Thanks to Yommy, Yommy, Yommy, malufett, Judas, Beret and everyone whos helped us get the 2013 client to work, Thank you all! http://hercules.ws/board/topic/367-introducing-cash-shop-support/ Signed-off-by: shennetsind --- db/cashshop_db.txt | 45 +++++++++ src/map/clif.c | 283 +++++++++++++++++++++++++++++++++++++++++++++-------- src/map/clif.h | 35 +++++++ src/map/itemdb.c | 1 + src/map/packets.h | 3 +- 5 files changed, 327 insertions(+), 40 deletions(-) create mode 100644 db/cashshop_db.txt (limited to 'src/map/itemdb.c') diff --git a/db/cashshop_db.txt b/db/cashshop_db.txt new file mode 100644 index 000000000..fc6a803c7 --- /dev/null +++ b/db/cashshop_db.txt @@ -0,0 +1,45 @@ +// Hercules Cash Shop Database +// Format: +// Tab ID or Tab Name, ItemID or Item Name, Price +// +// Tabs: +// 0 = New +// 1 = Popular +// 2 = Limited +// 3 = Rental +// 4 = Permanent +// 5 = Scroll +// 6 = Usable +// 7 = Other + +//New +New,Apple,100 +0,531,250 + +//Popular +1,513,100 +Popular,Banana_Juice,250 + +//Limited +2,Grape,100 +Limited,533,250 + +//Rental +Rental,515,100 +3,Carrot_Juice,250 + +//Permanent +4,Green_Herb,100 +Permanent,510,250 + +//Scroll +5,501,100 +5,502,250 + +//Usable +usable,White_Potion,150 +usable,Blue_Potion,500 + +//Other +7,909,400 +7,907,500 \ No newline at end of file diff --git a/src/map/clif.c b/src/map/clif.c index df0fd1077..745f90e68 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -16242,8 +16242,102 @@ void clif_parse_MoveItem(int fd, struct map_session_data *sd) { clif->favorite_item(sd, index); #endif } +/* [Ind/Hercules] */ +void clif_cashshop_db(void) { + FILE *fp; + char line[254]; + int ln = 0;/* line num */ + char *str[3], *p; + struct item_data * data; + int val, type, j; + + for( j = 0; j < CASHSHOP_TAB_MAX; j++ ) { + CREATE(clif->cs.data[j], struct hCSData *, 1); + clif->cs.item_count[j] = 0; + } + + if( (fp=fopen("db/cashshop_db.txt","r"))==NULL ){ + ShowError("can't read %s\n", "db/cashshop_db.txt"); + return; + } + + while(fgets(line, sizeof(line), fp)) { + ln++; + if( line[0]=='/' && line[1]=='/' ) + continue; + + memset(str,0,sizeof(str)); + data = NULL; + + for(j=0,p=line;j<3 && p;j++){ + str[j]=p; + p=strchr(p,','); + if(p) *p++=0; + } + + if(str[0]==NULL) + continue; + + if ( j < 3 ) { + if ( j > 1 ) + ShowWarning("cashshop_db: insufficient fields for entry at %s:%d\n", "db/cashshop_db.txt", ln); + continue; + } + if( ISALPHA(str[0][0]) ) { + if( strcmpi(str[0],"new") == 0 ) + type = CASHSHOP_TAB_NEW; + else if( strcmpi(str[0],"popular") == 0 ) + type = CASHSHOP_TAB_POPULAR; + else if( strcmpi(str[0],"limited") == 0 ) + type = CASHSHOP_TAB_LIMITED; + else if( strcmpi(str[0],"rental") == 0 ) + type = CASHSHOP_TAB_RENTAL; + else if( strcmpi(str[0],"permanent") == 0 ) + type = CASHSHOP_TAB_PERPETUITY; + else if( strcmpi(str[0],"scroll") == 0 ) + type = CASHSHOP_TAB_BUFF; + else if( strcmpi(str[0],"usable") == 0 ) + type = CASHSHOP_TAB_RECOVERY; + else if( strcmpi(str[0],"other") == 0 ) + type = CASHSHOP_TAB_ETC; + else { + ShowWarning("cashshop_db: unknown type %s for entry at %s:%d\n", str[0], "db/cashshop_db.txt", ln); + continue; + } + } else { + type = atoi(str[0]); + if( type < 0 || type > CASHSHOP_TAB_MAX ) { + ShowWarning("cashshop_db: unknown type %d for entry at %s:%d\n", type, "db/cashshop_db.txt", ln); + continue; + } + } + + if( ISALPHA(str[1][0]) ) { + if( !( data = itemdb_searchname(str[1]) ) ) { + ShowWarning("cashshop_db: unknown item name %s for entry at %s:%d\n", str[1], "db/cashshop_db.txt", ln); + continue; + } + } else { + if( !( data = itemdb_exists(atoi(str[1]))) ) { + ShowWarning("cashshop_db: unknown item id %s for entry at %s:%d\n", str[1], "db/cashshop_db.txt", ln); + continue; + } + } + + if( ( val = atoi(str[2]) ) < 1 ) { + ShowWarning("cashshop_db: unsupported price '%d' for entry at %s:%d\n", val, "db/cashshop_db.txt", ln); + continue; + } + + RECREATE(clif->cs.data[type], struct hCSData *, ++clif->cs.item_count[type]); + CREATE(clif->cs.data[type][ clif->cs.item_count[type] - 1 ], struct hCSData , 1); - + clif->cs.data[type][ clif->cs.item_count[type] - 1 ]->id = data->nameid; + clif->cs.data[type][ clif->cs.item_count[type] - 1 ]->price = val; + + } + fclose(fp); +} /// Items that are in favorite tab of inventory (ZC_ITEM_FAVORITE). /// 0900 .W .B void clif_favorite_item(struct map_session_data* sd, unsigned short index) { @@ -16287,15 +16381,114 @@ void __attribute__ ((unused)) clif_parse_dull(int fd,struct map_session_data *sd void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) { WFIFOHEAD(fd, 10); WFIFOW(fd, 0) = 0x845; - WFIFOL(fd, 2) = 0; - WFIFOL(fd, 6) = 0; - WFIFOSET(fd, 10); + WFIFOL(fd, 2) = sd->cashPoints;/* kafra for now disabled until we know how to apply it */ + WFIFOL(fd, 6) = sd->cashPoints; + WFIFOSET(fd, 10); } void clif_parse_CashShopClose(int fd, struct map_session_data *sd) { } +void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) { + int i, j = 0; + + for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) { + WFIFOHEAD(fd, 8 + ( clif->cs.item_count[i] * 6 ) ); + WFIFOW(fd, 0) = 0x8ca; + WFIFOW(fd, 2) = 8 + ( clif->cs.item_count[i] * 6 ); + WFIFOW(fd, 4) = clif->cs.item_count[i]; + WFIFOW(fd, 6) = i; + + for( j = 0; j < clif->cs.item_count[i]; j++ ) { + WFIFOW(fd, 8 + ( 6 * j ) ) = clif->cs.data[i][j]->id; + WFIFOL(fd, 10 + ( 6 * j ) ) = clif->cs.data[i][j]->price; + } + + WFIFOSET(fd, 8 + ( clif->cs.item_count[i] * 6 )); + } +} +void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { + unsigned short limit = RFIFOW(fd, 4), i, j; + + /* no idea what data is on 6-10 */ + + for(i = 0; i < limit; i++) { + int qty = RFIFOL(fd, 14 + ( i * 10 )); + int id = RFIFOL(fd, 10 + ( i * 10 )); + short tab = RFIFOW(fd, 18 + ( i * 10 )); + enum CASH_SHOP_BUY_RESULT result = CSBR_UNKNOWN; + + if( tab < 0 || tab > CASHSHOP_TAB_MAX ) + continue; + + for( j = 0; j < clif->cs.item_count[tab]; j++ ) { + if( clif->cs.data[tab][j]->id == id ) + break; + } + if( j < clif->cs.item_count[tab] ) { + struct item_data *data; + if( sd->cashPoints < (clif->cs.data[tab][j]->price * qty) ) { + result = CSBR_SHORTTAGE_CASH; + } else if ( !( data = itemdb_exists(clif->cs.data[tab][j]->id) ) ) { + result = CSBR_UNKONWN_ITEM; + } else { + struct item item_tmp; + int k, get_count; + + get_count = qty; + + if (!itemdb_isstackable2(data)) + get_count = 1; + + pc_paycash(sd, clif->cs.data[tab][j]->price * qty, 0);/* kafra point support is missing */ + for (k = 0; k < qty; k += get_count) { + if (!pet_create_egg(sd, data->nameid)) { + memset(&item_tmp, 0, sizeof(item_tmp)); + item_tmp.nameid = data->nameid; + item_tmp.identify = 1; + + switch (pc_additem(sd, &item_tmp, get_count, LOG_TYPE_NPC)) { + case 0: + result = CSBR_SUCCESS; + break; + case 1: + result = CSBR_EACHITEM_OVERCOUNT; + break; + case 2: + result = CSBR_INVENTORY_WEIGHT; + break; + case 4: + result = CSBR_INVENTORY_ITEMCNT; + break; + case 5: + result = CSBR_EACHITEM_OVERCOUNT; + break; + case 7: + result = CSBR_RUNE_OVERCOUNT; + break; + } + + if( result != CSBR_SUCCESS ) + pc_getcash(sd, clif->cs.data[tab][j]->price * get_count, 0);/* kafra point support is missing */ + } + } + } + } else { + result = CSBR_UNKONWN_ITEM; + } + + WFIFOHEAD(fd, 16); + WFIFOW(fd, 0) = 0x849; + WFIFOL(fd, 2) = id; + WFIFOW(fd, 6) = result;/* result */ + WFIFOL(fd, 8) = sd->cashPoints;/* current cash point */ + WFIFOL(fd, 12) = 0;/* no idea (kafra cash?) */ + WFIFOSET(fd, 16); + + } +} + /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -16303,13 +16496,13 @@ int clif_parse(int fd) { int cmd, packet_len; TBL_PC* sd; int pnum; - + //TODO apply delays or disconnect based on packet throughput [FlavioJS] // Note: "click masters" can do 80+ clicks in 10 seconds - + for( pnum = 0; pnum < 3; ++pnum ) { // Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] -- This actually aids packet spammers, but stuff like /str+ gets slow without it [Ai4rei] // begin main client packet processing loop - + sd = (TBL_PC *)session[fd]->session_data; if (session[fd]->flag.eof) { if (sd) { @@ -16319,101 +16512,101 @@ int clif_parse(int fd) { sd->fd = 0; ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off (using @autotrade).\n", sd->status.name); } else - if (sd->state.active) { - // Player logout display [Valaris] - ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off.\n", sd->status.name); - clif->quitsave(fd, sd); - } else { - //Unusual logout (during log on/off/map-changer procedure) - ShowInfo("Player AID:%d/CID:%d logged off.\n", sd->status.account_id, sd->status.char_id); - map_quit(sd); - } + if (sd->state.active) { + // Player logout display [Valaris] + ShowInfo("Character '"CL_WHITE"%s"CL_RESET"' logged off.\n", sd->status.name); + clif->quitsave(fd, sd); + } else { + //Unusual logout (during log on/off/map-changer procedure) + ShowInfo("Player AID:%d/CID:%d logged off.\n", sd->status.account_id, sd->status.char_id); + map_quit(sd); + } } else { ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip2str(session[fd]->client_addr, NULL)); } do_close(fd); return 0; } - + if (RFIFOREST(fd) < 2) return 0; - + cmd = RFIFOW(fd,0); - + // filter out invalid / unsupported packets if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0) { ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", cmd, RFIFOREST(fd), fd); - #ifdef DUMP_INVALID_PACKET +#ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); - #endif +#endif set_eof(fd); return 0; } - + // determine real packet length packet_len = packet_db[cmd].len; if (packet_len == -1) { // variable-length packet if (RFIFOREST(fd) < 4) return 0; - + packet_len = RFIFOW(fd,2); if (packet_len < 4 || packet_len > 32768) { ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd); - #ifdef DUMP_INVALID_PACKET +#ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); - #endif +#endif set_eof(fd); return 0; } } if ((int)RFIFOREST(fd) < packet_len) return 0; // not enough data received to form the packet - + if( packet_db[cmd].func == clif->pDebug ) packet_db[cmd].func(fd, sd); else if( packet_db[cmd].func != NULL ) { if( !sd && packet_db[cmd].func != clif->pWantToConnection ) ; //Only valid packet when there is no session else - if( sd && sd->bl.prev == NULL && packet_db[cmd].func != clif->pLoadEndAck ) - ; //Only valid packet when player is not on a map - else - packet_db[cmd].func(fd, sd); + if( sd && sd->bl.prev == NULL && packet_db[cmd].func != clif->pLoadEndAck ) + ; //Only valid packet when player is not on a map + else + packet_db[cmd].func(fd, sd); } - #ifdef DUMP_UNKNOWN_PACKET +#ifdef DUMP_UNKNOWN_PACKET else { const char* packet_txt = "save/packet.txt"; FILE* fp; - + if( ( fp = fopen( packet_txt , "a" ) ) != NULL ) { if( sd ) { fprintf(fp, "Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); } else { fprintf(fp, "Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd); } - + WriteDump(fp, RFIFOP(fd,0), packet_len); fprintf(fp, "\n"); fclose(fp); } else { ShowError("Failed to write '%s'.\n", packet_txt); - + // Dump on console instead if( sd ) { ShowDebug("Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); } else { ShowDebug("Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd); } - + ShowDump(RFIFOP(fd,0), packet_len); } } - #endif - +#endif + RFIFOSKIP(fd, packet_len); - + }; // main loop end - + return 0; } @@ -16517,6 +16710,15 @@ void do_final_clif(void) { db_destroy(clif->channel_db); ers_destroy(clif->delay_clearunit_ers); + + for(i = 0; i < CASHSHOP_TAB_MAX; i++) { + int k; + for( k = 0; k < clif->cs.item_count[i]; k++ ) { + aFree(clif->cs.data[i][k]); + } + aFree(clif->cs.data[i]); + } + } void clif_defaults(void) { clif = &clif_s; @@ -16957,6 +17159,7 @@ void clif_defaults(void) { clif->chsys_left = clif_hercules_chsys_left; clif->chsys_delete = clif_hercules_chsys_delete; clif->chsys_mjoin = clif_hercules_chsys_mjoin; + clif->cashshop_load = clif_cashshop_db; /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -17157,4 +17360,6 @@ void clif_defaults(void) { /* RagExe Cash Shop [Ind/Hercules] */ clif->pCashShopOpen = clif_parse_CashShopOpen; clif->pCashShopClose = clif_parse_CashShopClose; + clif->pCashShopSchedule = clif_parse_CashShopSchedule; + clif->pCashShopBuy = clif_parse_CashShopBuy; } diff --git a/src/map/clif.h b/src/map/clif.h index 1fffb42e8..90915e1c9 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -338,6 +338,28 @@ enum hChSysChType { hChSys_ALLY = 3, }; +enum CASH_SHOP_TABS { + CASHSHOP_TAB_NEW = 0, + CASHSHOP_TAB_POPULAR = 1, + CASHSHOP_TAB_LIMITED = 2, + CASHSHOP_TAB_RENTAL = 3, + CASHSHOP_TAB_PERPETUITY = 4, + CASHSHOP_TAB_BUFF = 5, + CASHSHOP_TAB_RECOVERY = 6, + CASHSHOP_TAB_ETC = 7, + CASHSHOP_TAB_MAX, +}; + +enum CASH_SHOP_BUY_RESULT { + CSBR_SUCCESS = 0x0, + CSBR_SHORTTAGE_CASH = 0x2, + CSBR_UNKONWN_ITEM = 0x3, + CSBR_INVENTORY_WEIGHT = 0x4, + CSBR_INVENTORY_ITEMCNT = 0x5, + CSBR_RUNE_OVERCOUNT = 0x9, + CSBR_EACHITEM_OVERCOUNT = 0xa, + CSBR_UNKNOWN = 0xb, +}; /** * Structures @@ -372,6 +394,11 @@ struct hChSysCh { uint16 m; }; +struct hCSData { + unsigned short id; + unsigned int price; +}; + /** * Vars **/ @@ -391,6 +418,11 @@ struct clif_interface { DBMap* channel_db; /* for clif_clearunit_delayed */ struct eri *delay_clearunit_ers; + /* Cash Shop [Ind/Hercules] */ + struct { + struct hCSData **data[CASHSHOP_TAB_MAX]; + unsigned int item_count[CASHSHOP_TAB_MAX]; + } cs; /* core */ int (*init) (void); void (*final) (void); @@ -424,6 +456,7 @@ struct clif_interface { void (*addcards) (unsigned char* buf, struct item* item); void (*item_sub) (unsigned char *buf, int n, struct item *i, struct item_data *id, int equip); void (*getareachar_item) (struct map_session_data* sd,struct flooritem_data* fitem); + void (*cashshop_load) (void); /* unit-related */ void (*clearunit_single) (int id, clr_type type, int fd); void (*clearunit_area) (struct block_list* bl, clr_type type); @@ -1025,6 +1058,8 @@ struct clif_interface { /* RagExe Cash Shop [Ind/Hercules] */ void (*pCashShopOpen) (int fd, struct map_session_data *sd); void (*pCashShopClose) (int fd, struct map_session_data *sd); + void (*pCashShopSchedule) (int fd, struct map_session_data *sd); + void (*pCashShopBuy) (int fd, struct map_session_data *sd); } clif_s; struct clif_interface *clif; diff --git a/src/map/itemdb.c b/src/map/itemdb.c index a91946b2a..2b7d27c8a 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1430,6 +1430,7 @@ int do_init_itemdb(void) { itemdb_other = idb_alloc(DB_OPT_BASE); create_dummy_data(); //Dummy data item. itemdb_read(); + clif->cashshop_load(); return 0; } diff --git a/src/map/packets.h b/src/map/packets.h index 2f4ca6ca4..29181d392 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2030,7 +2030,6 @@ packet(0x020d,-1); //packet(0x0288,-1,clif->pcashshop_buy,4,8); packet(0x086F,26,clif->pPartyInvite2,2); packet(0x0888,19,clif->pWantToConnection,2,6,10,14,18); - packet(0x08c9,4); packet(0x088E,7,clif->pActionRequest,2,6); packet(0x089B,10,clif->pUseSkillToId,2,4,6); packet(0x0881,5,clif->pWalkToXY,2); @@ -2060,6 +2059,8 @@ packet(0x020d,-1); //packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); packet(0x0844,2,clif->pCashShopOpen,0);/* tell server cashshop window is being open */ packet(0x084a,2,clif->pCashShopClose,0);/* tell server cashshop window is being closed */ + packet(0x08c9,4,clif->pCashShopSchedule,0); + packet(0x0848,-1,clif->pCashShopBuy,0); #endif #endif /* _PACKETS_H_ */ -- cgit v1.2.3-70-g09d2 From d8f0ee4c476102066268e6376f6544b57dbf5b71 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Thu, 11 Apr 2013 15:40:35 -0300 Subject: Follow up 1a4d3fcf403745de60eb5d7648342cdfa1388af8 Improved Fix. Signed-off-by: shennetsind --- src/map/itemdb.c | 2 -- src/map/itemdb.h | 2 ++ src/map/script.c | 11 +++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src/map/itemdb.c') diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 2b7d27c8a..22ac031ee 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -20,8 +20,6 @@ static struct item_data* itemdb_array[MAX_ITEMDB]; static DBMap* itemdb_other;// int nameid -> struct item_data* -static struct item_group itemgroup_db[MAX_ITEMGROUP]; - struct item_data dummy_item; //This is the default dummy item used for non-existant items. [Skotlex] /** diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 06c95da8a..4c8847705 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -155,6 +155,8 @@ struct item_combo { bool isRef;/* whether this struct is a reference or the master */ }; +struct item_group itemgroup_db[MAX_ITEMGROUP]; + struct item_data* itemdb_searchname(const char *name); int itemdb_searchname_array(struct item_data** data, int size, const char *str); struct item_data* itemdb_load(int nameid); diff --git a/src/map/script.c b/src/map/script.c index 4f98fff09..182b04f86 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -17263,10 +17263,17 @@ BUILDIN_FUNC(getrandgroupitem) { ShowError("getrandgroupitem: qty is <= 0!\n"); return 1; } - if( (nameid = itemdb_searchrandomid(group)) == UNKNOWN_ITEM_ID ) { - return 1;/* itemdb_searchrandomid will already scream a error */ + + if(group < 1 || group >= MAX_ITEMGROUP) { + ShowError("getrandgroupitem: Invalid group id %d\n", group); + return 1; + } + if (!itemgroup_db[group].qty) { + ShowError("getrandgroupitem: group id %d is empty!\n", group); + return 1; } + nameid = itemdb_searchrandomid(group); memset(&item_tmp,0,sizeof(item_tmp)); item_tmp.nameid = nameid; -- cgit v1.2.3-70-g09d2 From 19b8cbb835e867febb597b34187f6bbca48cbe7b Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 22 Apr 2013 18:28:18 -0300 Subject: Hercules April 22 MEGA-ULTRA-LONG Patch~! http://hercules.ws/board/topic/470-hercules-april-22-patch/ Signed-off-by: shennetsind --- conf/atcommand.conf | 7 + conf/channels.conf | 22 +- conf/map-server.conf | 9 +- db/cashshop_db.conf | 55 + db/cashshop_db.txt | 45 - db/const.txt | 2 - db/pre-re/item_combo_db.txt | 14 +- db/pre-re/item_trade.txt | 4 +- db/pre-re/map_zone_db.conf | 34 +- db/pre-re/skill_db.txt | 1 - db/re/item_combo_db.txt | 14 +- db/re/item_trade.txt | 4 +- db/re/map_zone_db.conf | 34 +- db/re/skill_db.txt | 1 - doc/script_commands.txt | Bin 593352 -> 289408 bytes src/char/char.c | 28 +- src/config/const.h | 4 +- src/config/core.h | 16 +- src/map/Makefile.in | 4 +- src/map/atcommand.c | 4914 ++++++++++++------------ src/map/atcommand.h | 98 +- src/map/battle.c | 95 +- src/map/buyingstore.c | 31 +- src/map/buyingstore.h | 31 +- src/map/clif.c | 1217 +++--- src/map/clif.h | 22 +- src/map/guild.c | 8 +- src/map/intif.c | 2 +- src/map/irc-bot.c | 272 ++ src/map/irc-bot.h | 58 + src/map/itemdb.c | 31 +- src/map/itemdb.h | 1 + src/map/log.c | 608 ++- src/map/log.h | 84 +- src/map/mail.c | 2 +- src/map/map.c | 465 ++- src/map/map.h | 51 +- src/map/mob.c | 63 +- src/map/npc.c | 4 +- src/map/packets_struct.h | 324 ++ src/map/party.c | 2 +- src/map/pc.c | 82 +- src/map/pc.h | 11 +- src/map/pc_groups.c | 40 +- src/map/pc_groups.h | 5 +- src/map/pet.c | 4 +- src/map/script.c | 6873 ++++++++++++++++------------------ src/map/script.h | 4 - src/map/searchstore.c | 201 +- src/map/searchstore.h | 42 +- src/map/skill.c | 6 +- src/map/skill.h | 1 - src/map/sql/CMakeLists.txt | 4 +- src/map/status.c | 4 + src/map/trade.c | 4 +- src/map/unit.c | 4 +- src/map/vending.c | 183 +- src/map/vending.h | 31 +- vcproj-10/map-server.vcxproj | 2 + vcproj-10/map-server.vcxproj.filters | 6 + vcproj-12/map-server.vcxproj | 2 + vcproj-12/map-server.vcxproj.filters | 6 + vcproj-9/map-server.vcproj | 8 + 63 files changed, 8590 insertions(+), 7614 deletions(-) create mode 100644 db/cashshop_db.conf delete mode 100644 db/cashshop_db.txt create mode 100644 src/map/irc-bot.c create mode 100644 src/map/irc-bot.h (limited to 'src/map/itemdb.c') diff --git a/conf/atcommand.conf b/conf/atcommand.conf index 67af3b91f..6e35d5327 100644 --- a/conf/atcommand.conf +++ b/conf/atcommand.conf @@ -59,6 +59,13 @@ aliases: { channel: ["main"] } +/* list of commands that should not be logged at all */ +/* add as many commands as you like */ +nolog: { + iteminfo: 1 + mobinfo: 1 +} + /* Commands help file */ help: { @include "conf/help.txt" diff --git a/conf/channels.conf b/conf/channels.conf index b12d2da8b..3584fc2ea 100644 --- a/conf/channels.conf +++ b/conf/channels.conf @@ -1,3 +1,14 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//==================================================== +//= http://hercules.ws/board/topic/316-introducing-hercules-channel-system/ chsys: ( { /* default channels (available on boot) */ @@ -18,6 +29,7 @@ chsys: ( Cyan: "0x00b89d" Yellow: "0xffff90" Green: "0x28bf00" + Light_Green: "0x3dff98" Normal: "0x00ff00" /* as many colors as you like */ } @@ -33,7 +45,15 @@ chsys: ( ally_channel_enabled: true ally_channel_name: "ally" /* available as #ally */ ally_channel_color: "Green" - ally_channel_autojoin: true + ally_channel_autojoin: true /* will members autojoin to their respective #ally chats when they log-in? */ + /* "irc_channel" is a special channel connected to a specific chat room in any irc network */ + irc_channel_enabled: false + irc_channel_name: "irc" /* available as #irc */ + irc_channel_color: "Light_Green" + irc_channel_network: "irc.rizon.net:6665" /* network to connect to (:and port) */ + irc_channel_channel: "#Hercules" /* channel in the network above to join */ + irc_channel_nick: "Hercules_chSysBot" /* nick the bot will use */ + irc_channel_nick_pw: "" /* password to this nick (if any) to identify to nick server on the irc network */ } ) diff --git a/conf/map-server.conf b/conf/map-server.conf index b251e69ec..cac5421e6 100644 --- a/conf/map-server.conf +++ b/conf/map-server.conf @@ -89,18 +89,19 @@ minsave_time: 100 // Apart from the autosave_time, players will also get saved when involved // in the following (add as needed): -// 1: after every successful trade -// 2: after every vending transaction -// 4: after closing storage/guild storage. +// 1: After every successful trade +// 2: After every vending transaction +// 4: After closing storage/guild storage. // 8: After hatching/returning to egg a pet. // 16: After successfully sending a mail with attachment // 32: After successfully submitting an item for auction // 64: After successfully get/delete/complete a quest +// 128: After every buying store transaction // NOTE: These settings decrease the chance of dupes/lost items when there's a // server crash at the expense of increasing the map/char server lag. If your // server rarely crashes, but experiences interserver lag, you may want to set // these off. -save_settings: 127 +save_settings: 255 // Message of the day file, when a character logs on, this message is displayed. motd_txt: conf/motd.txt diff --git a/db/cashshop_db.conf b/db/cashshop_db.conf new file mode 100644 index 000000000..381d898e0 --- /dev/null +++ b/db/cashshop_db.conf @@ -0,0 +1,55 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//==================================================== +//= http://hercules.ws/board/topic/367-introducing-cash-shop-support/ + +cash_shop: ( +{ + cat_0: { //New + Apple:100 + ID531:250 + } + + cat_1: { //Popular + ID513:100 + Banana_Juice:250 + } + + cat_2: { //Limited + Grape:100 + ID533:250 + } + + cat_3: { //Rental + ID515:100 + Carrot_Juice:250 + } + + cat_4: { //Permanent + Green_Herb:100 + ID510:250 + } + + cat_5: { //Scroll + ID501:100 + ID502:250 + } + + cat_6: { //Usable + White_Potion:150 + Blue_Potion:500 + } + + cat_7: { //Other + ID909:400 + ID907:500 + } +} +) \ No newline at end of file diff --git a/db/cashshop_db.txt b/db/cashshop_db.txt deleted file mode 100644 index fc6a803c7..000000000 --- a/db/cashshop_db.txt +++ /dev/null @@ -1,45 +0,0 @@ -// Hercules Cash Shop Database -// Format: -// Tab ID or Tab Name, ItemID or Item Name, Price -// -// Tabs: -// 0 = New -// 1 = Popular -// 2 = Limited -// 3 = Rental -// 4 = Permanent -// 5 = Scroll -// 6 = Usable -// 7 = Other - -//New -New,Apple,100 -0,531,250 - -//Popular -1,513,100 -Popular,Banana_Juice,250 - -//Limited -2,Grape,100 -Limited,533,250 - -//Rental -Rental,515,100 -3,Carrot_Juice,250 - -//Permanent -4,Green_Herb,100 -Permanent,510,250 - -//Scroll -5,501,100 -5,502,250 - -//Usable -usable,White_Potion,150 -usable,Blue_Potion,500 - -//Other -7,909,400 -7,907,500 \ No newline at end of file diff --git a/db/const.txt b/db/const.txt index d3d5991ab..ec051c4b0 100644 --- a/db/const.txt +++ b/db/const.txt @@ -333,8 +333,6 @@ mf_snow 16 mf_fog 17 mf_sakura 18 mf_leaves 19 -mf_rain 20 -mf_nogo 22 mf_clouds 23 mf_clouds2 24 mf_fireworks 25 diff --git a/db/pre-re/item_combo_db.txt b/db/pre-re/item_combo_db.txt index c1eb3c039..f745d25b7 100644 --- a/db/pre-re/item_combo_db.txt +++ b/db/pre-re/item_combo_db.txt @@ -9,10 +9,10 @@ 1421:2133,{ bonus2 bAddRace,RC_NonBoss,4; bonus2 bAddRace,RC_Boss,4; bonus bDef,2; } 1422:2133,{ bonus2 bAddRace,RC_NonBoss,4; bonus2 bAddRace,RC_Boss,4; bonus bDef,2; } 1428:2115,{ bonus3 bAutoSpellWhenHit,"HP_ASSUMPTIO",2,5; } -1472:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getrefine(); } -1472:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getrefine(); } -1473:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getrefine(); } -1473:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getrefine(); } +1472:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getequiprefinerycnt(EQI_HAND_R); } +1472:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getequiprefinerycnt(EQI_HAND_R); } +1473:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getequiprefinerycnt(EQI_HAND_R); } +1473:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bCastrate,-getequiprefinerycnt(EQI_HAND_R); } 1474:2527,{ bonus2 bAddRace,RC_Dragon,5; } 1477:2700,{ bonus2 bResEff,Eff_Confusion,9500; } 1479:2700,{ bonus2 bResEff,Eff_Confusion,9500; } @@ -23,11 +23,11 @@ 1573:2716:2717,{ bonus bInt,5; bonus bMaxHP,700; bonus bAspdRate,5; } 1615:18539,{ bonus bMatk,10*getequiprefinerycnt(EQI_HAND_R); bonus bCastRate,-10; } 1616:2515,{ bonus bSpeedRate,25; } -1618:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getrefine()*3; } +1618:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getequiprefinerycnt(EQI_HAND_R)*3; } 1618:2535,{ bonus bMatkRate,5; bonus2 bSubEle,Ele_Neutral,25; } -1620:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getrefine()*3; } +1620:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getequiprefinerycnt(EQI_HAND_R)*3; } 1620:2535,{ bonus bMatkRate,5; bonus2 bSubEle,Ele_Neutral,25; } -1629:5045,{ bonus bDex,2; bonus bInt,2; bonus bSPrecovRate,5; bonus bMatkRate,getrefine(); } +1629:5045,{ bonus bDex,2; bonus bInt,2; bonus bSPrecovRate,5; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R); } 1631:2129,{ bonus2 bSkillAtk,"PR_MAGNUS",20; bonus3 bAutoSpellWhenHit,"PR_TURNUNDEAD",1,20; } 1636:18539,{ bonus bMatk,10*getequiprefinerycnt(EQI_HAND_R); bonus bCastRate,-10; } 1723:2718,{ bonus bDex,1; bonus bMaxSP,50; bonus bSPrecovRate,10; } diff --git a/db/pre-re/item_trade.txt b/db/pre-re/item_trade.txt index b5fedbd62..84b0220f5 100644 --- a/db/pre-re/item_trade.txt +++ b/db/pre-re/item_trade.txt @@ -1,6 +1,6 @@ //Item Trading Restrictions File //Specify here special rules for item trading. -//Item ID, TradeMask, GM-Level Override +//Item ID, TradeMask, Group-Level Override //Trading mask values: //1:Item can't be droped //2:Item can't be traded (nor vended) @@ -13,7 +13,7 @@ //256:Item can't be auctioned //Example: //1161,67,50 //Balmung: No drop, No trade, No Guild Store (1+2+64 =67), -//only GMs of GM-level 50 and up can override the setting. +//only groups of group-level 50 and up can override the setting. // Wedding Related items 2634,507,100 // Wedding Ring diff --git a/db/pre-re/map_zone_db.conf b/db/pre-re/map_zone_db.conf index 36689ac57..6fb18084b 100644 --- a/db/pre-re/map_zone_db.conf +++ b/db/pre-re/map_zone_db.conf @@ -16,10 +16,41 @@ //= maps can be linked to a specific zone through the zone mapflag //= 'mapflagzone' //== available types for 'disabled_skills': -//= PLAYER, HOMUN, MERCENARY, MONSTER, ALL and NONE +//= PLAYER, HOMUN, MERCENARY, MONSTER, PET, ELEMENTAL, ALL and NONE //== More on //= http://hercules.ws/board/topic/302-introducing-hercules-map-zone-database/ +//= (TODO: replace with wiki link and detail the wiki page in a decent format ^) zones: ( +{ + /* All zone is a dynamic (very special) zone that is forcebly inherited by ALL maps automatically */ + name: "All" /* changing this name requires MAP_ZONE_ALL_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + //both examples below disable napalm beat (id 11) to players + //MG_NAPALMBEAT: "PLAYER" + //ID11: "PLAYER" + } + + disabled_items: { + //Both examples below disable apple (id 501) + //Apple: true + //ID501: true + } + + mapflags: ( ) + + /* "command:min-group-lv-to-override" e.g. "heal: 70" */ + disabled_commands: { + //Example Below makes @heal be used in maps within this zone only by those group lv 70 and above + //heal: 70 + } + skill_damage_cap: { + //Exemple Below caps firebolt damage in maps within this zone to a maximum 50 damage, + // (depends on HMAP_ZONE_DAMAGE_CAP_TYPE in src/config/core.h) + // to players and monsters. + //MG_FIREBOLT: (50,"PLAYER | MONSTER") + } +}, { /* Normal zone is applied to all maps that are not pkable (where players cant fight each other) */ /* However, it wont be applied to maps with its own zones (specified thru mapflag) */ @@ -37,6 +68,7 @@ zones: ( } mapflags: ( ) + }, { /* PvP zone is applied to all maps with a pvp mapflag */ diff --git a/db/pre-re/skill_db.txt b/db/pre-re/skill_db.txt index 806bb4d11..df52ec439 100644 --- a/db/pre-re/skill_db.txt +++ b/db/pre-re/skill_db.txt @@ -38,7 +38,6 @@ // 0x1000- disable usage on enemies (for non-offensive skills). // 0x2000- skill ignores land protector (e.g. arrow shower) // 0x4000- chorus skill -// 0x8000- skill wont be passed to clones // 13 maxcount: max amount of skill instances to place on the ground when // player_land_skill_limit/monster_land_skill_limit is enabled. For skills // that attack using a path, this is the path length to be used. diff --git a/db/re/item_combo_db.txt b/db/re/item_combo_db.txt index d921689c3..26b955d9b 100644 --- a/db/re/item_combo_db.txt +++ b/db/re/item_combo_db.txt @@ -12,10 +12,10 @@ 1422:2133,{ bonus2 bAddRace,RC_NonBoss,4; bonus2 bAddRace,RC_Boss,4; bonus bDef,2; } 1428:2115,{ bonus3 bAutoSpellWhenHit,"HP_ASSUMPTIO",2,5; } 1433:2153,{ bonus2 bSkillAtk,"CR_GRANDCROSS",10; bonus2 bSkillAtk,"LG_RAYOFGENESIS",10; } -1472:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getrefine(); } -1472:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getrefine(); } -1473:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getrefine(); } -1473:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getrefine(); } +1472:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getequiprefinerycnt(EQI_HAND_R); } +1472:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getequiprefinerycnt(EQI_HAND_R); } +1473:2677,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getequiprefinerycnt(EQI_HAND_R); } +1473:2711,{ bonus bMatkRate,6; bonus bDex,2; bonus bVariableCastrate,-getequiprefinerycnt(EQI_HAND_R); } 1474:2527,{ bonus2 bAddRace,RC_Dragon,5; } 1477:2700,{ bonus2 bResEff,Eff_Confusion,9500; } 1479:2700,{ bonus2 bResEff,Eff_Confusion,9500; } @@ -26,11 +26,11 @@ 1573:2716:2717,{ bonus bInt,5; bonus bMaxHP,700; bonus bAspdRate,5; } 1615:18539,{ bonus bMatk,10*getequiprefinerycnt(EQI_HAND_R); bonus bVariableCastrate,-10; } 1616:2515,{ bonus bSpeedRate,25; } -1618:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getrefine()*3; } +1618:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getequiprefinerycnt(EQI_HAND_R)*3; } 1618:2535,{ bonus bMatkRate,5; bonus2 bSubEle,Ele_Neutral,25; } -1620:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getrefine()*3; } +1620:2509,{ bonus bMaxHP,300; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R)-5; bonus2 bSubEle,Ele_Neutral,getequiprefinerycnt(EQI_HAND_R)*3; } 1620:2535,{ bonus bMatkRate,5; bonus2 bSubEle,Ele_Neutral,25; } -1629:5045,{ bonus bDex,2; bonus bInt,2; bonus bSPrecovRate,5; bonus bMatkRate,getrefine(); } +1629:5045,{ bonus bDex,2; bonus bInt,2; bonus bSPrecovRate,5; bonus bMatkRate,getequiprefinerycnt(EQI_HAND_R); } 1631:2129,{ bonus2 bSkillAtk,"PR_MAGNUS",20; bonus3 bAutoSpellWhenHit,"PR_TURNUNDEAD",1,20; } 1636:18539,{ bonus bMatk,10*getequiprefinerycnt(EQI_HAND_R); bonus bVariableCastrate,-10; } 1657:2471:2569:15029,{ bonus bHealPower,25; } diff --git a/db/re/item_trade.txt b/db/re/item_trade.txt index 9ad2a8c65..c6faa991b 100644 --- a/db/re/item_trade.txt +++ b/db/re/item_trade.txt @@ -1,6 +1,6 @@ //Item Trading Restrictions File //Specify here special rules for item trading. -//Item ID, TradeMask, GM-Level Override +//Item ID, TradeMask, Group-Level Override //Trading mask values: //1:Item can't be droped //2:Item can't be traded (nor vended) @@ -13,7 +13,7 @@ //256:Item can't be auctioned //Example: //1161,67,50 //Balmung: No drop, No trade, No Guild Store (1+2+64 =67), -//only GMs of GM-level 50 and up can override the setting. +//only groups of group-level 50 and up can override the setting. // Wedding Related items 2634,507,100 // Wedding Ring diff --git a/db/re/map_zone_db.conf b/db/re/map_zone_db.conf index 36689ac57..6fb18084b 100644 --- a/db/re/map_zone_db.conf +++ b/db/re/map_zone_db.conf @@ -16,10 +16,41 @@ //= maps can be linked to a specific zone through the zone mapflag //= 'mapflagzone' //== available types for 'disabled_skills': -//= PLAYER, HOMUN, MERCENARY, MONSTER, ALL and NONE +//= PLAYER, HOMUN, MERCENARY, MONSTER, PET, ELEMENTAL, ALL and NONE //== More on //= http://hercules.ws/board/topic/302-introducing-hercules-map-zone-database/ +//= (TODO: replace with wiki link and detail the wiki page in a decent format ^) zones: ( +{ + /* All zone is a dynamic (very special) zone that is forcebly inherited by ALL maps automatically */ + name: "All" /* changing this name requires MAP_ZONE_ALL_NAME to also be changed in src/map/map.h file */ + + disabled_skills: { + //both examples below disable napalm beat (id 11) to players + //MG_NAPALMBEAT: "PLAYER" + //ID11: "PLAYER" + } + + disabled_items: { + //Both examples below disable apple (id 501) + //Apple: true + //ID501: true + } + + mapflags: ( ) + + /* "command:min-group-lv-to-override" e.g. "heal: 70" */ + disabled_commands: { + //Example Below makes @heal be used in maps within this zone only by those group lv 70 and above + //heal: 70 + } + skill_damage_cap: { + //Exemple Below caps firebolt damage in maps within this zone to a maximum 50 damage, + // (depends on HMAP_ZONE_DAMAGE_CAP_TYPE in src/config/core.h) + // to players and monsters. + //MG_FIREBOLT: (50,"PLAYER | MONSTER") + } +}, { /* Normal zone is applied to all maps that are not pkable (where players cant fight each other) */ /* However, it wont be applied to maps with its own zones (specified thru mapflag) */ @@ -37,6 +68,7 @@ zones: ( } mapflags: ( ) + }, { /* PvP zone is applied to all maps with a pvp mapflag */ diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index ed4671c00..0bb63d7e9 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -38,7 +38,6 @@ // 0x1000- disable usage on enemies (for non-offensive skills). // 0x2000- skill ignores land protector (e.g. arrow shower) // 0x4000- chorus skill -// 0x8000- skill wont be passed to clones // 13 maxcount: max amount of skill instances to place on the ground when // player_land_skill_limit/monster_land_skill_limit is enabled. For skills // that attack using a path, this is the path length to be used. diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 38c442f74..aa3112d62 100644 Binary files a/doc/script_commands.txt and b/doc/script_commands.txt differ diff --git a/src/char/char.c b/src/char/char.c index ce0d067a7..109f74c36 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1059,13 +1059,6 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) j += mmo_char_tobuf(WBUFP(buf, j), &p); } -#if PACKETVER >= 20130000 - /* for some reason the client doesn't like "3" characters (yes...3) we gotta send a fake one or it wont display any =_= */ - if( j == 432 ){/* we just duplicate the last visually the client will say 4 chars instead of 3 though >_> */ - j += mmo_char_tobuf(WBUFP(buf, j), &p); - } -#endif - memset(sd->new_name,0,sizeof(sd->new_name)); SqlStmt_Free(stmt); @@ -1888,7 +1881,7 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) return 106+offset; } - + int mmo_char_send006b(int fd, struct char_session_data* sd); //---------------------------------------- // [Ind/Hercules] notify client about charselect window data //---------------------------------------- @@ -1906,10 +1899,7 @@ void mmo_char_send082d(int fd, struct char_session_data* sd) { WFIFOB(fd,8) = sd->char_slots; memset(WFIFOP(fd,9), 0, 20); // unused bytes WFIFOSET(fd,29); - WFIFOHEAD(fd, 6); - WFIFOW(fd,0) = 0x9a0; - WFIFOL(fd,2) = 1; - WFIFOSET(fd, 6); + mmo_char_send006b(fd,sd); } //---------------------------------------- @@ -4342,20 +4332,6 @@ int parse_char(int fd) RFIFOSKIP(fd, 8); } break; - - /* [Ind/Hercules] after hours reading over and over Shakto's network report, finally found this little ***hole */ - case 0x9a1: - FIFOSD_CHECK(2); - { - int j = 4; - RFIFOSKIP(fd, 2); - WFIFOHEAD(fd,j + (MAX_CHARS*MAX_CHAR_BUF)); - WFIFOW(fd,0) = 0x99d; - j+=mmo_chars_fromsql(sd, WFIFOP(fd,j)); - WFIFOW(fd,2) = j; - WFIFOSET(fd,j); - } - break; // unknown packet received default: diff --git a/src/config/const.h b/src/config/const.h index 825824c62..53f24da6f 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -53,9 +53,9 @@ /* pointer size fix which fixes several gcc warnings */ #ifdef __64BIT__ - #define __64BPRTSIZE(y) (intptr)y + #define __64BPTRSIZE(y) (intptr)y #else - #define __64BPRTSIZE(y) y + #define __64BPTRSIZE(y) y #endif /* ATCMD_FUNC(mobinfo) HIT and FLEE calculations */ diff --git a/src/config/core.h b/src/config/core.h index c9b1463de..bec6cb507 100644 --- a/src/config/core.h +++ b/src/config/core.h @@ -34,11 +34,6 @@ /// We kindly ask you to consider keeping it enabled, it helps us improve Hercules. //#define STATS_OPT_OUT -/// uncomment to enable query_sql script command and mysql logs to function on it's own thread -/// be aware this feature is under tests and you should use at your own risk, we however -/// welcome any feedback you may have regarding this feature, please send us all bug reports. -//#define BETA_THREAD_TEST - /// Uncomment to enable the Cell Stack Limit mod. /// It's only config is the battle_config cell_stack_limit. /// Only chars affected are those defined in BL_CHAR (mobs and players currently) @@ -51,6 +46,17 @@ /// - but is not the official behaviour. //#define CIRCULAR_AREA +//This is the distance at which @autoloot works, +//if the item drops farther from the player than this, +//it will not be autolooted. [Skotlex] +//Note: The range is unlimited unless this define is set. +//#define AUTOLOOT_DISTANCE AREA_SIZE + +/// Uncomment to switch the way map zones' "skill_damage_cap" functions. +/// When commented the cap takes place before modifiers, as to have them be useful. +/// When uncommented the cap takes place after modifiers. +//#define HMAP_ZONE_DAMAGE_CAP_TYPE + /// Uncomment to enable Non Stackable items unique ID /// By enabling it, the system will create an unique id for each new non stackable item created //#define NSI_UNIQUE_ID diff --git a/src/map/Makefile.in b/src/map/Makefile.in index 78f5c42c4..bb99b6a05 100644 --- a/src/map/Makefile.in +++ b/src/map/Makefile.in @@ -17,7 +17,7 @@ MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \ storage.o skill.o atcommand.o battle.o battleground.o \ intif.o trade.o party.o vending.o guild.o pet.o \ log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \ - buyingstore.o searchstore.o duel.o pc_groups.o elemental.o + buyingstore.o searchstore.o duel.o pc_groups.o elemental.o irc-bot.o MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \ obj_sql/mapreg_sql.o MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \ @@ -27,7 +27,7 @@ MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \ log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \ buyingstore.h searchstore.h duel.h pc_groups.h \ ../config/core.h ../config/renewal.h ../config/secure.h ../config/const.h \ - ../config/classes/general.h elemental.h packets.h packets_struct.h + ../config/classes/general.h elemental.h packets.h packets_struct.h irc-bot.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 0fc803198..e9c8c5fba 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/mmo.h" @@ -43,6 +44,7 @@ #include "unit.h" #include "mapreg.h" #include "quest.h" +#include "searchstore.h" #include #include @@ -50,36 +52,11 @@ #include -#define ATCOMMAND_LENGTH 50 -#define ACMD_FUNC(x) static int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message) -#define MAX_MSG 1500 - - -typedef struct AtCommandInfo AtCommandInfo; -typedef struct AliasInfo AliasInfo; - -int atcmd_binding_count = 0; - -struct AtCommandInfo { - char command[ATCOMMAND_LENGTH]; - AtCommandFunc func; - char* at_groups;/* quick @commands "can-use" lookup */ - char* char_groups;/* quick @charcommands "can-use" lookup */ -}; - -struct AliasInfo { - AtCommandInfo *command; - char alias[ATCOMMAND_LENGTH]; -}; - - -char atcommand_symbol = '@'; // first char of the commands -char charcommand_symbol = '#'; +#define ACMD(x) static bool atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info) static char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) static DBMap* atcommand_db = NULL; //name -> AtCommandInfo static DBMap* atcommand_alias_db = NULL; //alias -> AtCommandInfo -static config_t atcommand_config; static char atcmd_output[CHAT_SIZE_MAX]; static char atcmd_player_name[NAME_LENGTH]; @@ -92,12 +69,12 @@ static void atcommand_get_suggestions(struct map_session_data* sd, const char *n struct atcmd_binding_data* get_atcommandbind_byname(const char* name) { int i = 0; - if( *name == atcommand_symbol || *name == charcommand_symbol ) + if( *name == atcommand->at_symbol || *name == atcommand->char_symbol ) name++; // for backwards compatibility - ARR_FIND( 0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command, name) == 0 ); + ARR_FIND( 0, atcommand->binding_count, i, strcmp(atcommand->binding[i]->command, name) == 0 ); - return ( i < atcmd_binding_count ) ? atcmd_binding[i] : NULL; + return ( i < atcommand->binding_count ) ? atcommand->binding[i] : NULL; } //----------------------------------------------------------- @@ -169,107 +146,79 @@ void do_final_msg(void) /** * retrieves the help string associated with a given command. - * - * @param name the name of the command to retrieve help information for - * @return the string associated with the command, or NULL */ -static const char* atcommand_help_string(const char* command) -{ - const char* str = NULL; - config_setting_t* info; - - if( *command == atcommand_symbol || *command == charcommand_symbol ) - {// remove the prefix symbol for the raw name of the command - command ++; - } - - // convert alias to the real command name - command = atcommand_checkalias(command); - - // attept to find the first default help command - info = config_lookup(&atcommand_config, "help"); - - if( info == NULL ) - {// failed to find the help property in the configuration file - return NULL; - } - - if( !config_setting_lookup_string( info, command, &str ) ) - {// failed to find the matching help string - return NULL; - } - - // push the result from the method - return str; +static inline const char* atcommand_help_string(AtCommandInfo *info) { + return info->help; } + /*========================================== * @send (used for testing packet sends from the client) *------------------------------------------*/ -ACMD_FUNC(send) +ACMD(send) { int len=0,off,end,type; long num; - + // read message type as hex number (without the 0x) if(!message || !*message || - !((sscanf(message, "len %x", &type)==1 && (len=1)) - || sscanf(message, "%x", &type)==1) ) + !((sscanf(message, "len %x", &type)==1 && (len=1)) + || sscanf(message, "%x", &type)==1) ) { int i; for (i = 900; i <= 903; ++i) clif->message(fd, msg_txt(i)); - return -1; + return false; } - + #define PARSE_ERROR(error,p) \ - {\ - clif->message(fd, (error));\ - sprintf(atcmd_output, ">%s", (p));\ - clif->message(fd, atcmd_output);\ - } -//define PARSE_ERROR - +{\ +clif->message(fd, (error));\ +sprintf(atcmd_output, ">%s", (p));\ +clif->message(fd, atcmd_output);\ +} + //define PARSE_ERROR + #define CHECK_EOS(p) \ - if(*(p) == 0){\ - clif->message(fd, "Unexpected end of string");\ - return -1;\ - } -//define CHECK_EOS - +if(*(p) == 0){\ +clif->message(fd, "Unexpected end of string");\ +return false;\ +} + //define CHECK_EOS + #define SKIP_VALUE(p) \ - {\ - while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\ - while(*(p) && ISSPACE(*(p))) ++(p); /* space */\ - } -//define SKIP_VALUE - +{\ +while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\ +while(*(p) && ISSPACE(*(p))) ++(p); /* space */\ +} + //define SKIP_VALUE + #define GET_VALUE(p,num) \ - {\ - if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\ - PARSE_ERROR("Invalid number in:",(p));\ - return -1;\ - }\ - } -//define GET_VALUE - +{\ +if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\ +PARSE_ERROR("Invalid number in:",(p));\ +return false;\ +}\ +} + //define GET_VALUE + if (type > 0 && type < MAX_PACKET_DB) { - + if(len) {// show packet length sprintf(atcmd_output, msg_txt(904), type, packet_db[type].len); // Packet 0x%x length: %d clif->message(fd, atcmd_output); - return 0; + return true; } - + len=packet_db[type].len; off=2; if(len == 0) {// unknown packet - ERROR sprintf(atcmd_output, msg_txt(905), type); // Unknown packet: 0x%x clif->message(fd, atcmd_output); - return -1; + return false; } else if(len == -1) {// dynamic packet len=SHRT_MAX-4; // maximum length @@ -277,7 +226,7 @@ ACMD_FUNC(send) } WFIFOHEAD(fd, len); WFIFOW(fd,0)=TOW(type); - + // parse packet contents SKIP_VALUE(message); while(*message != 0 && off < len){ @@ -316,12 +265,12 @@ ACMD_FUNC(send) {// find start of string if(*message == 0 || ISSPACE(*message)){ PARSE_ERROR(msg_txt(906),message); // Not a string: - return -1; + return false; } ++message; } } - + // parse string ++message; CHECK_EOS(message); @@ -346,7 +295,7 @@ ACMD_FUNC(send) CHECK_EOS(message); if(!ISXDIGIT(*message)){ PARSE_ERROR(msg_txt(907),message); // Not a hexadecimal digit: - return -1; + return false; } num=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10); if(ISXDIGIT(*message)){ @@ -399,7 +348,7 @@ ACMD_FUNC(send) ++message; CHECK_EOS(message); } - + // terminate the string if(off < end) {// fill the rest with 0's @@ -409,11 +358,11 @@ ACMD_FUNC(send) } else {// unknown PARSE_ERROR(msg_txt(908),message); // Unknown type of value in: - return -1; + return false; } SKIP_VALUE(message); } - + if(packet_db[type].len == -1) {// send dynamic packet WFIFOW(fd,2)=TOW(off); WFIFOSET(fd,off); @@ -424,11 +373,11 @@ ACMD_FUNC(send) } } else { clif->message(fd, msg_txt(259)); // Invalid packet - return -1; + return false; } sprintf (atcmd_output, msg_txt(258), type, type); // Sent packet 0x%x (%d) clif->message(fd, atcmd_output); - return 0; + return true; #undef PARSE_ERROR #undef CHECK_EOS #undef SKIP_VALUE @@ -438,34 +387,34 @@ ACMD_FUNC(send) /*========================================== * @rura, @warp, @mapmove *------------------------------------------*/ -ACMD_FUNC(mapmove) +ACMD(mapmove) { char map_name[MAP_NAME_LENGTH_EXT]; unsigned short mapindex; short x = 0, y = 0; int16 m = -1; - + nullpo_retr(-1, sd); - + memset(map_name, '\0', sizeof(map_name)); - + if (!message || !*message || (sscanf(message, "%15s %hd %hd", map_name, &x, &y) < 3 && sscanf(message, "%15[^,],%hd,%hd", map_name, &x, &y) < 1)) { - + clif->message(fd, msg_txt(909)); // Please enter a map (usage: @warp/@rura/@mapmove ). - return -1; - } - + return false; + } + mapindex = mapindex_name2id(map_name); if (mapindex) m = map_mapindex2mapid(mapindex); - + if (!mapindex) { // m < 0 means on different server! [Kevin] clif->message(fd, msg_txt(1)); // Map not found. - return -1; + return false; } - + if ((x || y) && map_getcell(m, x, y, CELL_CHKNOPASS)) { //This is to prevent the pc_setpos call from printing an error. clif->message(fd, msg_txt(2)); @@ -474,138 +423,138 @@ ACMD_FUNC(mapmove) } if (map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(247)); - return -1; + return false; } if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); - return -1; + return false; } if (pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) != 0) { clif->message(fd, msg_txt(1)); // Map not found. - return -1; + return false; } - + clif->message(fd, msg_txt(0)); // Warped. - return 0; + return true; } /*========================================== * Displays where a character is. Corrected version by Silent. [Skotlex] *------------------------------------------*/ -ACMD_FUNC(where) +ACMD(where) { struct map_session_data* pl_sd; - + nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof atcmd_player_name); - + if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { clif->message(fd, msg_txt(910)); // Please enter a player name (usage: @where ). - return -1; + return false; } - + pl_sd = map_nick2sd(atcmd_player_name); if (pl_sd == NULL || strncmp(pl_sd->status.name, atcmd_player_name, NAME_LENGTH) != 0 || (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > pc_get_group_level(sd) && !pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID)) - ) { + ) { clif->message(fd, msg_txt(3)); // Character not found. - return -1; + return false; } - + snprintf(atcmd_output, sizeof atcmd_output, "%s %s %d %d", pl_sd->status.name, mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); clif->message(fd, atcmd_output); - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(jumpto) +ACMD(jumpto) { struct map_session_data *pl_sd = NULL; - + nullpo_retr(-1, sd); - + if (!message || !*message) { clif->message(fd, msg_txt(911)); // Please enter a player name (usage: @jumpto/@warpto/@goto ). - return -1; + return false; } - + if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_txt(3)); // Character not found. - return -1; + return false; } - + if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(247)); // You are not authorized to warp to this map. - return -1; + return false; } - + if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map. - return -1; + return false; } - + if( pc_isdead(sd) ) { clif->message(fd, msg_txt(664)); - return -1; + return false; } - + pc_setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT); sprintf(atcmd_output, msg_txt(4), pl_sd->status.name); // Jumped to %s clif->message(fd, atcmd_output); - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(jump) +ACMD(jump) { short x = 0, y = 0; - + nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + sscanf(message, "%hd %hd", &x, &y); - + if (map[sd->bl.m].flag.noteleport && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map. - return -1; + return false; } - + if( pc_isdead(sd) ) { clif->message(fd, msg_txt(664)); - return -1; + return false; } - + if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS)) { //This is to prevent the pc_setpos call from printing an error. clif->message(fd, msg_txt(2)); if (!map_search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1)) x = y = 0; //Invalid cell, use random spot. } - + pc_setpos(sd, sd->mapindex, x, y, CLR_TELEPORT); sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d clif->message(fd, atcmd_output); - return 0; + return true; } /*========================================== * Display list of online characters with * various info. *------------------------------------------*/ -ACMD_FUNC(who) +ACMD(who) { struct map_session_data *pl_sd = NULL; struct s_mapiterator *iter = NULL; @@ -621,24 +570,24 @@ ACMD_FUNC(who) */ int display_type = 1; int map_id = -1; - + nullpo_retr(-1, sd); - + if (strstr(command, "map") != NULL) { if (sscanf(message, "%15s %23s", map_name, player_name) < 1 || (map_id = map_mapname2mapid(map_name)) < 0) map_id = sd->bl.m; } else { sscanf(message, "%23s", player_name); } - + if (strstr(command, "2") != NULL) display_type = 2; else if (strstr(command, "3") != NULL) display_type = 3; - + level = pc_get_group_level(sd); StringBuf_Init(&buf); - + iter = mapit_getallusers(); for (pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter)) { if (!((pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) || (pl_sd->sc.option & OPTION_INVISIBLE)) && pc_get_group_level(pl_sd) > level)) { // you can look only lower or same level @@ -651,7 +600,7 @@ ACMD_FUNC(who) if (pc_get_group_id(pl_sd) > 0) // Player title, if exists StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) " StringBuf_Printf(&buf, msg_txt(347), pl_sd->status.base_level, pl_sd->status.job_level, - job_name(pl_sd->status.class_)); // "| Lv:%d/%d | Job: %s" + job_name(pl_sd->status.class_)); // "| Lv:%d/%d | Job: %s" break; } case 3: { @@ -666,7 +615,7 @@ ACMD_FUNC(who) default: { struct party_data *p = party_search(pl_sd->status.party_id); struct guild *g = pl_sd->guild; - + StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s " if (pc_get_group_id(pl_sd) > 0) // Player title, if exists StringBuf_Printf(&buf, msg_txt(344), pc_group_id2name(pc_get_group_id(pl_sd))); // "(%s) " @@ -683,7 +632,7 @@ ACMD_FUNC(who) } } mapit_free(iter); - + if (map_id < 0) { if (count == 0) StringBuf_Printf(&buf, msg_txt(28)); // No player found. @@ -701,13 +650,13 @@ ACMD_FUNC(who) } clif->message(fd, StringBuf_Value(&buf)); StringBuf_Destroy(&buf); - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(whogm) +ACMD(whogm) { struct map_session_data* pl_sd; struct s_mapiterator* iter; @@ -717,28 +666,28 @@ ACMD_FUNC(whogm) char player_name[NAME_LENGTH]; struct guild *g; struct party_data *p; - + nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(match_text, '\0', sizeof(match_text)); memset(player_name, '\0', sizeof(player_name)); - + if (sscanf(message, "%199[^\n]", match_text) < 1) strcpy(match_text, ""); for (j = 0; match_text[j]; j++) match_text[j] = TOLOWER(match_text[j]); - + count = 0; level = pc_get_group_level(sd); - + iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) { pl_level = pc_get_group_level(pl_sd); if (!pl_level) continue; - + if (match_text[0]) { memcpy(player_name, pl_sd->status.name, NAME_LENGTH); @@ -756,28 +705,28 @@ ACMD_FUNC(whogm) count++; continue; } - + sprintf(atcmd_output, msg_txt(914), // Name: %s (GM:%d) | Location: %s %d %d - pl_sd->status.name, pl_level, - mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); + pl_sd->status.name, pl_level, + mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); clif->message(fd, atcmd_output); - + sprintf(atcmd_output, msg_txt(915), // BLvl: %d | Job: %s (Lvl: %d) - pl_sd->status.base_level, - job_name(pl_sd->status.class_), pl_sd->status.job_level); + pl_sd->status.base_level, + job_name(pl_sd->status.class_), pl_sd->status.job_level); clif->message(fd, atcmd_output); - + p = party_search(pl_sd->status.party_id); g = pl_sd->guild; - + sprintf(atcmd_output,msg_txt(916), // Party: '%s' | Guild: '%s' - p?p->party.name:msg_txt(917), g?g->name:msg_txt(917)); // None. - + p?p->party.name:msg_txt(917), g?g->name:msg_txt(917)); // None. + clif->message(fd, atcmd_output); count++; } mapit_free(iter); - + if (count == 0) clif->message(fd, msg_txt(150)); // No GM found. else if (count == 1) @@ -786,70 +735,70 @@ ACMD_FUNC(whogm) sprintf(atcmd_output, msg_txt(152), count); // %d GMs found. clif->message(fd, atcmd_output); } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(save) +ACMD(save) { nullpo_retr(-1, sd); - + pc_setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y); if (sd->status.pet_id > 0 && sd->pd) intif_save_petdata(sd->status.account_id, &sd->pd->pet); - + chrif_save(sd,0); - + clif->message(fd, msg_txt(6)); // Your save point has been changed. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(load) +ACMD(load) { int16 m; - + nullpo_retr(-1, sd); - + m = map_mapindex2mapid(sd->status.save_point.map); if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(249)); // You are not authorized to warp to your save map. - return -1; + return false; } if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map. - return -1; + return false; } - + pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT); clif->message(fd, msg_txt(7)); // Warping to save point.. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(speed) +ACMD(speed) { int speed; - + nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d", &speed) < 1) { sprintf(atcmd_output, msg_txt(918), MIN_WALK_SPEED, MAX_WALK_SPEED); // Please enter a speed value (usage: @speed <%d-%d>). clif->message(fd, atcmd_output); - return -1; + return false; } - + if (speed < 0) { sd->base_status.speed = DEFAULT_WALK_SPEED; sd->state.permanent_speed = 0; // Remove lock when set back to default speed. @@ -859,100 +808,100 @@ ACMD_FUNC(speed) } status_calc_bl(&sd->bl, SCB_SPEED); clif->message(fd, msg_txt(8)); // Speed changed. - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(storage) +ACMD(storage) { nullpo_retr(-1, sd); - + if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag) - return -1; - + return false; + if (storage_storageopen(sd) == 1) { //Already open. clif->message(fd, msg_txt(250)); - return -1; + return false; } - + clif->message(fd, msg_txt(919)); // Storage opened. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(guildstorage) +ACMD(guildstorage) { nullpo_retr(-1, sd); - + if (!sd->status.guild_id) { clif->message(fd, msg_txt(252)); - return -1; + return false; } - + if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading) - return -1; - + return false; + if (sd->state.storage_flag == 1) { clif->message(fd, msg_txt(250)); - return -1; + return false; } - + if (sd->state.storage_flag == 2) { clif->message(fd, msg_txt(251)); - return -1; + return false; } - + storage_guild_storageopen(sd); clif->message(fd, msg_txt(920)); // Guild storage opened. - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(option) +ACMD(option) { int param1 = 0, param2 = 0, param3 = 0; nullpo_retr(-1, sd); - + if (!message || !*message || sscanf(message, "%d %d %d", ¶m1, ¶m2, ¶m3) < 1 || param1 < 0 || param2 < 0 || param3 < 0) {// failed to match the parameters so inform the user of the options const char* text; - + // attempt to find the setting information for this command - text = atcommand_help_string( command ); - + text = atcommand_help_string( info ); + // notify the user of the requirement to enter an option clif->message(fd, msg_txt(921)); // Please enter at least one option. - + if( text ) {// send the help text associated with this command clif->message( fd, text ); } - - return -1; + + return false; } - + sd->sc.opt1 = param1; sd->sc.opt2 = param2; pc_setoption(sd, param3); - + clif->message(fd, msg_txt(9)); // Options changed. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(hide) +ACMD(hide) { nullpo_retr(-1, sd); if (sd->sc.option & OPTION_INVISIBLE) { @@ -962,10 +911,10 @@ ACMD_FUNC(hide) else status_set_viewdata(&sd->bl, sd->status.class_); clif->message(fd, msg_txt(10)); // Invisible: Off - + // increment the number of pvp players on the map map[sd->bl.m].users_pvp++; - + if( map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank ) {// register the player for ranking calculations sd->pvp_timer = add_timer( gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0 ); @@ -976,10 +925,10 @@ ACMD_FUNC(hide) sd->sc.option |= OPTION_INVISIBLE; sd->vd.class_ = INVISIBLE_CLASS; clif->message(fd, msg_txt(11)); // Invisible: On - + // decrement the number of pvp players on the map map[sd->bl.m].users_pvp--; - + if( map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER ) {// unregister the player for ranking delete_timer( sd->pvp_timer, pc_calc_pvprank_timer ); @@ -987,25 +936,25 @@ ACMD_FUNC(hide) } } clif->changeoption(&sd->bl); - - return 0; + + return true; } /*========================================== * Changes a character's class *------------------------------------------*/ -ACMD_FUNC(jobchange) +ACMD(jobchange) { int job = 0, upper = 0; const char* text; nullpo_retr(-1, sd); - + if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) { int i; bool found = false; - + upper = 0; - + // Normal Jobs for( i = JOB_NOVICE; i < JOB_MAX_BASIC && !found; i++ ){ if (strncmpi(message, job_name(i), 16) == 0) { @@ -1013,7 +962,7 @@ ACMD_FUNC(jobchange) found = true; } } - + // High Jobs, Babys and Third for( i = JOB_NOVICE_HIGH; i < JOB_MAX && !found; i++ ){ if (strncmpi(message, job_name(i), 16) == 0) { @@ -1021,85 +970,85 @@ ACMD_FUNC(jobchange) found = true; } } - + if (!found) { - text = atcommand_help_string(command); + text = atcommand_help_string(info); if (text) clif->message(fd, text); - return -1; + return false; } } - + if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2 || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2 || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2 || job == JOB_STAR_GLADIATOR2 - || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2) || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2) - ) // Deny direct transformation into dummy jobs - {clif->message(fd, msg_txt(923)); //"You can not change to this job by command." - return 0;} - + || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2) || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2) + ) // Deny direct transformation into dummy jobs + {clif->message(fd, msg_txt(923)); //"You can not change to this job by command." + return true;} + if (pcdb_checkid(job)) { if (pc_jobchange(sd, job, upper) == 0) clif->message(fd, msg_txt(12)); // Your job has been changed. else { clif->message(fd, msg_txt(155)); // You are unable to change your job. - return -1; + return false; } } else { - text = atcommand_help_string(command); + text = atcommand_help_string(info); if (text) clif->message(fd, text); - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(kill) +ACMD(kill) { nullpo_retr(-1, sd); status_kill(&sd->bl); clif->message(sd->fd, msg_txt(13)); // A pity! You've died. if (fd != sd->fd) clif->message(fd, msg_txt(14)); // Character killed. - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(alive) +ACMD(alive) { nullpo_retr(-1, sd); if (!status_revive(&sd->bl, 100, 100)) { clif->message(fd, msg_txt(667)); - return -1; + return false; } clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); clif->message(fd, msg_txt(16)); // You've been revived! It's a miracle! - return 0; + return true; } /*========================================== * +kamic [LuzZza] *------------------------------------------*/ -ACMD_FUNC(kami) +ACMD(kami) { unsigned long color=0; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if(*(command + 5) != 'c' && *(command + 5) != 'C') { if (!message || !*message) { clif->message(fd, msg_txt(980)); // Please enter a message (usage: @kami ). - return -1; + return false; } - + sscanf(message, "%199[^\n]", atcmd_output); if (strstr(command, "l") != NULL) clif->broadcast(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 0, ALL_SAMEMAP); @@ -1108,22 +1057,22 @@ ACMD_FUNC(kami) } else { if(!message || !*message || (sscanf(message, "%lx %199[^\n]", &color, atcmd_output) < 2)) { clif->message(fd, msg_txt(981)); // Please enter color and message (usage: @kamic ). - return -1; + return false; } - + if(color > 0xFFFFFF) { clif->message(fd, msg_txt(982)); // Invalid color. - return -1; + return false; } intif_broadcast2(atcmd_output, strlen(atcmd_output) + 1, color, 0x190, 12, 0, 0); } - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(heal) +ACMD(heal) { int hp = 0, sp = 0; // [Valaris] thanks to fov nullpo_retr(-1, sd); @@ -1133,30 +1082,30 @@ ACMD_FUNC(heal) // some overflow checks if( hp == INT_MIN ) hp++; if( sp == INT_MIN ) sp++; - + if ( hp == 0 && sp == 0 ) { if (!status_percent_heal(&sd->bl, 100, 100)) clif->message(fd, msg_txt(157)); // HP and SP have already been recovered. else clif->message(fd, msg_txt(17)); // HP, SP recovered. - return 0; + return true; } - + if ( hp > 0 && sp >= 0 ) { if(!status_heal(&sd->bl, hp, sp, 0)) clif->message(fd, msg_txt(157)); // HP and SP are already with the good value. else clif->message(fd, msg_txt(17)); // HP, SP recovered. - return 0; + return true; } - + if ( hp < 0 && sp <= 0 ) { status_damage(NULL, &sd->bl, -hp, -sp, 0, 0); clif->damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0); clif->message(fd, msg_txt(156)); // HP or/and SP modified. - return 0; + return true; } - + //Opposing signs. if ( hp ) { if (hp > 0) @@ -1166,22 +1115,22 @@ ACMD_FUNC(heal) clif->damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0); } } - + if ( sp ) { if (sp > 0) status_heal(&sd->bl, 0, sp, 0); else status_damage(NULL, &sd->bl, 0, -sp, 0, 0); } - + clif->message(fd, msg_txt(156)); // HP or/and SP modified. - return 0; + return true; } /*========================================== * @item command (usage: @item ) (modified by [Yor] for pet_egg) *------------------------------------------*/ -ACMD_FUNC(item) +ACMD(item) { char item_name[100]; int number = 0, item_id, flag = 0; @@ -1189,54 +1138,54 @@ ACMD_FUNC(item) struct item_data *item_data; int get_count, i; nullpo_retr(-1, sd); - + memset(item_name, '\0', sizeof(item_name)); - + if (!message || !*message || ( - sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 && - sscanf(message, "%99s %d", item_name, &number) < 1 - )) { + sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 && + sscanf(message, "%99s %d", item_name, &number) < 1 + )) { clif->message(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item ). - return -1; + return false; } - + if (number <= 0) number = 1; - + if ((item_data = itemdb_searchname(item_name)) == NULL && (item_data = itemdb_exists(atoi(item_name))) == NULL) { clif->message(fd, msg_txt(19)); // Invalid item ID or name. - return -1; + return false; } - + item_id = item_data->nameid; get_count = number; //Check if it's stackable. if (!itemdb_isstackable2(item_data)) get_count = 1; - + for (i = 0; i < number; i += get_count) { // if not pet egg if (!pet_create_egg(sd, item_id)) { memset(&item_tmp, 0, sizeof(item_tmp)); item_tmp.nameid = item_id; item_tmp.identify = 1; - + if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif->additem(sd, 0, 0, flag); } } - + if (flag == 0) clif->message(fd, msg_txt(18)); // Item created. - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(item2) +ACMD(item2) { struct item item_tmp; struct item_data *item_data; @@ -1245,26 +1194,26 @@ ACMD_FUNC(item2) int identify = 0, refine = 0, attr = 0; int c1 = 0, c2 = 0, c3 = 0, c4 = 0; nullpo_retr(-1, sd); - + memset(item_name, '\0', sizeof(item_name)); - + if (!message || !*message || ( - sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 && - sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 - )) { + sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 && + sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 + )) { clif->message(fd, msg_txt(984)); // Please enter all parameters (usage: @item2 clif->message(fd, msg_txt(985)); // ). - return -1; + return false; } - + if (number <= 0) number = 1; - + item_id = 0; if ((item_data = itemdb_searchname(item_name)) != NULL || (item_data = itemdb_exists(atoi(item_name))) != NULL) item_id = item_data->nameid; - + if (item_id > 500) { int flag = 0; int loop, get_count, i; @@ -1299,59 +1248,59 @@ ACMD_FUNC(item2) if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif->additem(sd, 0, 0, flag); } - + if (flag == 0) clif->message(fd, msg_txt(18)); // Item created. } else { clif->message(fd, msg_txt(19)); // Invalid item ID or name. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(itemreset) +ACMD(itemreset) { int i; nullpo_retr(-1, sd); - + for (i = 0; i < MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) { pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_COMMAND); } } clif->message(fd, msg_txt(20)); // All of your items have been removed. - - return 0; + + return true; } /*========================================== * Atcommand @lvlup *------------------------------------------*/ -ACMD_FUNC(baselevelup) +ACMD(baselevelup) { int level=0, i=0, status_point=0; nullpo_retr(-1, sd); level = atoi(message); - + if (!message || !*message || !level) { clif->message(fd, msg_txt(986)); // Please enter a level adjustment (usage: @lvup/@blevel/@baselvlup ). - return -1; + return false; } - + if (level > 0) { if (sd->status.base_level >= pc_maxbaselv(sd)) { // check for max level by Valaris clif->message(fd, msg_txt(47)); // Base level can't go any higher. - return -1; + return false; } // End Addition if ((unsigned int)level > pc_maxbaselv(sd) || (unsigned int)level > pc_maxbaselv(sd) - sd->status.base_level) // fix positiv overflow level = pc_maxbaselv(sd) - sd->status.base_level; for (i = 0; i < level; i++) status_point += pc_gets_status_point(sd->status.base_level + i); - + sd->status.status_point += status_point; sd->status.base_level += (unsigned int)level; status_percent_heal(&sd->bl, 100, 100); @@ -1360,7 +1309,7 @@ ACMD_FUNC(baselevelup) } else { if (sd->status.base_level == 1) { clif->message(fd, msg_txt(158)); // Base level can't go any lower. - return -1; + return false; } level*=-1; if ((unsigned int)level >= sd->status.base_level) @@ -1385,27 +1334,27 @@ ACMD_FUNC(baselevelup) pc_baselevelchanged(sd); if(sd->status.party_id) party_send_levelup(sd); - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(joblevelup) +ACMD(joblevelup) { int level=0; nullpo_retr(-1, sd); - + level = atoi(message); - + if (!message || !*message || !level) { clif->message(fd, msg_txt(987)); // Please enter a level adjustment (usage: @joblvup/@jlevel/@joblvlup ). - return -1; + return false; } if (level > 0) { if (sd->status.job_level >= pc_maxjoblv(sd)) { clif->message(fd, msg_txt(23)); // Job level can't go any higher. - return -1; + return false; } if ((unsigned int)level > pc_maxjoblv(sd) || (unsigned int)level > pc_maxjoblv(sd) - sd->status.job_level) // fix positiv overflow level = pc_maxjoblv(sd) - sd->status.job_level; @@ -1416,7 +1365,7 @@ ACMD_FUNC(joblevelup) } else { if (sd->status.job_level == 1) { clif->message(fd, msg_txt(159)); // Job level can't go any lower. - return -1; + return false; } level *=-1; if ((unsigned int)level >= sd->status.job_level) // fix negativ overflow @@ -1436,60 +1385,54 @@ ACMD_FUNC(joblevelup) clif->updatestatus(sd, SP_NEXTJOBEXP); clif->updatestatus(sd, SP_SKILLPOINT); status_calc_pc(sd, 0); - - return 0; + + return true; } /*========================================== * @help *------------------------------------------*/ -ACMD_FUNC(help) -{ - config_setting_t *help; - const char *text = NULL; +ACMD(help) { const char *command_name = NULL; char *default_command = "help"; - + AtCommandInfo *tinfo = NULL; + nullpo_retr(-1, sd); - - help = config_lookup(&atcommand_config, "help"); - if (help == NULL) { - clif->message(fd, msg_txt(27)); // "Commands help is not available." - return -1; - } - + if (!message || !*message) { command_name = default_command; // If no command_name specified, display help for @help. } else { - if (*message == atcommand_symbol || *message == charcommand_symbol) + if (*message == atcommand->at_symbol || *message == atcommand->char_symbol) ++message; command_name = atcommand_checkalias(message); } - - if (!pc_can_use_command(sd, command_name, COMMAND_ATCOMMAND)) { + + if (!atcommand->can_use2(sd, command_name, COMMAND_ATCOMMAND)) { sprintf(atcmd_output, msg_txt(153), message); // "%s is Unknown Command" clif->message(fd, atcmd_output); atcommand_get_suggestions(sd, command_name, true); - return -1; + return false; } - - if (!config_setting_lookup_string(help, command_name, &text)) { - sprintf(atcmd_output, msg_txt(988), atcommand_symbol, command_name); // There is no help for %c%s. + + tinfo = get_atcommandinfo_byname(atcommand_checkalias(command_name)); + + if ( !tinfo || tinfo->help == NULL ) { + sprintf(atcmd_output, msg_txt(988), atcommand->at_symbol, command_name); // There is no help for %c%s. clif->message(fd, atcmd_output); atcommand_get_suggestions(sd, command_name, true); - return -1; + return false; } - - sprintf(atcmd_output, msg_txt(989), atcommand_symbol, command_name); // Help for command %c%s: + + sprintf(atcmd_output, msg_txt(989), atcommand->at_symbol, command_name); // Help for command %c%s: clif->message(fd, atcmd_output); - + { // Display aliases DBIterator* iter; AtCommandInfo *command_info; AliasInfo *alias_info = NULL; StringBuf buf; bool has_aliases = false; - + StringBuf_Init(&buf); StringBuf_AppendStr(&buf, msg_txt(990)); // Available aliases: command_info = get_atcommandinfo_byname(command_name); @@ -1505,10 +1448,10 @@ ACMD_FUNC(help) clif->message(fd, StringBuf_Value(&buf)); StringBuf_Destroy(&buf); } - + // Display help contents - clif->message(fd, text); - return 0; + clif->message(fd, tinfo->help); + return true; } // helper function, used in foreach calls to stop auto-attack timers @@ -1538,18 +1481,18 @@ static int atcommand_pvpoff_sub(struct block_list *bl,va_list ap) return 0; } -ACMD_FUNC(pvpoff) +ACMD(pvpoff) { nullpo_retr(-1, sd); - + if (!map[sd->bl.m].flag.pvp) { clif->message(fd, msg_txt(160)); // PvP is already Off. - return -1; + return false; } - + map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone); map[sd->bl.m].flag.pvp = 0; - + if (!battle_config.pk_mode) { clif->map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING); clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP); @@ -1557,7 +1500,7 @@ ACMD_FUNC(pvpoff) map_foreachinmap(atcommand_pvpoff_sub,sd->bl.m, BL_PC); map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0); clif->message(fd, msg_txt(31)); // PvP: Off. - return 0; + return true; } /*========================================== @@ -1577,61 +1520,61 @@ static int atcommand_pvpon_sub(struct block_list *bl,va_list ap) return 0; } -ACMD_FUNC(pvpon) +ACMD(pvpon) { nullpo_retr(-1, sd); - + if (map[sd->bl.m].flag.pvp) { clif->message(fd, msg_txt(161)); // PvP is already On. - return -1; + return false; } map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_PVP_NAME)); map[sd->bl.m].flag.pvp = 1; - + if (!battle_config.pk_mode) {// display pvp circle and rank clif->map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE); clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP); map_foreachinmap(atcommand_pvpon_sub,sd->bl.m, BL_PC); } - + clif->message(fd, msg_txt(32)); // PvP: On. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(gvgoff) +ACMD(gvgoff) { nullpo_retr(-1, sd); - + if (!map[sd->bl.m].flag.gvg) { clif->message(fd, msg_txt(162)); // GvG is already Off. - return -1; + return false; } - + map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone); map[sd->bl.m].flag.gvg = 0; clif->map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING); clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP); map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0); clif->message(fd, msg_txt(33)); // GvG: Off. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(gvgon) +ACMD(gvgon) { nullpo_retr(-1, sd); - + if (map[sd->bl.m].flag.gvg) { clif->message(fd, msg_txt(163)); // GvG is already On. - return -1; + return false; } map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_GVG_NAME)); @@ -1639,133 +1582,133 @@ ACMD_FUNC(gvgon) clif->map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE); clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP); clif->message(fd, msg_txt(34)); // GvG: On. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(model) +ACMD(model) { int hair_style = 0, hair_color = 0, cloth_color = 0; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d %d %d", &hair_style, &hair_color, &cloth_color) < 1) { sprintf(atcmd_output, msg_txt(991), // Please enter at least one value (usage: @model ). MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); clif->message(fd, atcmd_output); - return -1; + return false; } - + if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE && hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR && cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) { - pc_changelook(sd, LOOK_HAIR, hair_style); - pc_changelook(sd, LOOK_HAIR_COLOR, hair_color); - pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color); - clif->message(fd, msg_txt(36)); // Appearence changed. + pc_changelook(sd, LOOK_HAIR, hair_style); + pc_changelook(sd, LOOK_HAIR_COLOR, hair_color); + pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color); + clif->message(fd, msg_txt(36)); // Appearence changed. } else { clif->message(fd, msg_txt(37)); // An invalid number was specified. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * @dye && @ccolor *------------------------------------------*/ -ACMD_FUNC(dye) +ACMD(dye) { int cloth_color = 0; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) { sprintf(atcmd_output, msg_txt(992), MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); // Please enter a clothes color (usage: @dye/@ccolor ). clif->message(fd, atcmd_output); - return -1; + return false; } - + if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) { pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color); clif->message(fd, msg_txt(36)); // Appearence changed. } else { clif->message(fd, msg_txt(37)); // An invalid number was specified. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * @hairstyle && @hstyle *------------------------------------------*/ -ACMD_FUNC(hair_style) +ACMD(hair_style) { int hair_style = 0; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) { sprintf(atcmd_output, msg_txt(993), MIN_HAIR_STYLE, MAX_HAIR_STYLE); // Please enter a hair style (usage: @hairstyle/@hstyle ). clif->message(fd, atcmd_output); - return -1; + return false; } - + if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) { - pc_changelook(sd, LOOK_HAIR, hair_style); - clif->message(fd, msg_txt(36)); // Appearence changed. + pc_changelook(sd, LOOK_HAIR, hair_style); + clif->message(fd, msg_txt(36)); // Appearence changed. } else { clif->message(fd, msg_txt(37)); // An invalid number was specified. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * @haircolor && @hcolor *------------------------------------------*/ -ACMD_FUNC(hair_color) +ACMD(hair_color) { int hair_color = 0; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) { sprintf(atcmd_output, msg_txt(994), MIN_HAIR_COLOR, MAX_HAIR_COLOR); // Please enter a hair color (usage: @haircolor/@hcolor ). clif->message(fd, atcmd_output); - return -1; + return false; } - + if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) { - pc_changelook(sd, LOOK_HAIR_COLOR, hair_color); - clif->message(fd, msg_txt(36)); // Appearence changed. + pc_changelook(sd, LOOK_HAIR_COLOR, hair_color); + clif->message(fd, msg_txt(36)); // Appearence changed. } else { clif->message(fd, msg_txt(37)); // An invalid number was specified. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * @go [city_number or city_name] - Updated by Harbin *------------------------------------------*/ -ACMD_FUNC(go) +ACMD(go) { int i; int town; char map_name[MAP_NAME_LENGTH]; int16 m; - + const struct { char map[MAP_NAME_LENGTH]; int x, y; @@ -1811,37 +1754,32 @@ ACMD_FUNC(go) { MAP_MALAYA, 242, 211 }, // 34=Malaya Port { MAP_ECLAGE, 110, 39 }, // 35=Eclage }; - + nullpo_retr(-1, sd); - - if( map[sd->bl.m].flag.nogo && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { - clif->message(sd->fd,msg_txt(995)); // You cannot use @go on this map. - return 0; - } - + memset(map_name, '\0', sizeof(map_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); - + // get the number town = atoi(message); - + if (!message || !*message || sscanf(message, "%11s", map_name) < 1 || town < 0 || town >= ARRAYLENGTH(data)) {// no value matched so send the list of locations const char* text; - + // attempt to find the text help string - text = atcommand_help_string( command ); - + text = atcommand_help_string( info ); + clif->message(fd, msg_txt(38)); // Invalid location number, or name. - + if( text ) {// send the text to the client clif->message( fd, text ); } - - return -1; + + return false; } - + // get possible name of the city map_name[MAP_NAME_LENGTH-1] = '\0'; for (i = 0; map_name[i]; i++) @@ -1930,36 +1868,36 @@ ACMD_FUNC(go) } else if (strncmp(map_name, "eclage", 3) == 0) { town = 35; } - + if (town >= 0 && town < ARRAYLENGTH(data)) { m = map_mapname2mapid(data[town].map); if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(247)); - return -1; + return false; } if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); - return -1; + return false; } if (pc_setpos(sd, mapindex_name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) { clif->message(fd, msg_txt(0)); // Warped. } else { clif->message(fd, msg_txt(1)); // Map not found. - return -1; + return false; } } else { // if you arrive here, you have an error in town variable when reading of names clif->message(fd, msg_txt(38)); // Invalid location number or name. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(monster) +ACMD(monster) { char name[NAME_LENGTH]; char monster[NAME_LENGTH]; @@ -1971,14 +1909,14 @@ ACMD_FUNC(monster) short mx, my; unsigned int size; nullpo_retr(-1, sd); - + memset(name, '\0', sizeof(name)); memset(monster, '\0', sizeof(monster)); memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message) { - clif->message(fd, msg_txt(80)); // Give the display name or monster name/id please. - return -1; + clif->message(fd, msg_txt(80)); // Give the display name or monster name/id please. + return false; } if (sscanf(message, "\"%23[^\"]\" %23s %d", name, monster, &number) > 1 || sscanf(message, "%23s \"%23[^\"]\" %d", monster, name, &number) > 1) { @@ -1994,42 +1932,42 @@ ACMD_FUNC(monster) name[0] = '\0'; } else { clif->message(fd, msg_txt(80)); // Give a display name and monster name/id please. - return -1; + return false; } - + if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number) mob_id = mobdb_checkid(atoi(monster)); - + if (mob_id == 0) { clif->message(fd, msg_txt(40)); // Invalid monster ID or name. - return -1; + return false; } - + if (mob_id == MOBID_EMPERIUM) { clif->message(fd, msg_txt(83)); // Monster 'Emperium' cannot be spawned. - return -1; + return false; } - + if (number <= 0) number = 1; - + if( !name[0] ) strcpy(name, "--ja--"); - + // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive if (battle_config.atc_spawn_quantity_limit && number > battle_config.atc_spawn_quantity_limit) number = battle_config.atc_spawn_quantity_limit; - + if (strcmp(command+1, "monstersmall") == 0) size = SZ_MEDIUM; // This is just gorgeous [mkbu95] else if (strcmp(command+1, "monsterbig") == 0) size = SZ_BIG; else size = SZ_SMALL; - + if (battle_config.etc_log) ShowInfo("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y); - + count = 0; range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around) for (i = 0; i < number; i++) { @@ -2037,7 +1975,7 @@ ACMD_FUNC(monster) k = mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE); count += (k != 0) ? 1 : 0; } - + if (count != 0) if (number == count) clif->message(fd, msg_txt(39)); // All monster summoned! @@ -2045,12 +1983,12 @@ ACMD_FUNC(monster) sprintf(atcmd_output, msg_txt(240), count); // %d monster(s) summoned! clif->message(fd, atcmd_output); } - else { - clif->message(fd, msg_txt(40)); // Invalid monster ID or name. - return -1; - } - - return 0; + else { + clif->message(fd, msg_txt(40)); // Invalid monster ID or name. + return false; + } + + return true; } /*========================================== @@ -2060,13 +1998,13 @@ static int atkillmonster_sub(struct block_list *bl, va_list ap) { struct mob_data *md; int flag; - + nullpo_ret(md=(struct mob_data *)bl); flag = va_arg(ap, int); - + if (md->guardian_data) return 0; //Do not touch WoE mobs! - + if (flag) status_zap(bl,md->status.hp, 0); else @@ -2074,41 +2012,41 @@ static int atkillmonster_sub(struct block_list *bl, va_list ap) return 1; } -ACMD_FUNC(killmonster) +ACMD(killmonster) { int map_id, drop_flag; char map_name[MAP_NAME_LENGTH_EXT]; nullpo_retr(-1, sd); - + memset(map_name, '\0', sizeof(map_name)); - + if (!message || !*message || sscanf(message, "%15s", map_name) < 1) map_id = sd->bl.m; else { if ((map_id = map_mapname2mapid(map_name)) < 0) map_id = sd->bl.m; } - + drop_flag = strcmp(command+1, "killmonster2"); - + map_foreachinmap(atkillmonster_sub, map_id, BL_MOB, -drop_flag); - + clif->message(fd, msg_txt(165)); // All monsters killed! - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(refine) +ACMD(refine) { int i,j, position = 0, refine = 0, current_position, final_refine; int count; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d %d", &position, &refine) < 2) { clif->message(fd, msg_txt(996)); // Please enter a position and an amount (usage: @refine <+/- amount>). sprintf(atcmd_output, msg_txt(997), EQP_HEAD_LOW); // %d: Lower Headgear @@ -2131,11 +2069,11 @@ ACMD_FUNC(refine) clif->message(fd, atcmd_output); sprintf(atcmd_output, msg_txt(1006), EQP_HEAD_MID); // %d: Mid Headgear clif->message(fd, atcmd_output); - return -1; + return false; } - + refine = cap_value(refine, -MAX_REFINE, MAX_REFINE); - + count = 0; for (j = 0; j < EQI_MAX-1; j++) { if ((i = sd->equip_index[j]) < 0) @@ -2146,10 +2084,10 @@ ACMD_FUNC(refine) continue; if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == i || sd->equip_index[EQI_HEAD_LOW] == i)) continue; - + if(position && !(sd->status.inventory[i].equip & position)) continue; - + final_refine = cap_value(sd->status.inventory[i].refine + refine, 0, MAX_REFINE); if (sd->status.inventory[i].refine != final_refine) { sd->status.inventory[i].refine = final_refine; @@ -2163,7 +2101,7 @@ ACMD_FUNC(refine) count++; } } - + if (count == 0) clif->message(fd, msg_txt(166)); // No item has been refined. else if (count == 1) @@ -2172,40 +2110,40 @@ ACMD_FUNC(refine) sprintf(atcmd_output, msg_txt(168), count); // %d items have been refined. clif->message(fd, atcmd_output); } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(produce) +ACMD(produce) { char item_name[100]; int item_id, attribute = 0, star = 0; struct item_data *item_data; struct item tmp_item; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(item_name, '\0', sizeof(item_name)); - + if (!message || !*message || ( - sscanf(message, "\"%99[^\"]\" %d %d", item_name, &attribute, &star) < 1 && - sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1 - )) { + sscanf(message, "\"%99[^\"]\" %d %d", item_name, &attribute, &star) < 1 && + sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1 + )) { clif->message(fd, msg_txt(1007)); // Please enter at least one item name/ID (usage: @produce <# of very's>). - return -1; + return false; } - + if ( (item_data = itemdb_searchname(item_name)) == NULL && - (item_data = itemdb_exists(atoi(item_name))) == NULL ) { + (item_data = itemdb_exists(atoi(item_name))) == NULL ) { clif->message(fd, msg_txt(170)); //This item is not an equipment. - return -1; + return false; } - + item_id = item_data->nameid; - + if (itemdb_isequip2(item_data)) { int flag = 0; if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE) @@ -2218,33 +2156,33 @@ ACMD_FUNC(produce) tmp_item.identify = 1; tmp_item.card[0] = CARD0_FORGE; tmp_item.card[1] = item_data->type==IT_WEAPON? - ((star*5) << 8) + attribute:0; + ((star*5) << 8) + attribute:0; tmp_item.card[2] = GetWord(sd->status.char_id, 0); tmp_item.card[3] = GetWord(sd->status.char_id, 1); clif->produce_effect(sd, 0, item_id); clif->misceffect(&sd->bl, 3); - + if ((flag = pc_additem(sd, &tmp_item, 1, LOG_TYPE_COMMAND))) clif->additem(sd, 0, 0, flag); } else { sprintf(atcmd_output, msg_txt(169), item_id, item_data->name); // The item (%d: '%s') is not equipable. clif->message(fd, atcmd_output); - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(memo) +ACMD(memo) { int position = 0; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if( !message || !*message || sscanf(message, "%d", &position) < 1 ) { int i; @@ -2257,78 +2195,78 @@ ACMD_FUNC(memo) sprintf(atcmd_output, msg_txt(171), i); // %d - void clif->message(sd->fd, atcmd_output); } - return 0; + return true; } - + if( position < 0 || position >= MAX_MEMOPOINTS ) { sprintf(atcmd_output, msg_txt(1008), 0, MAX_MEMOPOINTS-1); // Please enter a valid position (usage: @memo ). clif->message(fd, atcmd_output); - return -1; + return false; } - + pc_memo(sd, position); - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(gat) +ACMD(gat) { int y; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + for (y = 2; y >= -2; y--) { sprintf(atcmd_output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X", - map[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y, - map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE), - map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE)); - + map[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y, + map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE), + map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE), + map_getcell(sd->bl.m, sd->bl.x, sd->bl.y + y, CELL_GETTYPE), + map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE), + map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE)); + clif->message(fd, atcmd_output); } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(displaystatus) +ACMD(displaystatus) { int i, type, flag, tick, val1 = 0, val2 = 0, val3 = 0; nullpo_retr(-1, sd); - + if (!message || !*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) { clif->message(fd, msg_txt(1009)); // Please enter a status type/flag (usage: @displaystatus { { {}}}). - return -1; + return false; } if (i < 2) flag = 1; if (i < 3) tick = 0; - + clif->status_change(&sd->bl, type, flag, tick, val1, val2, val3); - - return 0; + + return true; } /*========================================== * @stpoint (Rewritten by [Yor]) *------------------------------------------*/ -ACMD_FUNC(statuspoint) +ACMD(statuspoint) { int point; unsigned int new_status_point; - + if (!message || !*message || (point = atoi(message)) == 0) { clif->message(fd, msg_txt(1010)); // Please enter a number (usage: @stpoint ). - return -1; + return false; } - + if(point < 0) { if(sd->status.status_point < (unsigned int)(-point)) @@ -2348,7 +2286,7 @@ ACMD_FUNC(statuspoint) { new_status_point = sd->status.status_point + point; } - + if (new_status_point != sd->status.status_point) { sd->status.status_point = new_status_point; clif->updatestatus(sd, SP_STATUSPOINT); @@ -2358,26 +2296,26 @@ ACMD_FUNC(statuspoint) clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. else clif->message(fd, msg_txt(149)); // Unable to increase the number/value. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * @skpoint (Rewritten by [Yor]) *------------------------------------------*/ -ACMD_FUNC(skillpoint) +ACMD(skillpoint) { int point; unsigned int new_skill_point; nullpo_retr(-1, sd); - + if (!message || !*message || (point = atoi(message)) == 0) { clif->message(fd, msg_txt(1011)); // Please enter a number (usage: @skpoint ). - return -1; + return false; } - + if(point < 0) { if(sd->status.skill_point < (unsigned int)(-point)) @@ -2397,7 +2335,7 @@ ACMD_FUNC(skillpoint) { new_skill_point = sd->status.skill_point + point; } - + if (new_skill_point != sd->status.skill_point) { sd->status.skill_point = new_skill_point; clif->updatestatus(sd, SP_SKILLPOINT); @@ -2407,75 +2345,75 @@ ACMD_FUNC(skillpoint) clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. else clif->message(fd, msg_txt(149)); // Unable to increase the number/value. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * @zeny *------------------------------------------*/ -ACMD_FUNC(zeny) +ACMD(zeny) { int zeny=0, ret=-1; nullpo_retr(-1, sd); - + if (!message || !*message || (zeny = atoi(message)) == 0) { clif->message(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny ). - return -1; + return false; } - + if(zeny > 0){ if((ret=pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL)) == 1) - clif->message(fd, msg_txt(149)); // Unable to increase the number/value. + clif->message(fd, msg_txt(149)); // Unable to increase the number/value. } else { if( sd->status.zeny < -zeny ) zeny = -sd->status.zeny; if((ret=pc_payzeny(sd,-zeny,LOG_TYPE_COMMAND,NULL)) == 1) - clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. + clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. } if(!ret) clif->message(fd, msg_txt(176)); //ret=0 mean cmd success - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(param) +ACMD(param) { int i, value = 0, new_value, max; const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" }; short* status[6]; //we don't use direct initialization because it isn't part of the c standard. nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); - + if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) { clif->message(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>). - return -1; + return false; } - + ARR_FIND( 0, ARRAYLENGTH(param), i, strcmpi(command+1, param[i]) == 0 ); - + if( i == ARRAYLENGTH(param) || i > MAX_STATUS_TYPE) { // normally impossible... clif->message(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>). - return -1; + return false; } - + status[0] = &sd->status.str; status[1] = &sd->status.agi; status[2] = &sd->status.vit; status[3] = &sd->status.int_; status[4] = &sd->status.dex; status[5] = &sd->status.luk; - + if( battle_config.atcommand_max_stat_bypass ) max = SHRT_MAX; else max = pc_maxparameter(sd); - + if(value < 0 && *status[i] <= -value) { new_value = 1; } else if(max - *status[i] < value) { @@ -2483,7 +2421,7 @@ ACMD_FUNC(param) } else { new_value = *status[i] + value; } - + if (new_value != *status[i]) { *status[i] = new_value; clif->updatestatus(sd, SP_STR + i); @@ -2495,29 +2433,29 @@ ACMD_FUNC(param) clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. else clif->message(fd, msg_txt(149)); // Unable to increase the number/value. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * Stat all by fritz (rewritten by [Yor]) *------------------------------------------*/ -ACMD_FUNC(stat_all) +ACMD(stat_all) { int index, count, value, max, new_value; short* status[6]; //we don't use direct initialization because it isn't part of the c standard. nullpo_retr(-1, sd); - + status[0] = &sd->status.str; status[1] = &sd->status.agi; status[2] = &sd->status.vit; status[3] = &sd->status.int_; status[4] = &sd->status.dex; status[5] = &sd->status.luk; - + if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) { value = pc_maxparameter(sd); max = pc_maxparameter(sd); @@ -2527,17 +2465,17 @@ ACMD_FUNC(stat_all) else max = pc_maxparameter(sd); } - + count = 0; for (index = 0; index < ARRAYLENGTH(status); index++) { - + if (value > 0 && *status[index] > max - value) new_value = max; else if (value < 0 && *status[index] <= -value) new_value = 1; else new_value = *status[index] +value; - + if (new_value != (int)*status[index]) { *status[index] = new_value; clif->updatestatus(sd, SP_STR + index); @@ -2545,7 +2483,7 @@ ACMD_FUNC(stat_all) count++; } } - + if (count > 0) { // if at least 1 stat modified status_calc_pc(sd, 0); clif->message(fd, msg_txt(84)); // All stats changed! @@ -2554,268 +2492,268 @@ ACMD_FUNC(stat_all) clif->message(fd, msg_txt(177)); // You cannot decrease that stat anymore. else clif->message(fd, msg_txt(178)); // You cannot increase that stat anymore. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(guildlevelup) +ACMD(guildlevelup) { int level = 0; short added_level; struct guild *guild_info; nullpo_retr(-1, sd); - + if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) { clif->message(fd, msg_txt(1014)); // Please enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>). - return -1; + return false; } - + if (sd->status.guild_id <= 0 || (guild_info = sd->guild) == NULL) { clif->message(fd, msg_txt(43)); // You're not in a guild. - return -1; + return false; } //if (strcmp(sd->status.name, guild_info->master) != 0) { // clif->message(fd, msg_txt(44)); // You're not the master of your guild. - // return -1; + // return false; //} - + added_level = (short)level; if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv; else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow added_level = 1 - guild_info->guild_lv; - + if (added_level != 0) { intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level)); clif->message(fd, msg_txt(179)); // Guild level changed. } else { clif->message(fd, msg_txt(45)); // Guild level change failed. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(makeegg) +ACMD(makeegg) { struct item_data *item_data; int id, pet_id; nullpo_retr(-1, sd); - + if (!message || !*message) { clif->message(fd, msg_txt(1015)); // Please enter a monster/egg name/ID (usage: @makeegg ). - return -1; + return false; } - + if ((item_data = itemdb_searchname(message)) != NULL) // for egg name id = item_data->nameid; else - if ((id = mobdb_searchname(message)) != 0) // for monster name - ; - else - id = atoi(message); - + if ((id = mobdb_searchname(message)) != 0) // for monster name + ; + else + id = atoi(message); + pet_id = search_petDB_index(id, PET_CLASS); if (pet_id < 0) pet_id = search_petDB_index(id, PET_EGG); if (pet_id >= 0) { sd->catch_target_class = pet_db[pet_id].class_; intif_create_pet( - sd->status.account_id, sd->status.char_id, - (short)pet_db[pet_id].class_, (short)mob_db(pet_db[pet_id].class_)->lv, - (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate, - 100, 0, 1, pet_db[pet_id].jname); + sd->status.account_id, sd->status.char_id, + (short)pet_db[pet_id].class_, (short)mob_db(pet_db[pet_id].class_)->lv, + (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate, + 100, 0, 1, pet_db[pet_id].jname); } else { clif->message(fd, msg_txt(180)); // The monster/egg name/id doesn't exist. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(hatch) +ACMD(hatch) { nullpo_retr(-1, sd); if (sd->status.pet_id <= 0) clif->sendegg(sd); else { clif->message(fd, msg_txt(181)); // You already have a pet. - return -1; + return false; } - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(petfriendly) +ACMD(petfriendly) { int friendly; struct pet_data *pd; nullpo_retr(-1, sd); - + if (!message || !*message || (friendly = atoi(message)) < 0) { clif->message(fd, msg_txt(1016)); // Please enter a valid value (usage: @petfriendly <0-1000>). - return -1; + return false; } - + pd = sd->pd; if (!pd) { clif->message(fd, msg_txt(184)); // Sorry, but you have no pet. - return -1; + return false; } - + if (friendly < 0 || friendly > 1000) { clif->message(fd, msg_txt(37)); // An invalid number was specified. - return -1; + return false; } - + if (friendly == pd->pet.intimate) { clif->message(fd, msg_txt(183)); // Pet intimacy is already at maximum. - return -1; + return false; } - + pet_set_intimate(pd, friendly); clif->send_petstatus(sd); clif->message(fd, msg_txt(182)); // Pet intimacy changed. - return 0; + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(pethungry) +ACMD(pethungry) { int hungry; struct pet_data *pd; nullpo_retr(-1, sd); - + if (!message || !*message || (hungry = atoi(message)) < 0) { clif->message(fd, msg_txt(1017)); // Please enter a valid number (usage: @pethungry <0-100>). - return -1; + return false; } - + pd = sd->pd; if (!sd->status.pet_id || !pd) { clif->message(fd, msg_txt(184)); // Sorry, but you have no pet. - return -1; + return false; } if (hungry < 0 || hungry > 100) { clif->message(fd, msg_txt(37)); // An invalid number was specified. - return -1; + return false; } if (hungry == pd->pet.hungry) { clif->message(fd, msg_txt(186)); // Pet hunger is already at maximum. - return -1; + return false; } - + pd->pet.hungry = hungry; clif->send_petstatus(sd); clif->message(fd, msg_txt(185)); // Pet hunger changed. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(petrename) +ACMD(petrename) { struct pet_data *pd; nullpo_retr(-1, sd); if (!sd->status.pet_id || !sd->pd) { clif->message(fd, msg_txt(184)); // Sorry, but you have no pet. - return -1; + return false; } pd = sd->pd; if (!pd->pet.rename_flag) { clif->message(fd, msg_txt(188)); // You can already rename your pet. - return -1; + return false; } - + pd->pet.rename_flag = 0; intif_save_petdata(sd->status.account_id, &pd->pet); clif->send_petstatus(sd); clif->message(fd, msg_txt(187)); // You can now rename your pet. - - return 0; + + return true; } /*========================================== * *------------------------------------------*/ -ACMD_FUNC(recall) { +ACMD(recall) { struct map_session_data *pl_sd = NULL; - + nullpo_retr(-1, sd); - + if (!message || !*message) { clif->message(fd, msg_txt(1018)); // Please enter a player name (usage: @recall ). - return -1; + return false; } - + if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_txt(3)); // Character not found. - return -1; + return false; } - + if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { clif->message(fd, msg_txt(81)); // Your GM level doesn't authorize you to preform this action on the specified player. - return -1; + return false; } - + if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1019)); // You are not authorized to warp someone to this map. - return -1; + return false; } if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1020)); // You are not authorized to warp this player from their map. - return -1; + return false; } if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y) { - return -1; + return false; } pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN); sprintf(atcmd_output, msg_txt(46), pl_sd->status.name); // %s recalled! clif->message(fd, atcmd_output); - - return 0; + + return true; } /*========================================== * charblock command (usage: charblock ) * This command do a definitiv ban on a player *------------------------------------------*/ -ACMD_FUNC(char_block) +ACMD(char_block) { nullpo_retr(-1, sd); - + memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - + if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { clif->message(fd, msg_txt(1021)); // Please enter a player name (usage: @charblock/@block ). - return -1; + return false; } - + chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it. - - return 0; + + return true; } /*========================================== @@ -2833,24 +2771,24 @@ ACMD_FUNC(char_block) * @ban +1m-2mn1s-6y test_player * this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time. *------------------------------------------*/ -ACMD_FUNC(char_ban) +ACMD(char_ban) { char * modif_p; int year, month, day, hour, minute, second, value; time_t timestamp; struct tm *tmtime; nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); - + if (!message || !*message || sscanf(message, "%255s %23[^\n]", atcmd_output, atcmd_player_name) < 2) { clif->message(fd, msg_txt(1022)); // Please enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish