Index: conf/msg_conf/map_msg.conf
===================================================================
--- conf/msg_conf/map_msg.conf (revision 17307)
+++ conf/msg_conf/map_msg.conf (working copy)
@@ -629,7 +629,6 @@
678: You are no longer the Guild Master.
679: You have become the Guild Master!
680: You have been recovered!
-//681-899 free
681: Rune Knight T
682: Warlock T
@@ -646,6 +645,10 @@
693: Shadow Chaser T
694: Hanbok
+695: Item %d has been removed from your inventory.
+696: Item %d has been removed from your cart.
+697: Item %d has been removed from your storage.
+//698-899 free
//------------------------------------
// More atcommands message
Index: conf/battle/items.conf
===================================================================
--- conf/battle/items.conf (revision 17307)
+++ conf/battle/items.conf (working copy)
@@ -51,12 +51,16 @@
// NOTE: Wedding Rings and Whips/Musical Instruments will check gender regardless of setting.
ignore_items_gender: yes
-// Item check? (Note 1)
+// Item check? (Note 3)
// On map change it will check for items not tagged as "available" and
-// auto-delete them from inventory/cart.
+// auto-delete them from inventory/cart. Items are auto-deleted from
+// storage when the character data is saved.
// NOTE: An item is not available if it was not loaded from the item_db or you
// specify it as unavailable in db/item_avail.txt
-item_check: no
+// 1: Inventory
+// 2: Cart
+// 4: Storage
+item_check: 0
// How much time must pass between item uses?
// Only affects the delay between using items, prevents healing item abuse. Recommended ~500 ms
Index: conf/battle/exp.conf
===================================================================
--- conf/battle/exp.conf (revision 17307)
+++ conf/battle/exp.conf (working copy)
@@ -70,10 +70,10 @@
death_penalty_type: 1
// Base exp. penalty rate (Each 100 is 1% of their exp)
-death_penalty_base: 100
+death_penalty_base: 300
// Job exp. penalty rate (Each 100 is 1% of their exp)
-death_penalty_job: 100
+death_penalty_job: 300
// When a player dies (to another player), how much zeny should we penalize them with?
// NOTE: It is a percentage of their zeny, so 100 = 1%
Index: conf/char_athena.conf
===================================================================
--- conf/char_athena.conf (revision 17307)
+++ conf/char_athena.conf (working copy)
@@ -143,7 +143,7 @@
// How many Characters are allowed per Account ? (0 = disabled)
// You can not exceed the limit of MAX_CHARS slots, defined in mmo.h
// Doing that, chars_per_account will be default to MAX_CHARS.
-chars_per_account: 0
+chars_per_account: 9
// Restrict character deletion by BaseLevel
// 0: no restriction (players can delete characters of any level)
Index: conf/groups.conf
===================================================================
--- conf/groups.conf (revision 17307)
+++ conf/groups.conf (working copy)
@@ -97,6 +97,18 @@
},
{
id: 1
+ name: "VIP"
+ inherit: ( "Player" ) /* can do everything Players can */
+ level: 0
+ commands: {
+ /* no commands by default */
+ }
+ permissions: {
+ /* no permissions by default */
+ }
+},
+{
+ id: 2
name: "Super Player"
inherit: ( "Player" ) /* can do everything Players can and more */
level: 0
@@ -136,7 +148,7 @@
}
},
{
- id: 2
+ id: 3
name: "Support"
inherit: ( "Super Player" )
level: 1
@@ -161,7 +173,7 @@
}
},
{
- id: 3
+ id: 4
name: "Script Manager"
inherit: ( "Support" )
level: 1
@@ -180,7 +192,7 @@
}
},
{
- id: 4
+ id: 5
name: "Event Manager"
inherit: ( "Support" )
level: 1
Index: sql-files/main.sql
===================================================================
--- sql-files/main.sql (revision 17307)
+++ sql-files/main.sql (working copy)
@@ -442,6 +442,7 @@
`character_slots` tinyint(3) unsigned NOT NULL default '0',
`pincode` varchar(4) NOT NULL DEFAULT '',
`pincode_change` int(11) unsigned NOT NULL DEFAULT '0',
+ `vip_time` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`account_id`),
KEY `name` (`userid`)
) ENGINE=MyISAM AUTO_INCREMENT=2000000;
Index: src/login/account_sql.c
===================================================================
--- src/login/account_sql.c (revision 17307)
+++ src/login/account_sql.c (working copy)
@@ -7,6 +7,7 @@
#include "../common/sql.h"
#include "../common/strlib.h"
#include "../common/timer.h"
+#include "../common/conf.h" //Inter_config
#include "account.h"
#include <stdlib.h>
#include <string.h>
@@ -520,6 +521,28 @@
char* data;
int i = 0;
+ if( Inter_Config.vip_sys.enable ) {
+ // Check for VIP time and set if date has not been reached.
+ if( SQL_SUCCESS == Sql_Query(sql_handle,
+ "UPDATE `%s` SET `group_id` = %d WHERE `group_id`< %d and `account_id` = %d AND `vip_time` >= NOW()",
+ db->account_db, Inter_Config.vip_sys.group,Inter_Config.vip_sys.group,account_id) //only update if group_id lower
+ ) {
+ // Add premium character slots.
+ Sql_Query(sql_handle, "UPDATE `%s` SET `character_slots` = %d WHERE `character_slots`< %d `account_id` = '%d'", db->account_db, Inter_Config.vip_sys.char_increase,Inter_Config.vip_sys.char_increase,account_id);
+ }
+
+ // Check for VIP time and remove if date has been passed.
+ else if( SQL_SUCCESS == Sql_Query(sql_handle,
+ "UPDATE `%s` SET `group_id` = 0 WHERE `account_id` = %d AND `vip_time` != '0000-00-00 00:00:00' AND `vip_time` < NOW()",
+ db->account_db, account_id ) //@TODO return to previous group_id instead 0 ?
+ ) {
+ // Remove premium character slots.
+ // Setting to 0 will cause the char_server to force it to server default (char_athena.conf -> chars_per_account).
+ // Characters won't be deleted, they just won't be accessible.
+ Sql_Query(sql_handle, "UPDATE `%s` SET `character_slots` = 0 WHERE `account_id` = '%d'", db->account_db, account_id );
+ }
+ }
+
// retrieve login entry for the specified account
if( SQL_ERROR == Sql_Query(sql_handle,
"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change` FROM `%s` WHERE `account_id` = %d",
Index: src/map/atcommand.c
===================================================================
--- src/map/atcommand.c (revision 17307)
+++ src/map/atcommand.c (working copy)
@@ -7380,6 +7380,11 @@
nullpo_ret(sd);
memset(buf, '\0', sizeof(buf));
+ if( Inter_Config.vip_sys.enable && pc_get_vip(sd) ) { // Display EXP rate increase for VIP.
+ battle_config.base_exp_rate += Inter_Config.vip_sys.exp_increase;
+ battle_config.job_exp_rate += Inter_Config.vip_sys.exp_increase;
+ }
+
snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1298), // Experience rates: Base %.2fx / Job %.2fx
battle_config.base_exp_rate/100., battle_config.job_exp_rate/100.);
clif_displaymessage(fd, buf);
Index: src/map/skill.c
===================================================================
--- src/map/skill.c (revision 17307)
+++ src/map/skill.c (working copy)
@@ -13147,7 +13147,7 @@
* Warlock
**/
case WL_COMET:
- if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0
+ if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && require.itemid[0]
&& ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) ) {
//clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -13848,11 +13848,11 @@
continue;
break;
case AB_ADORAMUS:
- if( itemid_isgemstone(skill_db[idx].itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2) )
+ if( ( sd->special_state.no_gemstone != 2 ) && itemid_isgemstone(skill_db[idx].itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2) )
continue;
break;
case WL_COMET:
- if( itemid_isgemstone(skill_db[idx].itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0) )
+ if( ( sd->special_state.no_gemstone != 2 ) && itemid_isgemstone(skill_db[idx].itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0) )
continue;
break;
case GN_FIRE_EXPANSION:
@@ -13875,8 +13875,11 @@
req.itemid[i] = skill_db[idx].itemid[i];
req.amount[i] = skill_db[idx].amount[i];
- if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN )
- {
+ // Remove all Magic Stone required for all skills for VIP.
+ if( itemid_isgemstone(req.itemid[i]) && ( sd->special_state.no_gemstone == 2 ) ) {
+ req.itemid[i] = 0;
+ req.amount[i] = 0;
+ } else if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN ) {
if( sd->special_state.no_gemstone )
{ //Make it substract 1 gem rather than skipping the cost.
if( --req.amount[i] < 1 )
Index: src/map/pc.c
===================================================================
--- src/map/pc.c (revision 17307)
+++ src/map/pc.c (working copy)
@@ -12,6 +12,7 @@
#include "../common/timer.h"
#include "../common/utils.h"
#include "../common/mmo.h" //NAME_LENGTH
+#include "../common/conf.h" //Inter_config
#include "atcommand.h" // get_atcommand_level()
#include "battle.h" // battle_config
@@ -38,6 +39,7 @@
#include "script.h" // script_config
#include "skill.h"
#include "status.h" // struct status_data
+#include "storage.h"
#include "pc.h"
#include "pc_groups.h"
#include "quest.h"
@@ -1159,6 +1161,10 @@
sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT");
}
+ // Magic Stone requirement avoidance for VIP.
+ if(Inter_Config.vip_sys.magic_stone && pc_get_vip(sd))
+ sd->special_state.no_gemstone = 2;
+
//SG map and mob read [Komurka]
for(i=0;i<MAX_PC_FEELHATE;i++) //for now - someone need to make reading from txt/sql
{
@@ -1219,6 +1225,8 @@
if (!chrif_auth_finished(sd))
ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
+ pc_check_available_item(sd); // Check for invalid(ated) items in inventory/cart/storage.
+
pc_load_combo(sd);
status_calc_pc(sd,1);
@@ -2431,7 +2439,8 @@
break;
case SP_NO_GEMSTONE:
if(sd->state.lr_flag != 2)
- sd->special_state.no_gemstone = 1;
+ if( sd->special_state.no_gemstone != 2 )
+ sd->special_state.no_gemstone = 1;
break;
case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
if(sd->state.lr_flag != 2) {
@@ -5741,8 +5750,13 @@
(int)(status_get_lv(src) - sd->status.base_level) >= 20)
bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
- if (sd->sc.data[SC_EXPBOOST])
- bonus += sd->sc.data[SC_EXPBOOST]->val1;
+ if (sd->sc.data[SC_EXPBOOST]) {
+ // Increase Battle Manual EXP rate for VIP.
+ if( Inter_Config.vip_sys.bm_increase && pc_get_vip(sd) )
+ bonus += sd->sc.data[SC_EXPBOOST]->val1 + ( sd->sc.data[SC_EXPBOOST]->val1 / Inter_Config.vip_sys.bm_increase );
+ else
+ bonus += sd->sc.data[SC_EXPBOOST]->val1;
+ }
*base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
@@ -6785,6 +6799,10 @@
&& !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
&& !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
{
+ if(Inter_Config.vip_sys.exp_penalty && pc_get_vip(sd) ) { // Decrease EXP penalty for VIP.
+ battle_config.death_penalty_base -= Inter_Config.vip_sys.exp_penalty;
+ battle_config.death_penalty_job -= Inter_Config.vip_sys.exp_penalty;
+ }
unsigned int base_penalty =0;
if (battle_config.death_penalty_base > 0) {
switch (battle_config.death_penalty_type) {
@@ -8859,54 +8877,86 @@
*------------------------------------------*/
int pc_checkitem(struct map_session_data *sd)
{
- int i,id,calc_flag = 0;
+ int i,calc_flag = 0;
nullpo_ret(sd);
if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
return 0;
- if( battle_config.item_check ) {// check for invalid(ated) items
+ for( i = 0; i < MAX_INVENTORY; i++) {
+
+ if( sd->status.inventory[i].nameid == 0 )
+ continue;
+
+ if( !sd->status.inventory[i].equip )
+ continue;
+
+ if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) ) {
+ pc_unequipitem(sd, i, 2);
+ calc_flag = 1;
+ continue;
+ }
+
+ }
+
+ if( calc_flag && sd->state.active ) {
+ pc_checkallowskill(sd);
+ status_calc_pc(sd,0);
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * Checks for unavailable items and removes them.
+ *------------------------------------------*/
+int pc_check_available_item(struct map_session_data *sd)
+{
+ int i, id;
+ char output[256];
+
+ nullpo_ret(sd);
+
+ if( battle_config.item_check&1 ) { // Check for invalid(ated) items in inventory.
for( i = 0; i < MAX_INVENTORY; i++ ) {
id = sd->status.inventory[i].nameid;
if( id && !itemdb_available(id) ) {
+ sprintf(output, msg_txt(sd, 695), id); // Item %d has been removed from your inventory.
+ clif_displaymessage(sd->fd, output);
ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
}
}
+ }
+ if( battle_config.item_check&2 ) { // Check for invalid(ated) items in cart.
for( i = 0; i < MAX_CART; i++ ) {
id = sd->status.cart[i].nameid;
if( id && !itemdb_available(id) ) {
+ sprintf(output, msg_txt(sd, 696), id); // Item %d has been removed from your cart.
+ clif_displaymessage(sd->fd, output);
ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
}
}
}
- for( i = 0; i < MAX_INVENTORY; i++) {
+ if( battle_config.item_check&4 ) { // Check for invalid(ated) items in storage.
+ for( i = 0; i < MAX_STORAGE; i++ ) {
+ id = sd->status.storage.items[i].nameid;
- if( sd->status.inventory[i].nameid == 0 )
- continue;
-
- if( !sd->status.inventory[i].equip )
- continue;
-
- if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) ) {
- pc_unequipitem(sd, i, 2);
- calc_flag = 1;
- continue;
+ if( id && !itemdb_available(id) ) {
+ sprintf(output, msg_txt(sd, 697), id); // Item %d has been removed from your storage.
+ clif_displaymessage(sd->fd, output);
+ ShowWarning("Removed invalid/disabled item id %d from storage (amount=%d, char_id=%d).\n", id, sd->status.storage.items[i].amount, sd->status.char_id);
+ storage_delitem(sd, i, sd->status.storage.items[i].amount);
+ }
}
-
}
- if( calc_flag && sd->state.active ) {
- pc_checkallowskill(sd);
- status_calc_pc(sd,0);
- }
-
return 0;
}
Index: src/map/pc.h
===================================================================
--- src/map/pc.h (revision 17307)
+++ src/map/pc.h (working copy)
@@ -178,7 +178,7 @@
unsigned int no_castcancel : 1;
unsigned int no_castcancel2 : 1;
unsigned int no_sizefix : 1;
- unsigned int no_gemstone : 1;
+ unsigned int no_gemstone : 2; // 1: Mistress Card effect, 2: VIP effect
unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG]
unsigned int perfect_hiding : 1; // [Valaris]
unsigned int no_knockback : 1;
@@ -669,6 +669,8 @@
)
#define pcdb_checkid(class_) pcdb_checkid_sub((unsigned int)class_)
+#define pc_get_vip(sd) ( pc_get_group_id(sd) == Inter_Config.vip_sys.group ? 1 : 0 )
+
// clientside display macros (values to the left/right of the "+")
#ifdef RENEWAL
#define pc_leftside_atk(sd) ((sd)->battle_status.batk)
@@ -812,6 +814,7 @@
int pc_equipitem(struct map_session_data*,int,int);
int pc_unequipitem(struct map_session_data*,int,int);
int pc_checkitem(struct map_session_data*);
+int pc_check_available_item(struct map_session_data *sd);
int pc_useitem(struct map_session_data*,int);
int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id);
Index: src/map/mob.c
===================================================================
--- src/map/mob.c (revision 17307)
+++ src/map/mob.c (working copy)
@@ -12,6 +12,7 @@
#include "../common/strlib.h"
#include "../common/utils.h"
#include "../common/socket.h"
+#include "../common/conf.h" //Inter_config
#include "map.h"
#include "path.h"
@@ -2243,6 +2244,10 @@
zeny*=rnd()%250;
}
+ // Increase EXP rate for VIP.
+ if( Inter_Config.vip_sys.exp_increase && ( sd && pc_get_vip(sd) ) )
+ bonus += Inter_Config.vip_sys.exp_increase;
+
if (map[m].flag.nobaseexp || !md->db->base_exp)
base_exp = 0;
else
@@ -2371,6 +2376,11 @@
drop_rate = 1;
}
#endif
+
+ // Increase item drop rate for VIP.
+ if( Inter_Config.vip_sys.drop_increase && ( sd && pc_get_vip(sd) ) )
+ drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*Inter_Config.vip_sys.drop_increase/10000.),0,9000)); // now rig the drop rate to never be over 90% unless it is originally >90%.
+
// attempt to drop the item
if (rnd() % 10000 >= drop_rate)
continue;
Index: src/map/clif.c
===================================================================
--- src/map/clif.c (revision 17307)
+++ src/map/clif.c (working copy)
@@ -2418,6 +2418,7 @@
void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length)
{
+ static const int client_buf = 0x5000;
struct item_data *id;
int i,n,ne;
unsigned char *buf;
@@ -2469,27 +2470,33 @@
n++;
}
}
- if( n )
+ for (i = 0; i < n;)
{
+ int nn = n - i < (client_buf - 4)/s ? n - i : (client_buf - 4)/s;
+ unsigned char *p = buf + i*s;
+ i += nn;
#if PACKETVER < 5
- WBUFW(buf,0)=0xa5;
+ WBUFW(p,0)=0xa5;
#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1f0;
+ WBUFW(p,0)=0x1f0;
#else
- WBUFW(buf,0)=0x2ea;
+ WBUFW(p,0)=0x2ea;
#endif
- WBUFW(buf,2)=4+n*s;
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ WBUFW(p,2)=4+nn*s;
+ clif_send(p, WBUFW(p,2), &sd->bl, SELF);
}
- if( ne )
+ for (i = 0; i < ne;)
{
+ int nn = ne - i < (client_buf - 4)/cmd ? ne - i : (client_buf - 4)/cmd;
+ unsigned char *p = bufe + i*cmd;
+ i += nn;
#if PACKETVER < 20071002
- WBUFW(bufe,0)=0xa6;
+ WBUFW(p,0)=0xa6;
#else
- WBUFW(bufe,0)=0x2d1;
+ WBUFW(p,0)=0x2d1;
#endif
- WBUFW(bufe,2)=4+ne*cmd;
- clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+ WBUFW(p,2)=4+nn*cmd;
+ clif_send(p, WBUFW(p,2), &sd->bl, SELF);
}
if( buf ) aFree(buf);
@@ -14112,7 +14119,7 @@
return;
}
- if( (item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
+ if( (item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && itemdb_available(sd->status.inventory[idx].nameid) && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
{ // Consumable or pets are not allowed
clif_Auction_setitem(sd->fd, idx, true);
return;
Index: src/map/itemdb.c
===================================================================
--- src/map/itemdb.c (revision 17307)
+++ src/map/itemdb.c (working copy)
@@ -1422,6 +1422,7 @@
for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) {
memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays
pc_setinventorydata(sd);
+ pc_check_available_item(sd); // Check for invalid(ated) items in inventory/cart/storage.
/* clear combo bonuses */
if( sd->combos.count ) {
aFree(sd->combos.bonus);
Index: src/map/mail.c
===================================================================
--- src/map/mail.c (revision 17307)
+++ src/map/mail.c (working copy)
@@ -78,7 +78,7 @@
return 1;
if( amount < 0 || amount > sd->status.inventory[idx].amount )
return 1;
- if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time ||
+ if( !pc_can_give_items(sd) || !itemdb_available(sd->status.inventory[idx].nameid) || sd->status.inventory[idx].expire_time ||
!itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)) )
return 1;
Index: src/map/battle.c
===================================================================
--- src/map/battle.c (revision 17307)
+++ src/map/battle.c (working copy)
@@ -5668,7 +5668,7 @@
{ "max_heal_lv", &battle_config.max_heal_lv, 11, 1, INT_MAX, },
{ "max_heal", &battle_config.max_heal, 9999, 0, INT_MAX, },
{ "combo_delay_rate", &battle_config.combo_delay_rate, 100, 0, INT_MAX, },
- { "item_check", &battle_config.item_check, 0, 0, 1, },
+ { "item_check", &battle_config.item_check, 0, 0, 7, },
{ "item_use_interval", &battle_config.item_use_interval, 100, 0, INT_MAX, },
{ "cashfood_use_interval", &battle_config.cashfood_use_interval, 60000, 0, INT_MAX, },
{ "wedding_modifydisplay", &battle_config.wedding_modifydisplay, 0, 0, 1, },
Index: src/char/char.c
===================================================================
--- src/char/char.c (revision 17307)
+++ src/char/char.c (working copy)
@@ -108,7 +108,7 @@
#define TRIM_CHARS "\255\xA0\032\t\x0A\x0D " //The following characters are trimmed regardless because they cause confusion and problems on the servers. [Skotlex]
char char_name_letters[1024] = ""; // list of letters/symbols allowed (or not) in a character name. by [Yor]
-int char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
+int char_per_account = 0; //Maximum chars per account [Sirius]
int char_del_level = 0; //From which level u can delete character [Lupus]
int char_del_delay = 86400;
@@ -1563,12 +1563,10 @@
// check the number of already existing chars in this account
- if( char_per_account != 0 ) {
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
- Sql_ShowDebug(sql_handle);
- if( Sql_NumRows(sql_handle) >= char_per_account )
- return -2; // character account limit exceeded
- }
+ if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
+ Sql_ShowDebug(sql_handle);
+ if( Sql_NumRows(sql_handle) >= char_per_account )
+ return -2; // character account limit exceeded
// check char slot
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' LIMIT 1", char_db, sd->account_id, slot) )
@@ -2243,7 +2241,7 @@
ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.h! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots);
sd->char_slots = MAX_CHARS;/* cap to maximum */
} else if ( !sd->char_slots )/* no value aka 0 in sql */
- sd->char_slots = MAX_CHARS;/* cap to maximum */
+ sd->char_slots = char_per_account;/* cap to config */
safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
sd->pincode_change = (time_t)RFIFOL(fd,68);
@@ -5053,9 +5051,8 @@
safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
} else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
char_per_account = atoi(w2);
- if( char_per_account == 0 || char_per_account > MAX_CHARS ) {
- if( char_per_account > MAX_CHARS )
- ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
+ if(char_per_account <= 0 || char_per_account > MAX_CHARS) {
+ ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
char_per_account = MAX_CHARS;
}
} else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
Index: src/common/core.c
===================================================================
--- src/common/core.c (revision 17307)
+++ src/common/core.c (working copy)
@@ -5,6 +5,7 @@
#include "showmsg.h"
#include "malloc.h"
#include "core.h"
+#include "conf.h"
#ifndef MINICORE
#include "db.h"
#include "socket.h"
@@ -355,5 +356,7 @@
malloc_final();
+ inter_conf_read();
+
return 0;
}
Index: src/common/mmo.h
===================================================================
--- src/common/mmo.h (revision 17307)
+++ src/common/mmo.h (working copy)
@@ -72,7 +72,7 @@
#define MAX_MAP_PER_SERVER 1500 // Increased to allow creation of Instance Maps
#define MAX_INVENTORY 100
//Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
-#define MAX_CHARS 9
+#define MAX_CHARS 15
//Number of slots carded equipment can have. Never set to less than 4 as they are also used to keep the data of forged items/equipment. [Skotlex]
//Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size.
#define MAX_SLOTS 4
Index: src/common/conf.c
===================================================================
--- src/common/conf.c (revision 17307)
+++ src/common/conf.c (working copy)
@@ -3,6 +3,8 @@
#include "conf.h"
#include "libconfig.h"
+#include "utils.h"
+#include "mmo.h"
#include "../common/showmsg.h" // ShowError
@@ -64,7 +66,7 @@
config_setting_set_format(set, src->format);
} else if (CONFIG_TYPE_INT64 == config_setting_type(src)) {
set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src));
- config_setting_set_format(set, src->format);
+ config_setting_set_format(set, src->format);
} else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) {
config_setting_set_float_elem(parent, -1, config_setting_get_float(src));
} else if (CONFIG_TYPE_STRING == config_setting_type(src)) {
@@ -85,10 +87,10 @@
return;
n = config_setting_length(src);
-
+
for (i = 0; i < n; i++) {
if (config_setting_is_group(src)) {
- config_setting_copy_simple(newAgg, config_setting_get_elem(src, i));
+ config_setting_copy_simple(newAgg, config_setting_get_elem(src, i));
} else {
config_setting_copy_elem(newAgg, config_setting_get_elem(src, i));
}
@@ -107,3 +109,54 @@
}
return CONFIG_TRUE;
}
+
+//
+// Global configuration settings.
+//
+void inter_conf_read(void);
+
+void inter_conf_read(void){
+ config_t inter_conf;
+ config_setting_t *sys = NULL;
+ const char *config_filename = "conf/inter_battle.conf";
+
+ if (conf_read_file(&inter_conf, config_filename))
+ return;
+
+ sys = config_lookup(&inter_conf, "vip_sys");
+ if (sys != NULL) { //reading vip_sys part
+ config_setting_t *settings = config_setting_get_elem(sys, 0);
+ unsigned int enable; //:1
+ unsigned int group;
+ unsigned int magic_stone; //:1
+ unsigned int storage_increase;
+ unsigned int char_increase;
+ unsigned int exp_increase;
+ unsigned int exp_penalty;
+ unsigned int bm_increase;
+ unsigned int drop_increase;
+
+ config_setting_lookup_bool(settings, "enable", &enable);
+ Inter_Config.vip_sys.enable = enable;
+
+ if (enable) {
+ config_setting_lookup_int(settings, "group", &group);
+ config_setting_lookup_int(settings, "storage_increase", &storage_increase);
+ config_setting_lookup_int(settings, "char_increase", &char_increase);
+ config_setting_lookup_int(settings, "exp_increase", &exp_increase);
+ config_setting_lookup_int(settings, "exp_penalty", &exp_penalty);
+ config_setting_lookup_int(settings, "bm_increase", &bm_increase);
+ config_setting_lookup_int(settings, "drop_increase", &drop_increase);
+ config_setting_lookup_bool(settings, "magic_stone", &magic_stone);
+ }
+
+ Inter_Config.vip_sys.group = cap_value(storage_increase,0,99);
+ Inter_Config.vip_sys.storage_increase = cap_value(storage_increase,0,1000);
+ Inter_Config.vip_sys.char_increase = cap_value(char_increase,0,MAX_CHARS);
+ Inter_Config.vip_sys.exp_increase = cap_value(exp_increase,0,INT_MAX);
+ Inter_Config.vip_sys.exp_penalty = cap_value(exp_penalty,0,INT_MAX);
+ Inter_Config.vip_sys.bm_increase = cap_value(bm_increase,0,INT_MAX);
+ Inter_Config.vip_sys.drop_increase = cap_value(drop_increase,0,INT_MAX);
+ Inter_Config.vip_sys.magic_stone = magic_stone;
+ }
+}
Index: src/common/conf.h
===================================================================
--- src/common/conf.h (revision 17307)
+++ src/common/conf.h (working copy)
@@ -7,6 +7,22 @@
#include "../common/cbasetypes.h"
#include "libconfig.h"
+struct {
+ struct {
+ unsigned int enable : 1;
+ unsigned int group;
+ unsigned int storage_increase;
+ unsigned int char_increase;
+ unsigned int exp_increase;
+ unsigned int exp_penalty;
+ unsigned int bm_increase;
+ unsigned int drop_increase;
+ unsigned int magic_stone : 1;
+ } vip_sys;
+} Inter_Config;
+
+void inter_conf_read(void);
+
int conf_read_file(config_t *config, const char *config_filename);
int config_setting_copy(config_setting_t *parent, const config_setting_t *src);